#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 | chan_iax2_pvt::signaling_queue |
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_entry |
struct | tpeers |
Defines | |
#define | ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
#define | ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
#define | CALLTOKEN_IE_FORMAT "%u?%s" |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CALLENCRYPTED(pvt) (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_DEBUGDIGEST(msg, key) |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 563 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START 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_SHRINKCALLERID = (1 << 27) } |
enum | iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY } |
enum | iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static void | __reg_module (void) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static void | __unreg_module (void) |
static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
static int | acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
static int | add_calltoken_ignore (const char *addr) |
static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied) |
static int | addr_range_cmp_cb (void *obj, void *arg, int flags) |
static int | addr_range_delme_cb (void *obj, void *arg, int flags) |
static int | addr_range_hash_cb (const void *obj, const int flags) |
static int | addr_range_match_address_cb (void *obj, void *arg, int flags) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
Create new call, interface with the PBX core. | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static void | build_callno_limits (struct ast_variable *v) |
static struct iax2_context * | build_context (const char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static void | build_rand_pad (unsigned char *buf, ssize_t len) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
static int | callno_hash (const void *obj, const int flags) |
static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state) |
static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | create_callno_pools (void) |
static int | decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static struct iax2_user * | find_user (const char *name) |
static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (const char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static struct callno_entry * | get_unused_callno (int trunk, int validated) |
static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Set trunk MTU from CLI. | |
static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one peer in detail. | |
static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
static int | iax2_answer (struct ast_channel *c) |
static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static void * | iax2_dup_variable_datastore (void *) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static void | iax2_free_variable_datastore (void *) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_key_rotate (const void *vpvt) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (const char *value, int lineno) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_sched_replace (int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static int | load_objects (void) |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static void | log_jitterstats (unsigned short callno) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
callback to display iax peers in manager format | |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
callback to display iax peers in manager | |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static int | peercnt_add (struct sockaddr_in *sin) |
static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
static int | peercnt_hash_cb (const void *obj, const int flags) |
static void | peercnt_modify (unsigned char reg, uint16_t limit, struct sockaddr_in *sin) |
static void | peercnt_remove (struct peercnt *peercnt) |
static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
static int | peercnt_remove_cb (const void *obj) |
static void | poke_all_peers (void) |
static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | replace_callno (const void *obj) |
static void | requirecalltoken_mark_auto (const char *name, int subclass) |
static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static void | send_signaling (struct chan_iax2_pvt *pvt) |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (const char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_peercnt_limit (struct peercnt *peercnt) |
static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ao2_container * | callno_limits |
static struct ao2_container * | callno_pool |
static const unsigned int | CALLNO_POOL_BUCKETS = 2699 |
static struct ao2_container * | callno_pool_trunk |
static struct ao2_container * | calltoken_ignores |
static struct ast_cli_entry | cli_iax2 [] |
static struct sockaddr_in | debugaddr |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT = 2048 |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 |
static char | default_parkinglot [AST_MAX_CONTEXT] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static int | global_max_trunk_mtu |
static uint16_t | global_maxcallno |
static uint16_t | global_maxcallno_nonval |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static struct ast_datastore_info | iax2_variable_datastore_info |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static struct ao2_container * | iax_transfercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxdynamicthreadnum = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
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 char * | pdescrip |
static struct ao2_container * | peercnts |
static struct ao2_container * | peers |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
static char * | psyn = "Provision a calling IAXy with a given template" |
struct { | |
unsigned int cos | |
unsigned int tos | |
} | qos |
static int | randomcalltokendata |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static ast_mutex_t | sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static int | srvlookup = 0 |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static struct ast_timer * | timer |
static uint16_t | total_nonval_callno_used = 0 |
static int | trunk_maxmtu |
static int | trunk_nmaxmtu |
static int | trunk_timed |
static int | trunk_untimed |
static int | trunkfreq = 20 |
static int | trunkmaxsize = MAX_TRUNKDATA |
static struct ao2_container * | users |
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 112 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 104 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 120 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 139 of file chan_iax2.c.
Referenced by check_access(), and handle_cli_iax2_show_users().
#define DEFAULT_DROP 3 |
Definition at line 118 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 208 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 115 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 206 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 114 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 488 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 125 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CALLENCRYPTED | ( | pvt | ) | (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED)) |
Definition at line 211 of file chan_iax2.c.
Referenced by iax2_send(), iax2_start_transfer(), and socket_process().
#define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
Definition at line 188 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 197 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 202 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
#define IAX_DEBUGDIGEST | ( | msg, | |||
key | ) |
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 496 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 485 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 743 of file chan_iax2.c.
Referenced by load_objects().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 490 of file chan_iax2.c.
#define MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
Definition at line 134 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 155 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 117 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 486 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 111 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 100 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1270 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 957 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 493 of file chan_iax2.c.
anonymous enum |
Definition at line 803 of file chan_iax2.c.
00803 { 00804 /*! Extension exists */ 00805 CACHE_FLAG_EXISTS = (1 << 0), 00806 /*! Extension is nonexistent */ 00807 CACHE_FLAG_NONEXISTENT = (1 << 1), 00808 /*! Extension can exist */ 00809 CACHE_FLAG_CANEXIST = (1 << 2), 00810 /*! Waiting to hear back response */ 00811 CACHE_FLAG_PENDING = (1 << 3), 00812 /*! Timed out */ 00813 CACHE_FLAG_TIMEOUT = (1 << 4), 00814 /*! Request transmitted */ 00815 CACHE_FLAG_TRANSMITTED = (1 << 5), 00816 /*! Timeout */ 00817 CACHE_FLAG_UNKNOWN = (1 << 6), 00818 /*! Matchmore */ 00819 CACHE_FLAG_MATCHMORE = (1 << 7), 00820 };
anonymous enum |
Definition at line 1727 of file chan_iax2.c.
01727 { 01728 /* do not allow a new call number, only search ones in use for match */ 01729 NEW_PREVENT = 0, 01730 /* search for match first, then allow a new one to be allocated */ 01731 NEW_ALLOW = 1, 01732 /* do not search for match, force a new call number */ 01733 NEW_FORCE = 2, 01734 /* do not search for match, force a new call number. Signifies call number 01735 * has been calltoken validated */ 01736 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01737 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 310 of file chan_iax2.c.
00310 { 00311 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00312 CALLTOKEN_DEFAULT = 0, 00313 /*! \brief Require call token validation. */ 00314 CALLTOKEN_YES = 1, 00315 /*! \brief Require call token validation after a successful registration 00316 * using call token validation occurs. */ 00317 CALLTOKEN_AUTO = 2, 00318 /*! \brief Do not require call token validation. */ 00319 CALLTOKEN_NO = 3, 00320 };
enum iax2_flags |
Definition at line 270 of file chan_iax2.c.
00270 { 00271 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00272 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00273 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00274 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00275 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00276 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00277 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00278 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00279 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00280 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00281 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00282 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00283 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00284 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00285 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00286 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00287 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00288 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00289 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00290 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00291 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00292 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00293 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00294 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00295 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00296 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00297 response, so that we've achieved a three-way handshake with 00298 them before sending voice or anything else*/ 00299 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00300 IAX_SHRINKCALLERID = (1 << 27), /*!< Turn on and off caller id shrinking */ 00301 };
enum iax2_state |
Definition at line 259 of file chan_iax2.c.
00259 { 00260 IAX_STATE_STARTED = (1 << 0), 00261 IAX_STATE_AUTHENTICATED = (1 << 1), 00262 IAX_STATE_TBD = (1 << 2), 00263 };
enum iax2_thread_iostate |
Definition at line 844 of file chan_iax2.c.
00844 { 00845 IAX_IOSTATE_IDLE, 00846 IAX_IOSTATE_READY, 00847 IAX_IOSTATE_PROCESSING, 00848 IAX_IOSTATE_SCHEDREADY, 00849 };
enum iax2_thread_type |
Definition at line 851 of file chan_iax2.c.
00851 { 00852 IAX_THREAD_TYPE_POOL, 00853 IAX_THREAD_TYPE_DYNAMIC, 00854 };
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 441 of file chan_iax2.c.
00441 { 00442 REG_STATE_UNREGISTERED = 0, 00443 REG_STATE_REGSENT, 00444 REG_STATE_AUTHSENT, 00445 REG_STATE_REGISTERED, 00446 REG_STATE_REJECTED, 00447 REG_STATE_TIMEOUT, 00448 REG_STATE_NOAUTH 00449 };
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 451 of file chan_iax2.c.
00451 { 00452 TRANSFER_NONE = 0, 00453 TRANSFER_BEGIN, 00454 TRANSFER_READY, 00455 TRANSFER_RELEASED, 00456 TRANSFER_PASSTHROUGH, 00457 TRANSFER_MBEGIN, 00458 TRANSFER_MREADY, 00459 TRANSFER_MRELEASED, 00460 TRANSFER_MPASSTHROUGH, 00461 TRANSFER_MEDIA, 00462 TRANSFER_MEDIAPASS 00463 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3213 of file chan_iax2.c.
References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_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, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iax2_trunk_peer::list, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03214 { 03215 /* Attempt to transmit the frame to the remote peer... 03216 Called without iaxsl held. */ 03217 struct iax_frame *f = (struct iax_frame *)data; 03218 int freeme = 0; 03219 int callno = f->callno; 03220 /* Make sure this call is still active */ 03221 if (callno) 03222 ast_mutex_lock(&iaxsl[callno]); 03223 if (callno && iaxs[callno]) { 03224 if ((f->retries < 0) /* Already ACK'd */ || 03225 (f->retries >= max_retries) /* Too many attempts */) { 03226 /* Record an error if we've transmitted too many times */ 03227 if (f->retries >= max_retries) { 03228 if (f->transfer) { 03229 /* Transfer timeout */ 03230 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03231 } else if (f->final) { 03232 if (f->final) 03233 iax2_destroy(callno); 03234 } else { 03235 if (iaxs[callno]->owner) 03236 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); 03237 iaxs[callno]->error = ETIMEDOUT; 03238 if (iaxs[callno]->owner) { 03239 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03240 /* Hangup the fd */ 03241 iax2_queue_frame(callno, &fr); /* XXX */ 03242 /* Remember, owner could disappear */ 03243 if (iaxs[callno] && iaxs[callno]->owner) 03244 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03245 } else { 03246 if (iaxs[callno]->reg) { 03247 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03248 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03249 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03250 } 03251 iax2_destroy(callno); 03252 } 03253 } 03254 03255 } 03256 freeme = 1; 03257 } else { 03258 /* Update it if it needs it */ 03259 update_packet(f); 03260 /* Attempt transmission */ 03261 send_packet(f); 03262 f->retries++; 03263 /* Try again later after 10 times as long */ 03264 f->retrytime *= 10; 03265 if (f->retrytime > MAX_RETRY_TIME) 03266 f->retrytime = MAX_RETRY_TIME; 03267 /* Transfer messages max out at one second */ 03268 if (f->transfer && (f->retrytime > 1000)) 03269 f->retrytime = 1000; 03270 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03271 } 03272 } else { 03273 /* Make sure it gets freed */ 03274 f->retries = -1; 03275 freeme = 1; 03276 } 03277 if (callno) 03278 ast_mutex_unlock(&iaxsl[callno]); 03279 /* Do not try again */ 03280 if (freeme) { 03281 /* Don't attempt delivery, just remove it from the queue */ 03282 AST_LIST_LOCK(&frame_queue); 03283 AST_LIST_REMOVE(&frame_queue, f, list); 03284 AST_LIST_UNLOCK(&frame_queue); 03285 f->retrans = -1; /* this is safe because this is the scheduled function */ 03286 /* Free the IAX frame */ 03287 iax2_frame_free(f); 03288 } 03289 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8440 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, and send_command_final().
Referenced by auth_reject().
08441 { 08442 /* Called from IAX thread only, without iaxs lock */ 08443 int callno = (int)(long)(nothing); 08444 struct iax_ie_data ied; 08445 ast_mutex_lock(&iaxsl[callno]); 08446 if (iaxs[callno]) { 08447 memset(&ied, 0, sizeof(ied)); 08448 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08449 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08450 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08451 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08452 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08453 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08454 } 08455 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08456 } 08457 ast_mutex_unlock(&iaxsl[callno]); 08458 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4323 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04324 { 04325 int callno = PTR_TO_CALLNO(nothing); 04326 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04327 ast_mutex_lock(&iaxsl[callno]); 04328 if (iaxs[callno]) { 04329 iaxs[callno]->initid = -1; 04330 iax2_queue_frame(callno, &f); 04331 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04332 } 04333 ast_mutex_unlock(&iaxsl[callno]); 04334 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8489 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, and send_command_final().
Referenced by auto_hangup().
08490 { 08491 /* Called from IAX thread only, without iaxs lock */ 08492 int callno = (int)(long)(nothing); 08493 struct iax_ie_data ied; 08494 ast_mutex_lock(&iaxsl[callno]); 08495 if (iaxs[callno]) { 08496 memset(&ied, 0, sizeof(ied)); 08497 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08498 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 08499 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 08500 } 08501 ast_mutex_unlock(&iaxsl[callno]); 08502 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 3008 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, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03009 { 03010 /* Just deliver the packet by using queueing. This is called by 03011 the IAX thread with the iaxsl lock held. */ 03012 struct iax_frame *fr = data; 03013 fr->retrans = -1; 03014 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03015 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 03016 iax2_queue_frame(fr->callno, &fr->af); 03017 /* Free our iax frame */ 03018 iax2_frame_free(fr); 03019 /* And don't run again */ 03020 return 0; 03021 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8088 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, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, iax2_peer::name, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
08089 { 08090 struct iax2_peer *peer = (struct iax2_peer *) data; 08091 08092 if (!peer) 08093 return; 08094 08095 peer->expire = -1; 08096 08097 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08098 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08099 realtime_update_peer(peer->name, &peer->addr, 0); 08100 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08101 /* modify entry in peercnts table as _not_ registered */ 08102 peercnt_modify(0, 0, &peer->addr); 08103 /* Reset the address */ 08104 memset(&peer->addr, 0, sizeof(peer->addr)); 08105 /* Reset expiry value */ 08106 peer->expiry = min_reg_expire; 08107 if (!ast_test_flag(peer, IAX_TEMPONLY)) 08108 ast_db_del("IAX/Registry", peer->name); 08109 register_peer_exten(peer, 0); 08110 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08111 if (iax2_regfunk) 08112 iax2_regfunk(peer->name, 0); 08113 08114 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 08115 unlink_peer(peer); 08116 08117 peer_unref(peer); 08118 }
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 2485 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, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
02486 { 02487 int res = 0; 02488 int x; 02489 /* this call is calltoken validated as long as it is either NEW_FORCE 02490 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02491 int validated = (new > NEW_ALLOW) ? 1 : 0; 02492 char host[80]; 02493 02494 if (new <= NEW_ALLOW) { 02495 if (callno) { 02496 struct chan_iax2_pvt *pvt; 02497 struct chan_iax2_pvt tmp_pvt = { 02498 .callno = dcallno, 02499 .peercallno = callno, 02500 .transfercallno = callno, 02501 /* hack!! */ 02502 .frames_received = check_dcallno, 02503 }; 02504 02505 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02506 /* this works for finding normal call numbers not involving transfering */ 02507 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02508 if (return_locked) { 02509 ast_mutex_lock(&iaxsl[pvt->callno]); 02510 } 02511 res = pvt->callno; 02512 ao2_ref(pvt, -1); 02513 pvt = NULL; 02514 return res; 02515 } 02516 /* this searches for transfer call numbers that might not get caught otherwise */ 02517 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02518 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02519 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02520 if (return_locked) { 02521 ast_mutex_lock(&iaxsl[pvt->callno]); 02522 } 02523 res = pvt->callno; 02524 ao2_ref(pvt, -1); 02525 pvt = NULL; 02526 return res; 02527 } 02528 } 02529 /* This will occur on the first response to a message that we initiated, 02530 * such as a PING. */ 02531 if (dcallno) { 02532 ast_mutex_lock(&iaxsl[dcallno]); 02533 } 02534 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02535 iaxs[dcallno]->peercallno = callno; 02536 res = dcallno; 02537 store_by_peercallno(iaxs[dcallno]); 02538 if (!res || !return_locked) { 02539 ast_mutex_unlock(&iaxsl[dcallno]); 02540 } 02541 return res; 02542 } 02543 if (dcallno) { 02544 ast_mutex_unlock(&iaxsl[dcallno]); 02545 } 02546 #ifdef IAX_OLD_FIND 02547 /* If we get here, we SHOULD NOT find a call structure for this 02548 callno; if we do, it means that there is a call structure that 02549 has a peer callno but did NOT get entered into the hash table, 02550 which is bad. 02551 02552 If we find a call structure using this old, slow method, output a log 02553 message so we'll know about it. After a few months of leaving this in 02554 place, if we don't hear about people seeing these messages, we can 02555 remove this code for good. 02556 */ 02557 02558 for (x = 1; !res && x < maxnontrunkcall; x++) { 02559 ast_mutex_lock(&iaxsl[x]); 02560 if (iaxs[x]) { 02561 /* Look for an exact match */ 02562 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02563 res = x; 02564 } 02565 } 02566 if (!res || !return_locked) 02567 ast_mutex_unlock(&iaxsl[x]); 02568 } 02569 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02570 ast_mutex_lock(&iaxsl[x]); 02571 if (iaxs[x]) { 02572 /* Look for an exact match */ 02573 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02574 res = x; 02575 } 02576 } 02577 if (!res || !return_locked) 02578 ast_mutex_unlock(&iaxsl[x]); 02579 } 02580 #endif 02581 } 02582 if (!res && (new >= NEW_ALLOW)) { 02583 struct callno_entry *callno_entry; 02584 /* It may seem odd that we look through the peer list for a name for 02585 * this *incoming* call. Well, it is weird. However, users don't 02586 * have an IP address/port number that we can match against. So, 02587 * this is just checking for a peer that has that IP/port and 02588 * assuming that we have a user of the same name. This isn't always 02589 * correct, but it will be changed if needed after authentication. */ 02590 if (!iax2_getpeername(*sin, host, sizeof(host))) 02591 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02592 02593 if (peercnt_add(sin)) { 02594 /* This address has hit its callnumber limit. When the limit 02595 * is reached, the connection is not added to the peercnts table.*/ 02596 return 0; 02597 } 02598 02599 if (!(callno_entry = get_unused_callno(0, validated))) { 02600 /* since we ran out of space, remove the peercnt 02601 * entry we added earlier */ 02602 peercnt_remove_by_addr(sin); 02603 ast_log(LOG_WARNING, "No more space\n"); 02604 return 0; 02605 } 02606 x = callno_entry->callno; 02607 ast_mutex_lock(&iaxsl[x]); 02608 02609 iaxs[x] = new_iax(sin, host); 02610 update_max_nontrunk(); 02611 if (iaxs[x]) { 02612 if (iaxdebug) 02613 ast_debug(1, "Creating new call structure %d\n", x); 02614 iaxs[x]->callno_entry = callno_entry; 02615 iaxs[x]->sockfd = sockfd; 02616 iaxs[x]->addr.sin_port = sin->sin_port; 02617 iaxs[x]->addr.sin_family = sin->sin_family; 02618 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02619 iaxs[x]->peercallno = callno; 02620 iaxs[x]->callno = x; 02621 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02622 iaxs[x]->expiry = min_reg_expire; 02623 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02624 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02625 iaxs[x]->amaflags = amaflags; 02626 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02627 02628 ast_string_field_set(iaxs[x], accountcode, accountcode); 02629 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02630 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02631 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02632 02633 if (iaxs[x]->peercallno) { 02634 store_by_peercallno(iaxs[x]); 02635 } 02636 } else { 02637 ast_log(LOG_WARNING, "Out of resources\n"); 02638 ast_mutex_unlock(&iaxsl[x]); 02639 replace_callno(callno_entry); 02640 return 0; 02641 } 02642 if (!return_locked) 02643 ast_mutex_unlock(&iaxsl[x]); 02644 res = x; 02645 } 02646 return res; 02647 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3776 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, iaxs, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, iax2_trunk_peer::next, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
03777 { 03778 int callno = PTR_TO_CALLNO(p); 03779 struct chan_iax2_pvt *pvt = NULL; 03780 struct iax_frame *fr; 03781 jb_frame frame; 03782 int ret; 03783 long ms; 03784 long next; 03785 struct timeval now = ast_tvnow(); 03786 03787 /* Make sure we have a valid private structure before going on */ 03788 ast_mutex_lock(&iaxsl[callno]); 03789 pvt = iaxs[callno]; 03790 if (!pvt) { 03791 /* No go! */ 03792 ast_mutex_unlock(&iaxsl[callno]); 03793 return; 03794 } 03795 03796 pvt->jbid = -1; 03797 03798 /* round up a millisecond since ast_sched_runq does; */ 03799 /* prevents us from spinning while waiting for our now */ 03800 /* to catch up with runq's now */ 03801 now.tv_usec += 1000; 03802 03803 ms = ast_tvdiff_ms(now, pvt->rxcore); 03804 03805 if(ms >= (next = jb_next(pvt->jb))) { 03806 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 03807 switch(ret) { 03808 case JB_OK: 03809 fr = frame.data; 03810 __do_deliver(fr); 03811 /* __do_deliver() can cause the call to disappear */ 03812 pvt = iaxs[callno]; 03813 break; 03814 case JB_INTERP: 03815 { 03816 struct ast_frame af = { 0, }; 03817 03818 /* create an interpolation frame */ 03819 af.frametype = AST_FRAME_VOICE; 03820 af.subclass = pvt->voiceformat; 03821 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03822 af.src = "IAX2 JB interpolation"; 03823 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03824 af.offset = AST_FRIENDLY_OFFSET; 03825 03826 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03827 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03828 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03829 iax2_queue_frame(callno, &af); 03830 /* iax2_queue_frame() could cause the call to disappear */ 03831 pvt = iaxs[callno]; 03832 } 03833 } 03834 break; 03835 case JB_DROP: 03836 iax2_frame_free(frame.data); 03837 break; 03838 case JB_NOFRAME: 03839 case JB_EMPTY: 03840 /* do nothing */ 03841 break; 03842 default: 03843 /* shouldn't happen */ 03844 break; 03845 } 03846 } 03847 if (pvt) 03848 update_jbsched(pvt); 03849 ast_mutex_unlock(&iaxsl[callno]); 03850 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7762 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
07763 { 07764 struct iax2_registry *reg = (struct iax2_registry *)data; 07765 reg->expire = -1; 07766 iax2_do_register(reg); 07767 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11273 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, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
11274 { 11275 struct iax2_peer *peer = (struct iax2_peer *)data; 11276 int callno; 11277 11278 if (peer->lastms > -1) { 11279 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11280 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11281 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11282 } 11283 if ((callno = peer->callno) > 0) { 11284 ast_mutex_lock(&iaxsl[callno]); 11285 iax2_destroy(callno); 11286 ast_mutex_unlock(&iaxsl[callno]); 11287 } 11288 peer->callno = 0; 11289 peer->lastms = -1; 11290 /* Try again quickly */ 11291 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11292 if (peer->pokeexpire == -1) 11293 peer_unref(peer); 11294 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8552 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
08553 { 08554 struct iax2_peer *peer = (struct iax2_peer *)data; 08555 iax2_poke_peer(peer, 0); 08556 peer_unref(peer); 08557 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6217 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06218 { 06219 regex_t regexbuf; 06220 int havepattern = 0; 06221 int total_peers = 0; 06222 int online_peers = 0; 06223 int offline_peers = 0; 06224 int unmonitored_peers = 0; 06225 struct ao2_iterator i; 06226 06227 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 06228 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 06229 06230 struct iax2_peer *peer = NULL; 06231 char name[256]; 06232 int registeredonly=0; 06233 char *term = manager ? "\r\n" : "\n"; 06234 char idtext[256] = ""; 06235 switch (argc) { 06236 case 6: 06237 if (!strcasecmp(argv[3], "registered")) 06238 registeredonly = 1; 06239 else 06240 return RESULT_SHOWUSAGE; 06241 if (!strcasecmp(argv[4], "like")) { 06242 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06243 return RESULT_SHOWUSAGE; 06244 havepattern = 1; 06245 } else 06246 return RESULT_SHOWUSAGE; 06247 break; 06248 case 5: 06249 if (!strcasecmp(argv[3], "like")) { 06250 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06251 return RESULT_SHOWUSAGE; 06252 havepattern = 1; 06253 } else 06254 return RESULT_SHOWUSAGE; 06255 break; 06256 case 4: 06257 if (!strcasecmp(argv[3], "registered")) 06258 registeredonly = 1; 06259 else 06260 return RESULT_SHOWUSAGE; 06261 break; 06262 case 3: 06263 break; 06264 default: 06265 return RESULT_SHOWUSAGE; 06266 } 06267 06268 06269 if (!s) 06270 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 06271 06272 i = ao2_iterator_init(peers, 0); 06273 for (peer = ao2_iterator_next(&i); peer; 06274 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06275 char nm[20]; 06276 char status[20]; 06277 char srch[2000]; 06278 int retstatus; 06279 06280 if (registeredonly && !peer->addr.sin_addr.s_addr) 06281 continue; 06282 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 06283 continue; 06284 06285 if (!ast_strlen_zero(peer->username)) 06286 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06287 else 06288 ast_copy_string(name, peer->name, sizeof(name)); 06289 06290 retstatus = peer_status(peer, status, sizeof(status)); 06291 if (retstatus > 0) 06292 online_peers++; 06293 else if (!retstatus) 06294 offline_peers++; 06295 else 06296 unmonitored_peers++; 06297 06298 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06299 06300 snprintf(srch, sizeof(srch), FORMAT, name, 06301 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06302 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06303 nm, 06304 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 06305 peer->encmethods ? "(E)" : " ", status, term); 06306 06307 if (s) 06308 astman_append(s, 06309 "Event: PeerEntry\r\n%s" 06310 "Channeltype: IAX2\r\n" 06311 "ChanObjectType: peer\r\n" 06312 "ObjectName: %s\r\n" 06313 "IPaddress: %s\r\n" 06314 "IPport: %d\r\n" 06315 "Dynamic: %s\r\n" 06316 "Status: %s\r\n\r\n", 06317 idtext, 06318 name, 06319 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-", 06320 ntohs(peer->addr.sin_port), 06321 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no", 06322 status); 06323 06324 else 06325 ast_cli(fd, FORMAT, name, 06326 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06327 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06328 nm, 06329 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 06330 peer->encmethods ? "(E)" : " ", status, term); 06331 total_peers++; 06332 } 06333 ao2_iterator_destroy(&i); 06334 06335 if (!s) 06336 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 06337 06338 if (havepattern) 06339 regfree(®exbuf); 06340 06341 return RESULT_SUCCESS; 06342 #undef FORMAT 06343 #undef FORMAT2 06344 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13752 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1245 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01246 { 01247 struct iax2_thread *thread = NULL; 01248 static time_t lasterror; 01249 static time_t t; 01250 01251 thread = find_idle_thread(); 01252 01253 if (thread != NULL) { 01254 thread->schedfunc = func; 01255 thread->scheddata = data; 01256 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01257 #ifdef DEBUG_SCHED_MULTITHREAD 01258 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01259 #endif 01260 signal_condition(&thread->lock, &thread->cond); 01261 return 0; 01262 } 01263 time(&t); 01264 if (t != lasterror) 01265 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01266 lasterror = t; 01267 01268 return -1; 01269 }
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 6968 of file chan_iax2.c.
References f, iax2_send(), and queue_signalling().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
06970 { 06971 struct ast_frame f = { 0, }; 06972 int res = 0; 06973 06974 f.frametype = type; 06975 f.subclass = command; 06976 f.datalen = datalen; 06977 f.src = __FUNCTION__; 06978 f.data.ptr = (void *) data; 06979 06980 if ((res = queue_signalling(i, &f)) <= 0) { 06981 return res; 06982 } 06983 06984 return iax2_send(i, &f, ts, seqno, now, transfer, final); 06985 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1338 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, iaxs, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01339 { 01340 int callno = (long) data; 01341 01342 ast_mutex_lock(&iaxsl[callno]); 01343 01344 if (iaxs[callno]) { 01345 if (iaxs[callno]->peercallno) { 01346 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01347 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01348 } else { 01349 /* I am the schedule, so I'm allowed to do this */ 01350 iaxs[callno]->lagid = -1; 01351 } 01352 } else { 01353 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01354 } 01355 01356 ast_mutex_unlock(&iaxsl[callno]); 01357 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1293 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, iaxs, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
01294 { 01295 int callno = (long) data; 01296 01297 ast_mutex_lock(&iaxsl[callno]); 01298 01299 if (iaxs[callno]) { 01300 if (iaxs[callno]->peercallno) { 01301 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01302 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01303 } else { 01304 /* I am the schedule, so I'm allowed to do this */ 01305 iaxs[callno]->pingid = -1; 01306 } 01307 } else { 01308 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01309 } 01310 01311 ast_mutex_unlock(&iaxsl[callno]); 01312 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 13439 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), callno_limits, calltoken_ignores, cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxactivethreadcount, iaxs, netsock, outsock, papp, peercnts, peers, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, timer, and users.
13440 { 13441 struct iax2_thread *thread = NULL; 13442 struct ast_context *con; 13443 int x; 13444 13445 /* Make sure threads do not hold shared resources when they are canceled */ 13446 13447 /* Grab the sched lock resource to keep it away from threads about to die */ 13448 /* Cancel the network thread, close the net socket */ 13449 if (netthreadid != AST_PTHREADT_NULL) { 13450 AST_LIST_LOCK(&frame_queue); 13451 ast_mutex_lock(&sched_lock); 13452 pthread_cancel(netthreadid); 13453 ast_cond_signal(&sched_cond); 13454 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 13455 AST_LIST_UNLOCK(&frame_queue); 13456 pthread_join(netthreadid, NULL); 13457 } 13458 if (schedthreadid != AST_PTHREADT_NULL) { 13459 ast_mutex_lock(&sched_lock); 13460 pthread_cancel(schedthreadid); 13461 ast_cond_signal(&sched_cond); 13462 ast_mutex_unlock(&sched_lock); 13463 pthread_join(schedthreadid, NULL); 13464 } 13465 13466 /* Call for all threads to halt */ 13467 AST_LIST_LOCK(&idle_list); 13468 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) 13469 pthread_cancel(thread->threadid); 13470 AST_LIST_UNLOCK(&idle_list); 13471 13472 AST_LIST_LOCK(&active_list); 13473 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list))) 13474 pthread_cancel(thread->threadid); 13475 AST_LIST_UNLOCK(&active_list); 13476 13477 AST_LIST_LOCK(&dynamic_list); 13478 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list))) 13479 pthread_cancel(thread->threadid); 13480 AST_LIST_UNLOCK(&dynamic_list); 13481 13482 /* Wait for threads to exit */ 13483 while(0 < iaxactivethreadcount) 13484 usleep(10000); 13485 13486 ast_netsock_release(netsock); 13487 ast_netsock_release(outsock); 13488 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13489 if (iaxs[x]) { 13490 iax2_destroy(x); 13491 } 13492 } 13493 ast_manager_unregister( "IAXpeers" ); 13494 ast_manager_unregister( "IAXpeerlist" ); 13495 ast_manager_unregister( "IAXnetstats" ); 13496 ast_unregister_application(papp); 13497 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 13498 ast_unregister_switch(&iax2_switch); 13499 ast_channel_unregister(&iax2_tech); 13500 delete_users(); 13501 iax_provision_unload(); 13502 sched_context_destroy(sched); 13503 reload_firmware(1); 13504 13505 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13506 ast_mutex_destroy(&iaxsl[x]); 13507 } 13508 13509 ao2_ref(peers, -1); 13510 ao2_ref(users, -1); 13511 ao2_ref(iax_peercallno_pvts, -1); 13512 ao2_ref(iax_transfercallno_pvts, -1); 13513 ao2_ref(peercnts, -1); 13514 ao2_ref(callno_limits, -1); 13515 ao2_ref(calltoken_ignores, -1); 13516 ao2_ref(callno_pool, -1); 13517 ao2_ref(callno_pool_trunk, -1); 13518 if (timer) { 13519 ast_timer_close(timer); 13520 } 13521 13522 con = ast_context_find(regcontext); 13523 if (con) 13524 ast_context_destroy(con, "IAX2"); 13525 ast_unload_realtime("iaxpeers"); 13526 return 0; 13527 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13752 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 13224 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_tech, iaxs, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
13225 { 13226 struct chan_iax2_pvt *pvt; 13227 unsigned int callno; 13228 int res = 0; 13229 13230 if (!chan || chan->tech != &iax2_tech) { 13231 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13232 return -1; 13233 } 13234 13235 callno = PTR_TO_CALLNO(chan->tech_pvt); 13236 ast_mutex_lock(&iaxsl[callno]); 13237 if (!(pvt = iaxs[callno])) { 13238 ast_mutex_unlock(&iaxsl[callno]); 13239 return -1; 13240 } 13241 13242 if (!strcasecmp(args, "osptoken")) { 13243 ast_copy_string(buf, pvt->osptoken, buflen); 13244 } else if (!strcasecmp(args, "peerip")) { 13245 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13246 } else if (!strcasecmp(args, "peername")) { 13247 ast_copy_string(buf, pvt->username, buflen); 13248 } else { 13249 res = -1; 13250 } 13251 13252 ast_mutex_unlock(&iaxsl[callno]); 13253 13254 return res; 13255 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9220 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, chan, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, and var.
09221 { 09222 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09223 AST_LIST_HEAD(, ast_var_t) *varlist; 09224 struct ast_var_t *var; 09225 09226 if (!variablestore) { 09227 *buf = '\0'; 09228 return 0; 09229 } 09230 varlist = variablestore->data; 09231 09232 AST_LIST_LOCK(varlist); 09233 AST_LIST_TRAVERSE(varlist, var, entries) { 09234 if (strcmp(var->name, data) == 0) { 09235 ast_copy_string(buf, var->value, len); 09236 break; 09237 } 09238 } 09239 AST_LIST_UNLOCK(varlist); 09240 return 0; 09241 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9243 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(), chan, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_var_t::entries, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, and var.
09244 { 09245 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09246 AST_LIST_HEAD(, ast_var_t) *varlist; 09247 struct ast_var_t *var; 09248 09249 if (!variablestore) { 09250 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09251 if (!variablestore) { 09252 ast_log(LOG_ERROR, "Memory allocation error\n"); 09253 return -1; 09254 } 09255 varlist = ast_calloc(1, sizeof(*varlist)); 09256 if (!varlist) { 09257 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09258 return -1; 09259 } 09260 09261 AST_LIST_HEAD_INIT(varlist); 09262 variablestore->data = varlist; 09263 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09264 ast_channel_datastore_add(chan, variablestore); 09265 } else 09266 varlist = variablestore->data; 09267 09268 AST_LIST_LOCK(varlist); 09269 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09270 if (strcmp(var->name, data) == 0) { 09271 AST_LIST_REMOVE_CURRENT(entries); 09272 ast_var_delete(var); 09273 break; 09274 } 09275 } 09276 AST_LIST_TRAVERSE_SAFE_END; 09277 var = ast_var_assign(data, value); 09278 if (var) 09279 AST_LIST_INSERT_TAIL(varlist, var, entries); 09280 else 09281 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09282 AST_LIST_UNLOCK(varlist); 09283 return 0; 09284 }
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2238 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), calltoken_ignores, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02239 { 02240 struct addr_range tmp; 02241 struct addr_range *addr_range = NULL; 02242 struct ast_ha *ha = NULL; 02243 int error = 0; 02244 02245 if (ast_strlen_zero(addr)) { 02246 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02247 return -1; 02248 } 02249 02250 ha = ast_append_ha("permit", addr, NULL, &error); 02251 02252 /* check for valid config information */ 02253 if (error) { 02254 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02255 return -1; 02256 } 02257 02258 ast_copy_ha(ha, &tmp.ha); 02259 /* find or create the addr_range */ 02260 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02261 ao2_lock(addr_range); 02262 addr_range->delme = 0; 02263 ao2_unlock(addr_range); 02264 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02265 /* copy over config data into addr_range object */ 02266 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02267 ao2_link(calltoken_ignores, addr_range); 02268 } else { 02269 ast_free_ha(ha); 02270 return -1; 02271 } 02272 02273 ast_free_ha(ha); 02274 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02275 02276 return 0; 02277 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4397 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().
04398 { 04399 /* first make sure their are two empty bytes left in ied->buf */ 04400 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04401 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04402 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04403 pvt->calltoken_ie_len = 2; 04404 } 04405 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1900 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
01901 { 01902 struct addr_range *lim1 = obj, *lim2 = arg; 01903 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) && 01904 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ? 01905 CMP_MATCH | CMP_STOP : 0; 01906 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1887 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01888 { 01889 struct addr_range *lim = obj; 01890 lim->delme = 1; 01891 return 0; 01892 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1894 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01895 { 01896 const struct addr_range *lim = obj; 01897 return abs((int) lim->ha.netaddr.s_addr); 01898 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1920 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().
01921 { 01922 struct addr_range *addr_range = obj; 01923 struct sockaddr_in *sin = arg; 01924 01925 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 01926 return CMP_MATCH | CMP_STOP; 01927 } 01928 return 0; 01929 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 7026 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07027 { 07028 while(con) { 07029 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07030 return -1; 07031 con = con->next; 07032 } 07033 return 0; 07034 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 6731 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, iaxs, 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, chan_iax2_pvt::remote_rr, and s.
Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().
06732 { 06733 int x; 06734 int numchans = 0; 06735 char first_message[10] = { 0, }; 06736 char last_message[10] = { 0, }; 06737 #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" 06738 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 06739 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06740 ast_mutex_lock(&iaxsl[x]); 06741 if (iaxs[x]) { 06742 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06743 jb_info jbinfo; 06744 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06745 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06746 06747 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06748 jb_getinfo(iaxs[x]->jb, &jbinfo); 06749 localjitter = jbinfo.jitter; 06750 localdelay = jbinfo.current - jbinfo.min; 06751 locallost = jbinfo.frames_lost; 06752 locallosspct = jbinfo.losspct/1000; 06753 localdropped = jbinfo.frames_dropped; 06754 localooo = jbinfo.frames_ooo; 06755 } else { 06756 localjitter = -1; 06757 localdelay = 0; 06758 locallost = -1; 06759 locallosspct = -1; 06760 localdropped = 0; 06761 localooo = -1; 06762 } 06763 if (s) 06764 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06765 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06766 iaxs[x]->pingtime, 06767 localjitter, 06768 localdelay, 06769 locallost, 06770 locallosspct, 06771 localdropped, 06772 localooo, 06773 iaxs[x]->frames_received/1000, 06774 iaxs[x]->remote_rr.jitter, 06775 iaxs[x]->remote_rr.delay, 06776 iaxs[x]->remote_rr.losscnt, 06777 iaxs[x]->remote_rr.losspct, 06778 iaxs[x]->remote_rr.dropped, 06779 iaxs[x]->remote_rr.ooo, 06780 iaxs[x]->remote_rr.packets/1000, 06781 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06782 first_message, 06783 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06784 last_message); 06785 else 06786 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06787 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06788 iaxs[x]->pingtime, 06789 localjitter, 06790 localdelay, 06791 locallost, 06792 locallosspct, 06793 localdropped, 06794 localooo, 06795 iaxs[x]->frames_received/1000, 06796 iaxs[x]->remote_rr.jitter, 06797 iaxs[x]->remote_rr.delay, 06798 iaxs[x]->remote_rr.losscnt, 06799 iaxs[x]->remote_rr.losspct, 06800 iaxs[x]->remote_rr.dropped, 06801 iaxs[x]->remote_rr.ooo, 06802 iaxs[x]->remote_rr.packets/1000, 06803 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06804 first_message, 06805 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06806 last_message); 06807 numchans++; 06808 } 06809 ast_mutex_unlock(&iaxsl[x]); 06810 } 06811 06812 return numchans; 06813 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 5308 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(), iax2_tech, iax2_variable_datastore_info, iaxs, chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05309 { 05310 struct ast_channel *tmp; 05311 struct chan_iax2_pvt *i; 05312 struct ast_variable *v = NULL; 05313 05314 if (!(i = iaxs[callno])) { 05315 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05316 return NULL; 05317 } 05318 05319 /* Don't hold call lock */ 05320 ast_mutex_unlock(&iaxsl[callno]); 05321 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); 05322 ast_mutex_lock(&iaxsl[callno]); 05323 if (i != iaxs[callno]) { 05324 if (tmp) { 05325 /* unlock and relock iaxsl[callno] to preserve locking order */ 05326 ast_mutex_unlock(&iaxsl[callno]); 05327 ast_channel_free(tmp); 05328 ast_mutex_lock(&iaxsl[callno]); 05329 } 05330 return NULL; 05331 } 05332 iax2_ami_channelupdate(i); 05333 if (!tmp) 05334 return NULL; 05335 tmp->tech = &iax2_tech; 05336 /* We can support any format by default, until we get restricted */ 05337 tmp->nativeformats = capability; 05338 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05339 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05340 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05341 05342 if (!ast_strlen_zero(i->parkinglot)) 05343 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05344 /* Don't use ast_set_callerid() here because it will 05345 * generate a NewCallerID event before the NewChannel event */ 05346 if (!ast_strlen_zero(i->ani)) 05347 tmp->cid.cid_ani = ast_strdup(i->ani); 05348 else 05349 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05350 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05351 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05352 tmp->cid.cid_pres = i->calling_pres; 05353 tmp->cid.cid_ton = i->calling_ton; 05354 tmp->cid.cid_tns = i->calling_tns; 05355 if (!ast_strlen_zero(i->language)) 05356 ast_string_field_set(tmp, language, i->language); 05357 if (!ast_strlen_zero(i->accountcode)) 05358 ast_string_field_set(tmp, accountcode, i->accountcode); 05359 if (i->amaflags) 05360 tmp->amaflags = i->amaflags; 05361 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05362 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05363 if (i->adsi) 05364 tmp->adsicpe = i->peeradsicpe; 05365 else 05366 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05367 i->owner = tmp; 05368 i->capability = capability; 05369 05370 /* Set inherited variables */ 05371 if (i->vars) { 05372 for (v = i->vars ; v ; v = v->next) 05373 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05374 } 05375 if (i->iaxvars) { 05376 struct ast_datastore *variablestore; 05377 struct ast_variable *var, *prev = NULL; 05378 AST_LIST_HEAD(, ast_var_t) *varlist; 05379 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05380 varlist = ast_calloc(1, sizeof(*varlist)); 05381 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05382 if (variablestore && varlist) { 05383 variablestore->data = varlist; 05384 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05385 AST_LIST_HEAD_INIT(varlist); 05386 for (var = i->iaxvars; var; var = var->next) { 05387 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05388 if (prev) 05389 ast_free(prev); 05390 prev = var; 05391 if (!newvar) { 05392 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05393 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05394 } else { 05395 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05396 } 05397 } 05398 if (prev) 05399 ast_free(prev); 05400 i->iaxvars = NULL; 05401 ast_channel_datastore_add(i->owner, variablestore); 05402 } else { 05403 if (variablestore) { 05404 ast_datastore_free(variablestore); 05405 } 05406 if (varlist) { 05407 ast_free(varlist); 05408 } 05409 } 05410 } 05411 05412 if (state != AST_STATE_DOWN) { 05413 if (ast_pbx_start(tmp)) { 05414 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05415 ast_hangup(tmp); 05416 i->owner = NULL; 05417 return NULL; 05418 } 05419 } 05420 05421 ast_module_ref(ast_module_info->self); 05422 return tmp; 05423 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3291 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03292 { 03293 #ifdef SCHED_MULTITHREADED 03294 if (schedule_action(__attempt_transmit, data)) 03295 #endif 03296 __attempt_transmit(data); 03297 return 0; 03298 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 8474 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_replace(), iaxs, and sched.
Referenced by socket_process().
08475 { 08476 /* Schedule sending the authentication failure in one second, to prevent 08477 guessing */ 08478 if (iaxs[callno]) { 08479 iaxs[callno]->authfail = failcode; 08480 if (delayreject) { 08481 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08482 sched, 1000, auth_reject, (void *)(long)callno); 08483 } else 08484 auth_reject((void *)(long)callno); 08485 } 08486 return 0; 08487 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8460 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iaxs, and schedule_action.
Referenced by auth_fail().
08461 { 08462 int callno = (int)(long)(data); 08463 ast_mutex_lock(&iaxsl[callno]); 08464 if (iaxs[callno]) 08465 iaxs[callno]->authid = -1; 08466 ast_mutex_unlock(&iaxsl[callno]); 08467 #ifdef SCHED_MULTITHREADED 08468 if (schedule_action(__auth_reject, data)) 08469 #endif 08470 __auth_reject(data); 08471 return 0; 08472 }
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 7593 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
07594 { 07595 int res = -1; 07596 int x; 07597 if (!ast_strlen_zero(keyn)) { 07598 if (!(authmethods & IAX_AUTH_RSA)) { 07599 if (ast_strlen_zero(secret)) 07600 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)); 07601 } else if (ast_strlen_zero(challenge)) { 07602 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 07603 } else { 07604 char sig[256]; 07605 struct ast_key *key; 07606 key = ast_key_get(keyn, AST_KEY_PRIVATE); 07607 if (!key) { 07608 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 07609 } else { 07610 if (ast_sign(key, (char*)challenge, sig)) { 07611 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 07612 res = -1; 07613 } else { 07614 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 07615 res = 0; 07616 } 07617 } 07618 } 07619 } 07620 /* Fall back */ 07621 if (res && !ast_strlen_zero(secret)) { 07622 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 07623 struct MD5Context md5; 07624 unsigned char digest[16]; 07625 char digres[128]; 07626 MD5Init(&md5); 07627 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 07628 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 07629 MD5Final(digest, &md5); 07630 /* If they support md5, authenticate with it. */ 07631 for (x=0;x<16;x++) 07632 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 07633 if (pvt) { 07634 build_encryption_keys(digest, pvt); 07635 } 07636 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 07637 res = 0; 07638 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 07639 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 07640 res = 0; 07641 } else 07642 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 07643 } 07644 return res; 07645 }
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 7651 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, ast_datastore::inheritance, LOG_ERROR, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.
Referenced by socket_process().
07652 { 07653 struct iax2_peer *peer = NULL; 07654 /* Start pessimistic */ 07655 int res = -1; 07656 int authmethods = 0; 07657 struct iax_ie_data ied; 07658 uint16_t callno = p->callno; 07659 07660 memset(&ied, 0, sizeof(ied)); 07661 07662 if (ies->username) 07663 ast_string_field_set(p, username, ies->username); 07664 if (ies->challenge) 07665 ast_string_field_set(p, challenge, ies->challenge); 07666 if (ies->authmethods) 07667 authmethods = ies->authmethods; 07668 if (authmethods & IAX_AUTH_MD5) 07669 merge_encryption(p, ies->encmethods); 07670 else 07671 p->encmethods = 0; 07672 07673 /* Check for override RSA authentication first */ 07674 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07675 /* Normal password authentication */ 07676 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07677 } else { 07678 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07679 while ((peer = ao2_iterator_next(&i))) { 07680 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07681 /* No peer specified at our end, or this is the peer */ 07682 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07683 /* No username specified in peer rule, or this is the right username */ 07684 && (!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))) 07685 /* No specified host, or this is our host */ 07686 ) { 07687 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07688 if (!res) { 07689 peer_unref(peer); 07690 break; 07691 } 07692 } 07693 peer_unref(peer); 07694 } 07695 ao2_iterator_destroy(&i); 07696 if (!peer) { 07697 /* We checked our list and didn't find one. It's unlikely, but possible, 07698 that we're trying to authenticate *to* a realtime peer */ 07699 const char *peer_name = ast_strdupa(p->peer); 07700 ast_mutex_unlock(&iaxsl[callno]); 07701 if ((peer = realtime_peer(peer_name, NULL))) { 07702 ast_mutex_lock(&iaxsl[callno]); 07703 if (!(p = iaxs[callno])) { 07704 peer_unref(peer); 07705 return -1; 07706 } 07707 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07708 peer_unref(peer); 07709 } 07710 if (!peer) { 07711 ast_mutex_lock(&iaxsl[callno]); 07712 if (!(p = iaxs[callno])) 07713 return -1; 07714 } 07715 } 07716 } 07717 if (ies->encmethods) 07718 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07719 if (!res) { 07720 struct ast_datastore *variablestore; 07721 struct ast_variable *var, *prev = NULL; 07722 AST_LIST_HEAD(, ast_var_t) *varlist; 07723 varlist = ast_calloc(1, sizeof(*varlist)); 07724 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 07725 if (variablestore && varlist && p->owner) { 07726 variablestore->data = varlist; 07727 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 07728 AST_LIST_HEAD_INIT(varlist); 07729 for (var = ies->vars; var; var = var->next) { 07730 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 07731 if (prev) 07732 ast_free(prev); 07733 prev = var; 07734 if (!newvar) { 07735 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 07736 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07737 } else { 07738 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 07739 } 07740 } 07741 if (prev) 07742 ast_free(prev); 07743 ies->vars = NULL; 07744 ast_channel_datastore_add(p->owner, variablestore); 07745 } else { 07746 if (p->owner) 07747 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07748 if (variablestore) 07749 ast_datastore_free(variablestore); 07750 if (varlist) 07751 ast_free(varlist); 07752 } 07753 } 07754 07755 if (!res) 07756 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 07757 return res; 07758 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7304 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, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, OBJ_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07305 { 07306 struct iax_ie_data ied; 07307 int res = -1, authreq_restrict = 0; 07308 char challenge[10]; 07309 struct chan_iax2_pvt *p = iaxs[call_num]; 07310 07311 memset(&ied, 0, sizeof(ied)); 07312 07313 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07314 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07315 struct iax2_user *user, tmp_user = { 07316 .name = p->username, 07317 }; 07318 07319 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07320 if (user) { 07321 if (user->curauthreq == user->maxauthreq) 07322 authreq_restrict = 1; 07323 else 07324 user->curauthreq++; 07325 user = user_unref(user); 07326 } 07327 } 07328 07329 /* If the AUTHREQ limit test failed, send back an error */ 07330 if (authreq_restrict) { 07331 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07332 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07333 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07334 return 0; 07335 } 07336 07337 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07338 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07339 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07340 ast_string_field_set(p, challenge, challenge); 07341 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07342 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07343 } 07344 if (p->encmethods) 07345 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07346 07347 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07348 07349 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07350 07351 if (p->encmethods) 07352 ast_set_flag(p, IAX_ENCRYPTED); 07353 07354 return res; 07355 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7357 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07358 { 07359 char requeststr[256]; 07360 char md5secret[256] = ""; 07361 char secret[256] = ""; 07362 char rsasecret[256] = ""; 07363 int res = -1; 07364 int x; 07365 struct iax2_user *user, tmp_user = { 07366 .name = p->username, 07367 }; 07368 07369 if (p->authrej) { 07370 return res; 07371 } 07372 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07373 if (user) { 07374 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07375 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07376 ast_clear_flag(p, IAX_MAXAUTHREQ); 07377 } 07378 ast_string_field_set(p, host, user->name); 07379 user = user_unref(user); 07380 } 07381 07382 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07383 return res; 07384 if (ies->password) 07385 ast_copy_string(secret, ies->password, sizeof(secret)); 07386 if (ies->md5_result) 07387 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07388 if (ies->rsa_result) 07389 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07390 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07391 struct ast_key *key; 07392 char *keyn; 07393 char tmpkey[256]; 07394 char *stringp=NULL; 07395 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07396 stringp=tmpkey; 07397 keyn = strsep(&stringp, ":"); 07398 while(keyn) { 07399 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07400 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07401 res = 0; 07402 break; 07403 } else if (!key) 07404 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07405 keyn = strsep(&stringp, ":"); 07406 } 07407 } else if (p->authmethods & IAX_AUTH_MD5) { 07408 struct MD5Context md5; 07409 unsigned char digest[16]; 07410 char *tmppw, *stringp; 07411 07412 tmppw = ast_strdupa(p->secret); 07413 stringp = tmppw; 07414 while((tmppw = strsep(&stringp, ";"))) { 07415 MD5Init(&md5); 07416 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07417 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07418 MD5Final(digest, &md5); 07419 /* If they support md5, authenticate with it. */ 07420 for (x=0;x<16;x++) 07421 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07422 if (!strcasecmp(requeststr, md5secret)) { 07423 res = 0; 07424 break; 07425 } 07426 } 07427 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07428 if (!strcmp(secret, p->secret)) 07429 res = 0; 07430 } 07431 return res; 07432 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4336 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04337 { 04338 #ifdef SCHED_MULTITHREADED 04339 if (schedule_action(__auto_congest, data)) 04340 #endif 04341 __auto_congest(data); 04342 return 0; 04343 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 8504 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
08505 { 08506 int callno = (int)(long)(data); 08507 ast_mutex_lock(&iaxsl[callno]); 08508 if (iaxs[callno]) { 08509 iaxs[callno]->autoid = -1; 08510 } 08511 ast_mutex_unlock(&iaxsl[callno]); 08512 #ifdef SCHED_MULTITHREADED 08513 if (schedule_action(__auto_hangup, data)) 08514 #endif 08515 __auto_hangup(data); 08516 return 0; 08517 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2183 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02184 { 02185 struct addr_range *addr_range = NULL; 02186 struct addr_range tmp; 02187 struct ast_ha *ha; 02188 int limit; 02189 int error; 02190 int found; 02191 02192 for (; v; v = v->next) { 02193 limit = -1; 02194 error = 0; 02195 found = 0; 02196 ha = ast_append_ha("permit", v->name, NULL, &error); 02197 02198 /* check for valid config information */ 02199 if (error) { 02200 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02201 continue; 02202 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02203 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02204 ast_free_ha(ha); 02205 continue; 02206 } 02207 02208 ast_copy_ha(ha, &tmp.ha); 02209 /* find or create the addr_range */ 02210 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02211 ao2_lock(addr_range); 02212 found = 1; 02213 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02214 ast_free_ha(ha); 02215 return; /* out of memory */ 02216 } 02217 02218 /* copy over config data into addr_range object */ 02219 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02220 ast_free_ha(ha); /* cleanup the tmp ha */ 02221 addr_range->limit = limit; 02222 addr_range->delme = 0; 02223 02224 /* cleanup */ 02225 if (found) { 02226 ao2_unlock(addr_range); 02227 } else { 02228 ao2_link(callno_limits, addr_range); 02229 } 02230 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02231 } 02232 }
static struct iax2_context* build_context | ( | const char * | context | ) | [static] |
Definition at line 11593 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
11594 { 11595 struct iax2_context *con; 11596 11597 if ((con = ast_calloc(1, sizeof(*con)))) 11598 ast_copy_string(con->context, context, sizeof(con->context)); 11599 11600 return con; 11601 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5766 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().
05767 { 05768 /* it is required to hold the corresponding decrypt key to our encrypt key 05769 * in the pvt struct because queued frames occasionally need to be decrypted and 05770 * re-encrypted when updated for a retransmission */ 05771 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05772 ast_aes_encrypt_key(digest, &pvt->ecx); 05773 ast_aes_decrypt_key(digest, &pvt->mydcx); 05774 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5760 of file chan_iax2.c.
References ast_aes_decrypt_key, build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05761 { 05762 build_ecx_key(digest, pvt); 05763 ast_aes_decrypt_key(digest, &pvt->dcx); 05764 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 11741 of file chan_iax2.c.
References ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), iax2_peer::inkeys, ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), 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, peers, prefs, regexten, S_OR, sched, secret, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.
11742 { 11743 struct iax2_peer *peer = NULL; 11744 struct ast_ha *oldha = NULL; 11745 int maskfound = 0; 11746 int found = 0; 11747 int firstpass = 1; 11748 struct iax2_peer tmp_peer = { 11749 .name = name, 11750 }; 11751 11752 if (!temponly) { 11753 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 11754 if (peer && !ast_test_flag(peer, IAX_DELME)) 11755 firstpass = 0; 11756 } 11757 11758 if (peer) { 11759 found++; 11760 if (firstpass) { 11761 oldha = peer->ha; 11762 peer->ha = NULL; 11763 } 11764 unlink_peer(peer); 11765 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 11766 peer->expire = -1; 11767 peer->pokeexpire = -1; 11768 peer->sockfd = defaultsockfd; 11769 if (ast_string_field_init(peer, 32)) 11770 peer = peer_unref(peer); 11771 } 11772 11773 if (peer) { 11774 if (firstpass) { 11775 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11776 peer->encmethods = iax2_encryption; 11777 peer->adsi = adsi; 11778 ast_string_field_set(peer,secret,""); 11779 if (!found) { 11780 ast_string_field_set(peer, name, name); 11781 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11782 peer->expiry = min_reg_expire; 11783 } 11784 peer->prefs = prefs; 11785 peer->capability = iax2_capability; 11786 peer->smoothing = 0; 11787 peer->pokefreqok = DEFAULT_FREQ_OK; 11788 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 11789 peer->maxcallno = 0; 11790 peercnt_modify(0, 0, &peer->addr); 11791 peer->calltoken_required = CALLTOKEN_DEFAULT; 11792 ast_string_field_set(peer,context,""); 11793 ast_string_field_set(peer,peercontext,""); 11794 ast_clear_flag(peer, IAX_HASCALLERID); 11795 ast_string_field_set(peer, cid_name, ""); 11796 ast_string_field_set(peer, cid_num, ""); 11797 ast_string_field_set(peer, mohinterpret, mohinterpret); 11798 ast_string_field_set(peer, mohsuggest, mohsuggest); 11799 } 11800 11801 if (!v) { 11802 v = alt; 11803 alt = NULL; 11804 } 11805 while(v) { 11806 if (!strcasecmp(v->name, "secret")) { 11807 ast_string_field_set(peer, secret, v->value); 11808 } else if (!strcasecmp(v->name, "mailbox")) { 11809 ast_string_field_set(peer, mailbox, v->value); 11810 } else if (!strcasecmp(v->name, "hasvoicemail")) { 11811 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 11812 ast_string_field_set(peer, mailbox, name); 11813 } 11814 } else if (!strcasecmp(v->name, "mohinterpret")) { 11815 ast_string_field_set(peer, mohinterpret, v->value); 11816 } else if (!strcasecmp(v->name, "mohsuggest")) { 11817 ast_string_field_set(peer, mohsuggest, v->value); 11818 } else if (!strcasecmp(v->name, "dbsecret")) { 11819 ast_string_field_set(peer, dbsecret, v->value); 11820 } else if (!strcasecmp(v->name, "trunk")) { 11821 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 11822 if (ast_test_flag(peer, IAX_TRUNK) && !timer) { 11823 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 11824 ast_clear_flag(peer, IAX_TRUNK); 11825 } 11826 } else if (!strcasecmp(v->name, "auth")) { 11827 peer->authmethods = get_auth_methods(v->value); 11828 } else if (!strcasecmp(v->name, "encryption")) { 11829 peer->encmethods |= get_encrypt_methods(v->value); 11830 } else if (!strcasecmp(v->name, "transfer")) { 11831 if (!strcasecmp(v->value, "mediaonly")) { 11832 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11833 } else if (ast_true(v->value)) { 11834 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11835 } else 11836 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11837 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11838 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 11839 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11840 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 11841 } else if (!strcasecmp(v->name, "host")) { 11842 if (!strcasecmp(v->value, "dynamic")) { 11843 /* They'll register with us */ 11844 ast_set_flag(peer, IAX_DYNAMIC); 11845 if (!found) { 11846 /* Initialize stuff iff we're not found, otherwise 11847 we keep going with what we had */ 11848 memset(&peer->addr.sin_addr, 0, 4); 11849 if (peer->addr.sin_port) { 11850 /* If we've already got a port, make it the default rather than absolute */ 11851 peer->defaddr.sin_port = peer->addr.sin_port; 11852 peer->addr.sin_port = 0; 11853 } 11854 } 11855 } else { 11856 /* Non-dynamic. Make sure we become that way if we're not */ 11857 AST_SCHED_DEL(sched, peer->expire); 11858 ast_clear_flag(peer, IAX_DYNAMIC); 11859 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 11860 return peer_unref(peer); 11861 if (!peer->addr.sin_port) 11862 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11863 } 11864 if (!maskfound) 11865 inet_aton("255.255.255.255", &peer->mask); 11866 } else if (!strcasecmp(v->name, "defaultip")) { 11867 if (ast_get_ip(&peer->defaddr, v->value)) 11868 return peer_unref(peer); 11869 } else if (!strcasecmp(v->name, "sourceaddress")) { 11870 peer_set_srcaddr(peer, v->value); 11871 } else if (!strcasecmp(v->name, "permit") || 11872 !strcasecmp(v->name, "deny")) { 11873 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 11874 } else if (!strcasecmp(v->name, "mask")) { 11875 maskfound++; 11876 inet_aton(v->value, &peer->mask); 11877 } else if (!strcasecmp(v->name, "context")) { 11878 ast_string_field_set(peer, context, v->value); 11879 } else if (!strcasecmp(v->name, "regexten")) { 11880 ast_string_field_set(peer, regexten, v->value); 11881 } else if (!strcasecmp(v->name, "peercontext")) { 11882 ast_string_field_set(peer, peercontext, v->value); 11883 } else if (!strcasecmp(v->name, "port")) { 11884 if (ast_test_flag(peer, IAX_DYNAMIC)) 11885 peer->defaddr.sin_port = htons(atoi(v->value)); 11886 else 11887 peer->addr.sin_port = htons(atoi(v->value)); 11888 } else if (!strcasecmp(v->name, "username")) { 11889 ast_string_field_set(peer, username, v->value); 11890 } else if (!strcasecmp(v->name, "allow")) { 11891 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 11892 } else if (!strcasecmp(v->name, "disallow")) { 11893 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 11894 } else if (!strcasecmp(v->name, "callerid")) { 11895 if (!ast_strlen_zero(v->value)) { 11896 char name2[80]; 11897 char num2[80]; 11898 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 11899 ast_string_field_set(peer, cid_name, name2); 11900 ast_string_field_set(peer, cid_num, num2); 11901 } else { 11902 ast_string_field_set(peer, cid_name, ""); 11903 ast_string_field_set(peer, cid_num, ""); 11904 } 11905 ast_set_flag(peer, IAX_HASCALLERID); 11906 } else if (!strcasecmp(v->name, "fullname")) { 11907 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 11908 ast_set_flag(peer, IAX_HASCALLERID); 11909 } else if (!strcasecmp(v->name, "cid_number")) { 11910 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 11911 ast_set_flag(peer, IAX_HASCALLERID); 11912 } else if (!strcasecmp(v->name, "sendani")) { 11913 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 11914 } else if (!strcasecmp(v->name, "inkeys")) { 11915 ast_string_field_set(peer, inkeys, v->value); 11916 } else if (!strcasecmp(v->name, "outkey")) { 11917 ast_string_field_set(peer, outkey, v->value); 11918 } else if (!strcasecmp(v->name, "qualify")) { 11919 if (!strcasecmp(v->value, "no")) { 11920 peer->maxms = 0; 11921 } else if (!strcasecmp(v->value, "yes")) { 11922 peer->maxms = DEFAULT_MAXMS; 11923 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 11924 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); 11925 peer->maxms = 0; 11926 } 11927 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 11928 peer->smoothing = ast_true(v->value); 11929 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 11930 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 11931 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); 11932 } 11933 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 11934 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 11935 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); 11936 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 11937 } else if (!strcasecmp(v->name, "timezone")) { 11938 ast_string_field_set(peer, zonetag, v->value); 11939 } else if (!strcasecmp(v->name, "adsi")) { 11940 peer->adsi = ast_true(v->value); 11941 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11942 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 11943 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 11944 } else { 11945 peercnt_modify(1, peer->maxcallno, &peer->addr); 11946 } 11947 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11948 /* default is required unless in optional ip list */ 11949 if (ast_false(v->value)) { 11950 peer->calltoken_required = CALLTOKEN_NO; 11951 } else if (!strcasecmp(v->value, "auto")) { 11952 peer->calltoken_required = CALLTOKEN_AUTO; 11953 } else if (ast_true(v->value)) { 11954 peer->calltoken_required = CALLTOKEN_YES; 11955 } else { 11956 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11957 } 11958 } /* else if (strcasecmp(v->name,"type")) */ 11959 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11960 v = v->next; 11961 if (!v) { 11962 v = alt; 11963 alt = NULL; 11964 } 11965 } 11966 if (!peer->authmethods) 11967 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11968 ast_clear_flag(peer, IAX_DELME); 11969 /* Make sure these are IPv4 addresses */ 11970 peer->addr.sin_family = AF_INET; 11971 } 11972 11973 if (oldha) 11974 ast_free_ha(oldha); 11975 11976 if (!ast_strlen_zero(peer->mailbox)) { 11977 char *mailbox, *context; 11978 context = mailbox = ast_strdupa(peer->mailbox); 11979 strsep(&context, "@"); 11980 if (ast_strlen_zero(context)) 11981 context = "default"; 11982 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL, 11983 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 11984 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 11985 AST_EVENT_IE_END); 11986 } 11987 11988 return peer; 11989 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 5750 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05751 { 05752 long tmp; 05753 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05754 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05755 buf += sizeof(tmp); 05756 len -= sizeof(tmp); 05757 } 05758 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 12005 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.
12006 { 12007 struct iax2_user *user = NULL; 12008 struct iax2_context *con, *conl = NULL; 12009 struct ast_ha *oldha = NULL; 12010 struct iax2_context *oldcon = NULL; 12011 int format; 12012 int firstpass=1; 12013 int oldcurauthreq = 0; 12014 char *varname = NULL, *varval = NULL; 12015 struct ast_variable *tmpvar = NULL; 12016 struct iax2_user tmp_user = { 12017 .name = name, 12018 }; 12019 12020 if (!temponly) { 12021 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12022 if (user && !ast_test_flag(user, IAX_DELME)) 12023 firstpass = 0; 12024 } 12025 12026 if (user) { 12027 if (firstpass) { 12028 oldcurauthreq = user->curauthreq; 12029 oldha = user->ha; 12030 oldcon = user->contexts; 12031 user->ha = NULL; 12032 user->contexts = NULL; 12033 } 12034 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12035 ao2_unlink(users, user); 12036 } else { 12037 user = ao2_alloc(sizeof(*user), user_destructor); 12038 } 12039 12040 if (user) { 12041 if (firstpass) { 12042 ast_string_field_free_memory(user); 12043 memset(user, 0, sizeof(struct iax2_user)); 12044 if (ast_string_field_init(user, 32)) { 12045 user = user_unref(user); 12046 goto cleanup; 12047 } 12048 user->maxauthreq = maxauthreq; 12049 user->curauthreq = oldcurauthreq; 12050 user->prefs = prefs; 12051 user->capability = iax2_capability; 12052 user->encmethods = iax2_encryption; 12053 user->adsi = adsi; 12054 user->calltoken_required = CALLTOKEN_DEFAULT; 12055 ast_string_field_set(user, name, name); 12056 ast_string_field_set(user, language, language); 12057 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 12058 ast_clear_flag(user, IAX_HASCALLERID); 12059 ast_string_field_set(user, cid_name, ""); 12060 ast_string_field_set(user, cid_num, ""); 12061 ast_string_field_set(user, accountcode, accountcode); 12062 ast_string_field_set(user, mohinterpret, mohinterpret); 12063 ast_string_field_set(user, mohsuggest, mohsuggest); 12064 } 12065 if (!v) { 12066 v = alt; 12067 alt = NULL; 12068 } 12069 while(v) { 12070 if (!strcasecmp(v->name, "context")) { 12071 con = build_context(v->value); 12072 if (con) { 12073 if (conl) 12074 conl->next = con; 12075 else 12076 user->contexts = con; 12077 conl = con; 12078 } 12079 } else if (!strcasecmp(v->name, "permit") || 12080 !strcasecmp(v->name, "deny")) { 12081 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12082 } else if (!strcasecmp(v->name, "setvar")) { 12083 varname = ast_strdupa(v->value); 12084 if (varname && (varval = strchr(varname,'='))) { 12085 *varval = '\0'; 12086 varval++; 12087 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12088 tmpvar->next = user->vars; 12089 user->vars = tmpvar; 12090 } 12091 } 12092 } else if (!strcasecmp(v->name, "allow")) { 12093 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12094 } else if (!strcasecmp(v->name, "disallow")) { 12095 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12096 } else if (!strcasecmp(v->name, "trunk")) { 12097 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 12098 if (ast_test_flag(user, IAX_TRUNK) && !timer) { 12099 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12100 ast_clear_flag(user, IAX_TRUNK); 12101 } 12102 } else if (!strcasecmp(v->name, "auth")) { 12103 user->authmethods = get_auth_methods(v->value); 12104 } else if (!strcasecmp(v->name, "encryption")) { 12105 user->encmethods |= get_encrypt_methods(v->value); 12106 } else if (!strcasecmp(v->name, "transfer")) { 12107 if (!strcasecmp(v->value, "mediaonly")) { 12108 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12109 } else if (ast_true(v->value)) { 12110 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12111 } else 12112 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12113 } else if (!strcasecmp(v->name, "codecpriority")) { 12114 if(!strcasecmp(v->value, "caller")) 12115 ast_set_flag(user, IAX_CODEC_USER_FIRST); 12116 else if(!strcasecmp(v->value, "disabled")) 12117 ast_set_flag(user, IAX_CODEC_NOPREFS); 12118 else if(!strcasecmp(v->value, "reqonly")) { 12119 ast_set_flag(user, IAX_CODEC_NOCAP); 12120 ast_set_flag(user, IAX_CODEC_NOPREFS); 12121 } 12122 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12123 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 12124 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12125 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12126 } else if (!strcasecmp(v->name, "dbsecret")) { 12127 ast_string_field_set(user, dbsecret, v->value); 12128 } else if (!strcasecmp(v->name, "secret")) { 12129 if (!ast_strlen_zero(user->secret)) { 12130 char *old = ast_strdupa(user->secret); 12131 12132 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12133 } else 12134 ast_string_field_set(user, secret, v->value); 12135 } else if (!strcasecmp(v->name, "callerid")) { 12136 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12137 char name2[80]; 12138 char num2[80]; 12139 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12140 ast_string_field_set(user, cid_name, name2); 12141 ast_string_field_set(user, cid_num, num2); 12142 ast_set_flag(user, IAX_HASCALLERID); 12143 } else { 12144 ast_clear_flag(user, IAX_HASCALLERID); 12145 ast_string_field_set(user, cid_name, ""); 12146 ast_string_field_set(user, cid_num, ""); 12147 } 12148 } else if (!strcasecmp(v->name, "fullname")) { 12149 if (!ast_strlen_zero(v->value)) { 12150 ast_string_field_set(user, cid_name, v->value); 12151 ast_set_flag(user, IAX_HASCALLERID); 12152 } else { 12153 ast_string_field_set(user, cid_name, ""); 12154 if (ast_strlen_zero(user->cid_num)) 12155 ast_clear_flag(user, IAX_HASCALLERID); 12156 } 12157 } else if (!strcasecmp(v->name, "cid_number")) { 12158 if (!ast_strlen_zero(v->value)) { 12159 ast_string_field_set(user, cid_num, v->value); 12160 ast_set_flag(user, IAX_HASCALLERID); 12161 } else { 12162 ast_string_field_set(user, cid_num, ""); 12163 if (ast_strlen_zero(user->cid_name)) 12164 ast_clear_flag(user, IAX_HASCALLERID); 12165 } 12166 } else if (!strcasecmp(v->name, "accountcode")) { 12167 ast_string_field_set(user, accountcode, v->value); 12168 } else if (!strcasecmp(v->name, "mohinterpret")) { 12169 ast_string_field_set(user, mohinterpret, v->value); 12170 } else if (!strcasecmp(v->name, "mohsuggest")) { 12171 ast_string_field_set(user, mohsuggest, v->value); 12172 } else if (!strcasecmp(v->name, "parkinglot")) { 12173 ast_string_field_set(user, parkinglot, v->value); 12174 } else if (!strcasecmp(v->name, "language")) { 12175 ast_string_field_set(user, language, v->value); 12176 } else if (!strcasecmp(v->name, "amaflags")) { 12177 format = ast_cdr_amaflags2int(v->value); 12178 if (format < 0) { 12179 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12180 } else { 12181 user->amaflags = format; 12182 } 12183 } else if (!strcasecmp(v->name, "inkeys")) { 12184 ast_string_field_set(user, inkeys, v->value); 12185 } else if (!strcasecmp(v->name, "maxauthreq")) { 12186 user->maxauthreq = atoi(v->value); 12187 if (user->maxauthreq < 0) 12188 user->maxauthreq = 0; 12189 } else if (!strcasecmp(v->name, "adsi")) { 12190 user->adsi = ast_true(v->value); 12191 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12192 /* default is required unless in optional ip list */ 12193 if (ast_false(v->value)) { 12194 user->calltoken_required = CALLTOKEN_NO; 12195 } else if (!strcasecmp(v->value, "auto")) { 12196 user->calltoken_required = CALLTOKEN_AUTO; 12197 } else if (ast_true(v->value)) { 12198 user->calltoken_required = CALLTOKEN_YES; 12199 } else { 12200 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12201 } 12202 } /* else if (strcasecmp(v->name,"type")) */ 12203 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12204 v = v->next; 12205 if (!v) { 12206 v = alt; 12207 alt = NULL; 12208 } 12209 } 12210 if (!user->authmethods) { 12211 if (!ast_strlen_zero(user->secret)) { 12212 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12213 if (!ast_strlen_zero(user->inkeys)) 12214 user->authmethods |= IAX_AUTH_RSA; 12215 } else if (!ast_strlen_zero(user->inkeys)) { 12216 user->authmethods = IAX_AUTH_RSA; 12217 } else { 12218 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12219 } 12220 } 12221 ast_clear_flag(user, IAX_DELME); 12222 } 12223 cleanup: 12224 if (oldha) 12225 ast_free_ha(oldha); 12226 if (oldcon) 12227 free_context(oldcon); 12228 return user; 12229 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 12813 of file chan_iax2.c.
References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
12814 { 12815 struct sockaddr_in sin; 12816 int x; 12817 int callno; 12818 struct iax_ie_data ied; 12819 struct create_addr_info cai; 12820 struct parsed_dial_string pds; 12821 char *tmpstr; 12822 12823 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 12824 /* Look for an *exact match* call. Once a call is negotiated, it can only 12825 look up entries for a single context */ 12826 if (!ast_mutex_trylock(&iaxsl[x])) { 12827 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 12828 return x; 12829 ast_mutex_unlock(&iaxsl[x]); 12830 } 12831 } 12832 12833 /* No match found, we need to create a new one */ 12834 12835 memset(&cai, 0, sizeof(cai)); 12836 memset(&ied, 0, sizeof(ied)); 12837 memset(&pds, 0, sizeof(pds)); 12838 12839 tmpstr = ast_strdupa(data); 12840 parse_dial_string(tmpstr, &pds); 12841 12842 if (ast_strlen_zero(pds.peer)) { 12843 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 12844 return -1; 12845 } 12846 12847 /* Populate our address from the given */ 12848 if (create_addr(pds.peer, NULL, &sin, &cai)) 12849 return -1; 12850 12851 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 12852 pds.peer, pds.username, pds.password, pds.context); 12853 12854 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12855 if (callno < 1) { 12856 ast_log(LOG_WARNING, "Unable to create call\n"); 12857 return -1; 12858 } 12859 12860 ast_string_field_set(iaxs[callno], dproot, data); 12861 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 12862 12863 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 12864 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 12865 /* the string format is slightly different from a standard dial string, 12866 because the context appears in the 'exten' position 12867 */ 12868 if (pds.exten) 12869 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 12870 if (pds.username) 12871 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 12872 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 12873 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 12874 /* Keep password handy */ 12875 if (pds.password) 12876 ast_string_field_set(iaxs[callno], secret, pds.password); 12877 if (pds.key) 12878 ast_string_field_set(iaxs[callno], outkey, pds.key); 12879 /* Start the call going */ 12880 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12881 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 12882 12883 return callno; 12884 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5602 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.
05603 { 05604 /* Returns where in "receive time" we are. That is, how many ms 05605 since we received (or would have received) the frame with timestamp 0 */ 05606 int ms; 05607 #ifdef IAXTESTS 05608 int jit; 05609 #endif /* IAXTESTS */ 05610 /* Setup rxcore if necessary */ 05611 if (ast_tvzero(p->rxcore)) { 05612 p->rxcore = ast_tvnow(); 05613 if (iaxdebug) 05614 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05615 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05616 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05617 #if 1 05618 if (iaxdebug) 05619 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05620 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05621 #endif 05622 } 05623 05624 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05625 #ifdef IAXTESTS 05626 if (test_jit) { 05627 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05628 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05629 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05630 jit = -jit; 05631 ms += jit; 05632 } 05633 } 05634 if (test_late) { 05635 ms += test_late; 05636 test_late = 0; 05637 } 05638 #endif /* IAXTESTS */ 05639 return ms; 05640 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5469 of file chan_iax2.c.
References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, and chan_iax2_pvt::offset.
Referenced by iax2_send(), and socket_process().
05470 { 05471 int ms; 05472 int voice = 0; 05473 int genuine = 0; 05474 int adjust; 05475 int rate = ast_format_rate(f->subclass) / 1000; 05476 struct timeval *delivery = NULL; 05477 05478 05479 /* What sort of frame do we have?: voice is self-explanatory 05480 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05481 non-genuine frames are CONTROL frames [ringing etc], DTMF 05482 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05483 the others need a timestamp slaved to the voice frames so that they go in sequence 05484 */ 05485 if (f) { 05486 if (f->frametype == AST_FRAME_VOICE) { 05487 voice = 1; 05488 delivery = &f->delivery; 05489 } else if (f->frametype == AST_FRAME_IAX) { 05490 genuine = 1; 05491 } else if (f->frametype == AST_FRAME_CNG) { 05492 p->notsilenttx = 0; 05493 } 05494 } 05495 if (ast_tvzero(p->offset)) { 05496 p->offset = ast_tvnow(); 05497 /* Round to nearest 20ms for nice looking traces */ 05498 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05499 } 05500 /* If the timestamp is specified, just send it as is */ 05501 if (ts) 05502 return ts; 05503 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05504 if (delivery && !ast_tvzero(*delivery)) { 05505 ms = ast_tvdiff_ms(*delivery, p->offset); 05506 if (ms < 0) { 05507 ms = 0; 05508 } 05509 if (iaxdebug) 05510 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05511 } else { 05512 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05513 if (ms < 0) 05514 ms = 0; 05515 if (voice) { 05516 /* On a voice frame, use predicted values if appropriate */ 05517 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05518 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05519 /* AN EXPLANATION: 05520 When we send voice, we usually send "calculated" timestamps worked out 05521 on the basis of the number of samples sent. When we send other frames, 05522 we usually send timestamps worked out from the real clock. 05523 The problem is that they can tend to drift out of step because the 05524 source channel's clock and our clock may not be exactly at the same rate. 05525 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05526 for this call. Moving it adjusts timestamps for non-voice frames. 05527 We make the adjustment in the style of a moving average. Each time we 05528 adjust p->offset by 10% of the difference between our clock-derived 05529 timestamp and the predicted timestamp. That's why you see "10000" 05530 below even though IAX2 timestamps are in milliseconds. 05531 The use of a moving average avoids offset moving too radically. 05532 Generally, "adjust" roams back and forth around 0, with offset hardly 05533 changing at all. But if a consistent different starts to develop it 05534 will be eliminated over the course of 10 frames (200-300msecs) 05535 */ 05536 adjust = (ms - p->nextpred); 05537 if (adjust < 0) 05538 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05539 else if (adjust > 0) 05540 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05541 05542 if (!p->nextpred) { 05543 p->nextpred = ms; /*f->samples / rate;*/ 05544 if (p->nextpred <= p->lastsent) 05545 p->nextpred = p->lastsent + 3; 05546 } 05547 ms = p->nextpred; 05548 } else { 05549 /* in this case, just use the actual 05550 * time, since we're either way off 05551 * (shouldn't happen), or we're ending a 05552 * silent period -- and seed the next 05553 * predicted time. Also, round ms to the 05554 * next multiple of frame size (so our 05555 * silent periods are multiples of 05556 * frame size too) */ 05557 05558 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05559 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05560 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05561 05562 if (f->samples >= rate) /* check to make sure we dont core dump */ 05563 { 05564 int diff = ms % (f->samples / rate); 05565 if (diff) 05566 ms += f->samples/rate - diff; 05567 } 05568 05569 p->nextpred = ms; 05570 p->notsilenttx = 1; 05571 } 05572 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05573 /* 05574 * IAX2 draft 03 says that timestamps MUST be in order. 05575 * It does not say anything about several frames having the same timestamp 05576 * When transporting video, we can have a frame that spans multiple iax packets 05577 * (so called slices), so it would make sense to use the same timestamp for all of 05578 * them 05579 * We do want to make sure that frames don't go backwards though 05580 */ 05581 if ( (unsigned int)ms < p->lastsent ) 05582 ms = p->lastsent; 05583 } else { 05584 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05585 it's a genuine frame */ 05586 if (genuine) { 05587 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05588 if (ms <= p->lastsent) 05589 ms = p->lastsent + 3; 05590 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05591 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05592 ms = p->lastsent + 3; 05593 } 05594 } 05595 } 05596 p->lastsent = ms; 05597 if (voice) 05598 p->nextpred = p->nextpred + f->samples / rate; 05599 return ms; 05600 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5425 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().
05426 { 05427 unsigned long int mssincetx; /* unsigned to handle overflows */ 05428 long int ms, pred; 05429 05430 tpeer->trunkact = *now; 05431 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05432 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05433 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05434 tpeer->txtrunktime = *now; 05435 tpeer->lastsent = 999999; 05436 } 05437 /* Update last transmit time now */ 05438 tpeer->lasttxtime = *now; 05439 05440 /* Calculate ms offset */ 05441 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05442 /* Predict from last value */ 05443 pred = tpeer->lastsent + sampms; 05444 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05445 ms = pred; 05446 05447 /* We never send the same timestamp twice, so fudge a little if we must */ 05448 if (ms == tpeer->lastsent) 05449 ms = tpeer->lastsent + 1; 05450 tpeer->lastsent = ms; 05451 return ms; 05452 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2388 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02389 { 02390 return abs(ast_random()); 02391 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 1936 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, calltoken_ignores, CALLTOKEN_NO, iax2_peer::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, user, and user_unref().
Referenced by handle_call_token().
01937 { 01938 struct addr_range *addr_range; 01939 struct iax2_peer *peer = NULL; 01940 struct iax2_user *user = NULL; 01941 /* if no username is given, check for guest accounts */ 01942 const char *find = S_OR(name, "guest"); 01943 int res = 1; /* required by default */ 01944 int optional = 0; 01945 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 01946 /* There are only two cases in which calltoken validation is not required. 01947 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 01948 * the peer definition has not set the requirecalltoken option. 01949 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 01950 */ 01951 01952 /* ----- Case 1 ----- */ 01953 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 01954 ao2_ref(addr_range, -1); 01955 optional = 1; 01956 } 01957 01958 /* ----- Case 2 ----- */ 01959 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 01960 calltoken_required = user->calltoken_required; 01961 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 01962 calltoken_required = user->calltoken_required; 01963 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 01964 calltoken_required = peer->calltoken_required; 01965 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 01966 calltoken_required = peer->calltoken_required; 01967 } 01968 01969 if (peer) { 01970 peer_unref(peer); 01971 } 01972 if (user) { 01973 user_unref(user); 01974 } 01975 01976 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); 01977 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 01978 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 01979 res = 0; 01980 } 01981 01982 return res; 01983 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7037 of file chan_iax2.c.
References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, LOG_WARNING, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.
Referenced by socket_process().
07038 { 07039 /* Start pessimistic */ 07040 int res = -1; 07041 int version = 2; 07042 struct iax2_user *user = NULL, *best = NULL; 07043 int bestscore = 0; 07044 int gotcapability = 0; 07045 struct ast_variable *v = NULL, *tmpvar = NULL; 07046 struct ao2_iterator i; 07047 07048 if (!iaxs[callno]) 07049 return res; 07050 if (ies->called_number) 07051 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07052 if (ies->calling_number) { 07053 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 07054 ast_shrink_phone_number(ies->calling_number); 07055 } 07056 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07057 } 07058 if (ies->calling_name) 07059 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07060 if (ies->calling_ani) 07061 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07062 if (ies->dnid) 07063 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07064 if (ies->rdnis) 07065 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07066 if (ies->called_context) 07067 ast_string_field_set(iaxs[callno], context, ies->called_context); 07068 if (ies->language) 07069 ast_string_field_set(iaxs[callno], language, ies->language); 07070 if (ies->username) 07071 ast_string_field_set(iaxs[callno], username, ies->username); 07072 if (ies->calling_ton > -1) 07073 iaxs[callno]->calling_ton = ies->calling_ton; 07074 if (ies->calling_tns > -1) 07075 iaxs[callno]->calling_tns = ies->calling_tns; 07076 if (ies->calling_pres > -1) 07077 iaxs[callno]->calling_pres = ies->calling_pres; 07078 if (ies->format) 07079 iaxs[callno]->peerformat = ies->format; 07080 if (ies->adsicpe) 07081 iaxs[callno]->peeradsicpe = ies->adsicpe; 07082 if (ies->capability) { 07083 gotcapability = 1; 07084 iaxs[callno]->peercapability = ies->capability; 07085 } 07086 if (ies->version) 07087 version = ies->version; 07088 07089 /* Use provided preferences until told otherwise for actual preferences */ 07090 if(ies->codec_prefs) { 07091 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07092 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07093 } 07094 07095 if (!gotcapability) 07096 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07097 if (version > IAX_PROTO_VERSION) { 07098 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07099 ast_inet_ntoa(sin->sin_addr), version); 07100 return res; 07101 } 07102 /* Search the userlist for a compatible entry, and fill in the rest */ 07103 i = ao2_iterator_init(users, 0); 07104 while ((user = ao2_iterator_next(&i))) { 07105 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07106 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07107 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 07108 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07109 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07110 if (!ast_strlen_zero(iaxs[callno]->username)) { 07111 /* Exact match, stop right now. */ 07112 if (best) 07113 user_unref(best); 07114 best = user; 07115 break; 07116 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07117 /* No required authentication */ 07118 if (user->ha) { 07119 /* There was host authentication and we passed, bonus! */ 07120 if (bestscore < 4) { 07121 bestscore = 4; 07122 if (best) 07123 user_unref(best); 07124 best = user; 07125 continue; 07126 } 07127 } else { 07128 /* No host access, but no secret, either, not bad */ 07129 if (bestscore < 3) { 07130 bestscore = 3; 07131 if (best) 07132 user_unref(best); 07133 best = user; 07134 continue; 07135 } 07136 } 07137 } else { 07138 if (user->ha) { 07139 /* Authentication, but host access too, eh, it's something.. */ 07140 if (bestscore < 2) { 07141 bestscore = 2; 07142 if (best) 07143 user_unref(best); 07144 best = user; 07145 continue; 07146 } 07147 } else { 07148 /* Authentication and no host access... This is our baseline */ 07149 if (bestscore < 1) { 07150 bestscore = 1; 07151 if (best) 07152 user_unref(best); 07153 best = user; 07154 continue; 07155 } 07156 } 07157 } 07158 } 07159 user_unref(user); 07160 } 07161 ao2_iterator_destroy(&i); 07162 user = best; 07163 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07164 user = realtime_user(iaxs[callno]->username, sin); 07165 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07166 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07167 user = user_unref(user); 07168 } 07169 } 07170 if (user) { 07171 /* We found our match (use the first) */ 07172 /* copy vars */ 07173 for (v = user->vars ; v ; v = v->next) { 07174 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07175 tmpvar->next = iaxs[callno]->vars; 07176 iaxs[callno]->vars = tmpvar; 07177 } 07178 } 07179 /* If a max AUTHREQ restriction is in place, activate it */ 07180 if (user->maxauthreq > 0) 07181 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 07182 iaxs[callno]->prefs = user->prefs; 07183 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 07184 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 07185 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 07186 iaxs[callno]->encmethods = user->encmethods; 07187 /* Store the requested username if not specified */ 07188 if (ast_strlen_zero(iaxs[callno]->username)) 07189 ast_string_field_set(iaxs[callno], username, user->name); 07190 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07191 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 07192 iaxs[callno]->capability = user->capability; 07193 /* And use the default context */ 07194 if (ast_strlen_zero(iaxs[callno]->context)) { 07195 if (user->contexts) 07196 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07197 else 07198 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07199 } 07200 /* And any input keys */ 07201 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07202 /* And the permitted authentication methods */ 07203 iaxs[callno]->authmethods = user->authmethods; 07204 iaxs[callno]->adsi = user->adsi; 07205 /* If the user has callerid, override the remote caller id. */ 07206 if (ast_test_flag(user, IAX_HASCALLERID)) { 07207 iaxs[callno]->calling_tns = 0; 07208 iaxs[callno]->calling_ton = 0; 07209 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07210 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07211 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07212 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07213 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07214 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07215 } /* else user is allowed to set their own CID settings */ 07216 if (!ast_strlen_zero(user->accountcode)) 07217 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07218 if (!ast_strlen_zero(user->mohinterpret)) 07219 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07220 if (!ast_strlen_zero(user->mohsuggest)) 07221 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07222 if (!ast_strlen_zero(user->parkinglot)) 07223 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07224 if (user->amaflags) 07225 iaxs[callno]->amaflags = user->amaflags; 07226 if (!ast_strlen_zero(user->language)) 07227 ast_string_field_set(iaxs[callno], language, user->language); 07228 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07229 /* Keep this check last */ 07230 if (!ast_strlen_zero(user->dbsecret)) { 07231 char *family, *key=NULL; 07232 char buf[80]; 07233 family = ast_strdupa(user->dbsecret); 07234 key = strchr(family, '/'); 07235 if (key) { 07236 *key = '\0'; 07237 key++; 07238 } 07239 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07240 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07241 else 07242 ast_string_field_set(iaxs[callno], secret, buf); 07243 } else 07244 ast_string_field_set(iaxs[callno], secret, user->secret); 07245 res = 0; 07246 user = user_unref(user); 07247 } else { 07248 /* user was not found, but we should still fake an AUTHREQ. 07249 * Set authmethods to the last known authmethod used by the system 07250 * Set a fake secret, it's not looked at, just required to attempt authentication. 07251 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07252 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07253 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07254 iaxs[callno]->authrej = 1; 07255 if (!ast_strlen_zero(iaxs[callno]->username)) { 07256 /* only send the AUTHREQ if a username was specified. */ 07257 res = 0; 07258 } 07259 } 07260 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07261 return res; 07262 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 8828 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
08829 { 08830 unsigned int ourver; 08831 char rsi[80]; 08832 snprintf(rsi, sizeof(rsi), "si-%s", si); 08833 if (iax_provision_version(&ourver, rsi, 1)) 08834 return 0; 08835 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 08836 if (ourver != ver) 08837 iax2_provision(sin, sockfd, NULL, rsi, 1); 08838 return 0; 08839 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 11619 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
11620 { 11621 int sd; 11622 int res; 11623 11624 sd = socket(AF_INET, SOCK_DGRAM, 0); 11625 if (sd < 0) { 11626 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 11627 return -1; 11628 } 11629 11630 res = bind(sd, sa, salen); 11631 if (res < 0) { 11632 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 11633 close(sd); 11634 return 1; 11635 } 11636 11637 close(sd); 11638 return 0; 11639 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7813 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().
07814 { 07815 char exten[256] = ""; 07816 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 07817 struct iax2_dpcache *dp = NULL; 07818 07819 if (ies->called_number) 07820 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07821 07822 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07823 status = CACHE_FLAG_EXISTS; 07824 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07825 status = CACHE_FLAG_CANEXIST; 07826 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07827 status = CACHE_FLAG_NONEXISTENT; 07828 07829 if (ies->refresh) 07830 expiry = ies->refresh; 07831 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07832 matchmore = CACHE_FLAG_MATCHMORE; 07833 07834 AST_LIST_LOCK(&dpcache); 07835 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 07836 if (strcmp(dp->exten, exten)) 07837 continue; 07838 AST_LIST_REMOVE_CURRENT(peer_list); 07839 dp->callno = 0; 07840 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 07841 if (dp->flags & CACHE_FLAG_PENDING) { 07842 dp->flags &= ~CACHE_FLAG_PENDING; 07843 dp->flags |= status; 07844 dp->flags |= matchmore; 07845 } 07846 /* Wake up waiters */ 07847 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 07848 if (dp->waiters[x] > -1) { 07849 if (write(dp->waiters[x], "asdf", 4) < 0) { 07850 } 07851 } 07852 } 07853 } 07854 AST_LIST_TRAVERSE_SAFE_END; 07855 AST_LIST_UNLOCK(&dpcache); 07856 07857 return 0; 07858 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3545 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03546 { 03547 int which = 0; 03548 struct iax2_peer *peer; 03549 char *res = NULL; 03550 int wordlen = strlen(word); 03551 struct ao2_iterator i; 03552 03553 i = ao2_iterator_init(peers, 0); 03554 while ((peer = ao2_iterator_next(&i))) { 03555 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 03556 res = ast_strdup(peer->name); 03557 peer_unref(peer); 03558 break; 03559 } 03560 peer_unref(peer); 03561 } 03562 ao2_iterator_destroy(&i); 03563 03564 return res; 03565 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6458 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_unregister().
06459 { 06460 int which = 0; 06461 struct iax2_peer *p = NULL; 06462 char *res = NULL; 06463 int wordlen = strlen(word); 06464 06465 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06466 if (pos == 2) { 06467 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06468 while ((p = ao2_iterator_next(&i))) { 06469 if (!strncasecmp(p->name, word, wordlen) && 06470 ++which > state && p->expire > 0) { 06471 res = ast_strdup(p->name); 06472 peer_unref(p); 06473 break; 06474 } 06475 peer_unref(p); 06476 } 06477 ao2_iterator_destroy(&i); 06478 } 06479 06480 return res; 06481 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7860 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(), iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, iax_frame::list, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
07861 { 07862 int peercallno = 0; 07863 struct chan_iax2_pvt *pvt = iaxs[callno]; 07864 struct iax_frame *cur; 07865 jb_frame frame; 07866 07867 if (ies->callno) 07868 peercallno = ies->callno; 07869 07870 if (peercallno < 1) { 07871 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07872 return -1; 07873 } 07874 remove_by_transfercallno(pvt); 07875 /* since a transfer has taken place, the address will change. 07876 * This must be accounted for in the peercnts table. Remove 07877 * the old address and add the new one */ 07878 peercnt_remove_by_addr(&pvt->addr); 07879 peercnt_add(&pvt->transfer); 07880 /* now copy over the new address */ 07881 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 07882 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 07883 /* Reset sequence numbers */ 07884 pvt->oseqno = 0; 07885 pvt->rseqno = 0; 07886 pvt->iseqno = 0; 07887 pvt->aseqno = 0; 07888 07889 if (pvt->peercallno) { 07890 remove_by_peercallno(pvt); 07891 } 07892 pvt->peercallno = peercallno; 07893 /*this is where the transfering call swiches hash tables */ 07894 store_by_peercallno(pvt); 07895 pvt->transferring = TRANSFER_NONE; 07896 pvt->svoiceformat = -1; 07897 pvt->voiceformat = 0; 07898 pvt->svideoformat = -1; 07899 pvt->videoformat = 0; 07900 pvt->transfercallno = 0; 07901 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 07902 memset(&pvt->offset, 0, sizeof(pvt->offset)); 07903 /* reset jitterbuffer */ 07904 while(jb_getall(pvt->jb,&frame) == JB_OK) 07905 iax2_frame_free(frame.data); 07906 jb_reset(pvt->jb); 07907 pvt->lag = 0; 07908 pvt->last = 0; 07909 pvt->lastsent = 0; 07910 pvt->nextpred = 0; 07911 pvt->pingtime = DEFAULT_RETRY_TIME; 07912 AST_LIST_LOCK(&frame_queue); 07913 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 07914 /* We must cancel any packets that would have been transmitted 07915 because now we're talking to someone new. It's okay, they 07916 were transmitted to someone that didn't care anyway. */ 07917 if (callno == cur->callno) 07918 cur->retries = -1; 07919 } 07920 AST_LIST_UNLOCK(&frame_queue); 07921 return 0; 07922 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1369 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().
01370 { 01371 int x; 01372 int power=-1; 01373 /* If it's 128 or smaller, just return it */ 01374 if (subclass < IAX_FLAG_SC_LOG) 01375 return subclass; 01376 /* Otherwise find its power */ 01377 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01378 if (subclass & (1 << x)) { 01379 if (power > -1) { 01380 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01381 return 0; 01382 } else 01383 power = x; 01384 } 01385 } 01386 return power | IAX_FLAG_SC_LOG; 01387 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 8841 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().
08842 { 08843 jb_info stats; 08844 jb_getinfo(pvt->jb, &stats); 08845 08846 memset(iep, 0, sizeof(*iep)); 08847 08848 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 08849 if(stats.frames_in == 0) stats.frames_in = 1; 08850 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 08851 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 08852 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 08853 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 08854 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 08855 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4234 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
04235 { 04236 struct iax2_peer *peer; 04237 int res = -1; 04238 struct ast_codec_pref ourprefs; 04239 04240 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 04241 cai->sockfd = defaultsockfd; 04242 cai->maxtime = 0; 04243 sin->sin_family = AF_INET; 04244 04245 if (!(peer = find_peer(peername, 1))) { 04246 cai->found = 0; 04247 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) { 04248 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04249 return -1; 04250 } 04251 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04252 /* use global iax prefs for unknown peer/user */ 04253 /* But move the calling channel's native codec to the top of the preference list */ 04254 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04255 if (c) 04256 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04257 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04258 return 0; 04259 } 04260 04261 cai->found = 1; 04262 04263 /* if the peer has no address (current or default), return failure */ 04264 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 04265 goto return_unref; 04266 04267 /* if the peer is being monitored and is currently unreachable, return failure */ 04268 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04269 goto return_unref; 04270 04271 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04272 cai->maxtime = peer->maxms; 04273 cai->capability = peer->capability; 04274 cai->encmethods = peer->encmethods; 04275 cai->sockfd = peer->sockfd; 04276 cai->adsi = peer->adsi; 04277 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04278 /* Move the calling channel's native codec to the top of the preference list */ 04279 if (c) { 04280 ast_debug(1, "prepending %x to prefs\n", c->nativeformats); 04281 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04282 } 04283 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04284 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04285 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04286 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04287 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04288 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04289 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04290 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04291 if (ast_strlen_zero(peer->dbsecret)) { 04292 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04293 } else { 04294 char *family; 04295 char *key = NULL; 04296 04297 family = ast_strdupa(peer->dbsecret); 04298 key = strchr(family, '/'); 04299 if (key) 04300 *key++ = '\0'; 04301 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04302 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04303 goto return_unref; 04304 } 04305 } 04306 04307 if (peer->addr.sin_addr.s_addr) { 04308 sin->sin_addr = peer->addr.sin_addr; 04309 sin->sin_port = peer->addr.sin_port; 04310 } else { 04311 sin->sin_addr = peer->defaddr.sin_addr; 04312 sin->sin_port = peer->defaddr.sin_port; 04313 } 04314 04315 res = 0; 04316 04317 return_unref: 04318 peer_unref(peer); 04319 04320 return res; 04321 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2393 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_hash(), IAX_MAX_CALLS, and TRUNK_CALL_START.
Referenced by load_objects().
02394 { 02395 uint16_t i; 02396 02397 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02398 return -1; 02399 } 02400 02401 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02402 return -1; 02403 } 02404 02405 /* start at 2, 0 and 1 are reserved */ 02406 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02407 struct callno_entry *callno_entry; 02408 02409 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02410 return -1; 02411 } 02412 02413 callno_entry->callno = i; 02414 02415 if (i < TRUNK_CALL_START) { 02416 ao2_link(callno_pool, callno_entry); 02417 } else { 02418 ao2_link(callno_pool_trunk, callno_entry); 02419 } 02420 02421 ao2_ref(callno_entry, -1); 02422 } 02423 02424 return 0; 02425 }
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 5824 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, f, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
05825 { 05826 int padding; 05827 unsigned char *workspace; 05828 05829 workspace = alloca(*datalen); 05830 memset(f, 0, sizeof(*f)); 05831 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05832 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05833 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05834 return -1; 05835 /* Decrypt */ 05836 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05837 05838 padding = 16 + (workspace[15] & 0x0f); 05839 if (iaxdebug) 05840 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05841 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05842 return -1; 05843 05844 *datalen -= padding; 05845 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05846 f->frametype = fh->type; 05847 if (f->frametype == AST_FRAME_VIDEO) { 05848 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05849 } else { 05850 f->subclass = uncompress_subclass(fh->csub); 05851 } 05852 } else { 05853 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05854 if (iaxdebug) 05855 ast_debug(1, "Decoding mini with length %d\n", *datalen); 05856 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05857 return -1; 05858 /* Decrypt */ 05859 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05860 padding = 16 + (workspace[15] & 0x0f); 05861 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05862 return -1; 05863 *datalen -= padding; 05864 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05865 } 05866 return 0; 05867 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5910 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
05911 { 05912 int res=-1; 05913 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 05914 /* Search for possible keys, given secrets */ 05915 struct MD5Context md5; 05916 unsigned char digest[16]; 05917 char *tmppw, *stringp; 05918 05919 tmppw = ast_strdupa(iaxs[callno]->secret); 05920 stringp = tmppw; 05921 while ((tmppw = strsep(&stringp, ";"))) { 05922 MD5Init(&md5); 05923 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05924 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05925 MD5Final(digest, &md5); 05926 build_encryption_keys(digest, iaxs[callno]); 05927 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05928 if (!res) { 05929 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 05930 break; 05931 } 05932 } 05933 } else 05934 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05935 return res; 05936 }
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 8988 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
08989 { 08990 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 08991 struct ast_iax2_full_hdr *fh, *cur_fh; 08992 08993 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 08994 return; 08995 08996 pkt_buf->len = from_here->buf_len; 08997 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 08998 08999 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09000 ast_mutex_lock(&to_here->lock); 09001 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09002 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09003 if (fh->oseqno < cur_fh->oseqno) { 09004 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09005 break; 09006 } 09007 } 09008 AST_LIST_TRAVERSE_SAFE_END 09009 09010 if (!cur_pkt_buf) 09011 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09012 09013 ast_mutex_unlock(&to_here->lock); 09014 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12249 of file chan_iax2.c.
References ao2_callback, ast_dnsmgr_release(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::entry, iax2_registry::expire, iax2_destroy(), iaxs, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
12250 { 12251 struct iax2_registry *reg; 12252 12253 ao2_callback(users, 0, user_delme_cb, NULL); 12254 12255 AST_LIST_LOCK(®istrations); 12256 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12257 AST_SCHED_DEL(sched, reg->expire); 12258 if (reg->callno) { 12259 int callno = reg->callno; 12260 ast_mutex_lock(&iaxsl[callno]); 12261 if (iaxs[callno]) { 12262 iaxs[callno]->reg = NULL; 12263 iax2_destroy(callno); 12264 } 12265 ast_mutex_unlock(&iaxsl[callno]); 12266 } 12267 if (reg->dnsmgr) 12268 ast_dnsmgr_release(reg->dnsmgr); 12269 ast_free(reg); 12270 } 12271 AST_LIST_UNLOCK(®istrations); 12272 12273 ao2_callback(peers, 0, peer_delme_cb, NULL); 12274 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2749 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
02750 { 02751 /* Close firmware */ 02752 if (cur->fwh) { 02753 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02754 } 02755 close(cur->fd); 02756 ast_free(cur); 02757 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 8689 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_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
08690 { 08691 unsigned short dpstatus = 0; 08692 struct iax_ie_data ied1; 08693 int mm; 08694 08695 memset(&ied1, 0, sizeof(ied1)); 08696 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 08697 /* Must be started */ 08698 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 08699 dpstatus = IAX_DPSTATUS_EXISTS; 08700 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 08701 dpstatus = IAX_DPSTATUS_CANEXIST; 08702 } else { 08703 dpstatus = IAX_DPSTATUS_NONEXISTENT; 08704 } 08705 if (ast_ignore_pattern(context, callednum)) 08706 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 08707 if (mm) 08708 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08709 if (!skiplock) 08710 ast_mutex_lock(&iaxsl[callno]); 08711 if (iaxs[callno]) { 08712 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08713 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08714 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08715 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08716 } 08717 if (!skiplock) 08718 ast_mutex_unlock(&iaxsl[callno]); 08719 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8721 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().
08722 { 08723 /* Look up for dpreq */ 08724 struct dpreq_data *dpr = data; 08725 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 08726 if (dpr->callerid) 08727 ast_free(dpr->callerid); 08728 ast_free(dpr); 08729 return NULL; 08730 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 5869 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().
05870 { 05871 int padding; 05872 unsigned char *workspace; 05873 workspace = alloca(*datalen + 32); 05874 if (!workspace) 05875 return -1; 05876 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05877 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05878 if (iaxdebug) 05879 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05880 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05881 padding = 16 + (padding & 0xf); 05882 memcpy(workspace, poo, padding); 05883 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05884 workspace[15] &= 0xf0; 05885 workspace[15] |= (padding & 0xf); 05886 if (iaxdebug) 05887 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 05888 *datalen += padding; 05889 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05890 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05891 memcpy(poo, workspace + *datalen - 32, 32); 05892 } else { 05893 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05894 if (iaxdebug) 05895 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 05896 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 05897 padding = 16 + (padding & 0xf); 05898 memcpy(workspace, poo, padding); 05899 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05900 workspace[15] &= 0xf0; 05901 workspace[15] |= (padding & 0x0f); 05902 *datalen += padding; 05903 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 05904 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 05905 memcpy(poo, workspace + *datalen - 32, 32); 05906 } 05907 return 0; 05908 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8120 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), reg_source_db(), and update_registry().
08121 { 08122 #ifdef SCHED_MULTITHREADED 08123 if (schedule_action(__expire_registry, data)) 08124 #endif 08125 __expire_registry(data); 08126 return 0; 08127 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 12886 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, chan, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
12887 { 12888 struct iax2_dpcache *dp = NULL; 12889 struct timeval now = ast_tvnow(); 12890 int x, com[2], timeout, old = 0, outfd, doabort, callno; 12891 struct ast_channel *c = NULL; 12892 struct ast_frame *f = NULL; 12893 12894 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 12895 if (ast_tvcmp(now, dp->expiry) > 0) { 12896 AST_LIST_REMOVE_CURRENT(cache_list); 12897 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 12898 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 12899 else 12900 ast_free(dp); 12901 continue; 12902 } 12903 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 12904 break; 12905 } 12906 AST_LIST_TRAVERSE_SAFE_END; 12907 12908 if (!dp) { 12909 /* No matching entry. Create a new one. */ 12910 /* First, can we make a callno? */ 12911 if ((callno = cache_get_callno_locked(data)) < 0) { 12912 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 12913 return NULL; 12914 } 12915 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 12916 ast_mutex_unlock(&iaxsl[callno]); 12917 return NULL; 12918 } 12919 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 12920 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 12921 dp->expiry = ast_tvnow(); 12922 dp->orig = dp->expiry; 12923 /* Expires in 30 mins by default */ 12924 dp->expiry.tv_sec += iaxdefaultdpcache; 12925 dp->flags = CACHE_FLAG_PENDING; 12926 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 12927 dp->waiters[x] = -1; 12928 /* Insert into the lists */ 12929 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 12930 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 12931 /* Send the request if we're already up */ 12932 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 12933 iax2_dprequest(dp, callno); 12934 ast_mutex_unlock(&iaxsl[callno]); 12935 } 12936 12937 /* By here we must have a dp */ 12938 if (dp->flags & CACHE_FLAG_PENDING) { 12939 /* Okay, here it starts to get nasty. We need a pipe now to wait 12940 for a reply to come back so long as it's pending */ 12941 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 12942 /* Find an empty slot */ 12943 if (dp->waiters[x] < 0) 12944 break; 12945 } 12946 if (x >= ARRAY_LEN(dp->waiters)) { 12947 ast_log(LOG_WARNING, "No more waiter positions available\n"); 12948 return NULL; 12949 } 12950 if (pipe(com)) { 12951 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 12952 return NULL; 12953 } 12954 dp->waiters[x] = com[1]; 12955 /* Okay, now we wait */ 12956 timeout = iaxdefaulttimeout * 1000; 12957 /* Temporarily unlock */ 12958 AST_LIST_UNLOCK(&dpcache); 12959 /* Defer any dtmf */ 12960 if (chan) 12961 old = ast_channel_defer_dtmf(chan); 12962 doabort = 0; 12963 while(timeout) { 12964 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 12965 if (outfd > -1) 12966 break; 12967 if (!c) 12968 continue; 12969 if (!(f = ast_read(c))) { 12970 doabort = 1; 12971 break; 12972 } 12973 ast_frfree(f); 12974 } 12975 if (!timeout) { 12976 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 12977 } 12978 AST_LIST_LOCK(&dpcache); 12979 dp->waiters[x] = -1; 12980 close(com[1]); 12981 close(com[0]); 12982 if (doabort) { 12983 /* Don't interpret anything, just abort. Not sure what th epoint 12984 of undeferring dtmf on a hung up channel is but hey whatever */ 12985 if (!old && chan) 12986 ast_channel_undefer_dtmf(chan); 12987 return NULL; 12988 } 12989 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 12990 /* Now to do non-independent analysis the results of our wait */ 12991 if (dp->flags & CACHE_FLAG_PENDING) { 12992 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 12993 pending. Don't let it take as long to timeout. */ 12994 dp->flags &= ~CACHE_FLAG_PENDING; 12995 dp->flags |= CACHE_FLAG_TIMEOUT; 12996 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 12997 systems without leaving it unavailable once the server comes back online */ 12998 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 12999 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13000 if (dp->waiters[x] > -1) { 13001 if (write(dp->waiters[x], "asdf", 4) < 0) { 13002 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13003 } 13004 } 13005 } 13006 } 13007 } 13008 /* Our caller will obtain the rest */ 13009 if (!old && chan) 13010 ast_channel_undefer_dtmf(chan); 13011 } 13012 return dp; 13013 }
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 2649 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02649 { 02650 02651 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02652 }
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 2654 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().
02654 { 02655 02656 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02657 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1181 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_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_trunk_peer::list, and thread.
Referenced by __schedule_action(), and socket_read().
01182 { 01183 struct iax2_thread *thread = NULL; 01184 01185 /* Pop the head of the idle list off */ 01186 AST_LIST_LOCK(&idle_list); 01187 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01188 AST_LIST_UNLOCK(&idle_list); 01189 01190 /* If we popped a thread off the idle list, just return it */ 01191 if (thread) { 01192 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01193 return thread; 01194 } 01195 01196 /* Pop the head of the dynamic list off */ 01197 AST_LIST_LOCK(&dynamic_list); 01198 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01199 AST_LIST_UNLOCK(&dynamic_list); 01200 01201 /* If we popped a thread off the dynamic list, just return it */ 01202 if (thread) { 01203 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01204 return thread; 01205 } 01206 01207 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01208 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01209 return NULL; 01210 01211 /* Set default values */ 01212 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01213 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01214 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01215 01216 /* Initialize lock and condition */ 01217 ast_mutex_init(&thread->lock); 01218 ast_cond_init(&thread->cond, NULL); 01219 ast_mutex_init(&thread->init_lock); 01220 ast_cond_init(&thread->init_cond, NULL); 01221 ast_mutex_lock(&thread->init_lock); 01222 01223 /* Create thread and send it on it's way */ 01224 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01225 ast_cond_destroy(&thread->cond); 01226 ast_mutex_destroy(&thread->lock); 01227 ast_free(thread); 01228 return NULL; 01229 } 01230 01231 /* this thread is not processing a full frame (since it is idle), 01232 so ensure that the field for the full frame call number is empty */ 01233 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01234 01235 /* Wait for the thread to be ready before returning it to the caller */ 01236 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01237 01238 /* Done with init_lock */ 01239 ast_mutex_unlock(&thread->init_lock); 01240 01241 return thread; 01242 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1447 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().
01448 { 01449 struct iax2_peer *peer = NULL; 01450 struct iax2_peer tmp_peer = { 01451 .name = name, 01452 }; 01453 01454 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01455 01456 /* Now go for realtime if applicable */ 01457 if(!peer && realtime) 01458 peer = realtime_peer(name, NULL); 01459 01460 return peer; 01461 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 5642 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init(), ast_mutex_lock(), ast_tvnow(), inaddrcmp(), iax2_trunk_peer::list, and iax2_trunk_peer::lock.
Referenced by iax2_trunk_queue(), and socket_process_meta().
05643 { 05644 struct iax2_trunk_peer *tpeer = NULL; 05645 05646 /* Finds and locks trunk peer */ 05647 AST_LIST_LOCK(&tpeers); 05648 05649 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 05650 if (!inaddrcmp(&tpeer->addr, sin)) { 05651 ast_mutex_lock(&tpeer->lock); 05652 break; 05653 } 05654 } 05655 05656 if (!tpeer) { 05657 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05658 ast_mutex_init(&tpeer->lock); 05659 tpeer->lastsent = 9999; 05660 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05661 tpeer->trunkact = ast_tvnow(); 05662 ast_mutex_lock(&tpeer->lock); 05663 tpeer->sockfd = fd; 05664 #ifdef SO_NO_CHECK 05665 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05666 #endif 05667 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05668 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 05669 } 05670 } 05671 05672 AST_LIST_UNLOCK(&tpeers); 05673 05674 return tpeer; 05675 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1475 of file chan_iax2.c.
References ao2_find, iax2_user::name, OBJ_POINTER, and users.
01476 { 01477 struct iax2_user tmp_user = { 01478 .name = name, 01479 }; 01480 01481 return ao2_find(users, &tmp_user, OBJ_POINTER); 01482 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5454 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05455 { 05456 long ms; /* NOT unsigned */ 05457 if (ast_tvzero(iaxs[callno]->rxcore)) { 05458 /* Initialize rxcore time if appropriate */ 05459 iaxs[callno]->rxcore = ast_tvnow(); 05460 /* Round to nearest 20ms so traces look pretty */ 05461 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05462 } 05463 /* Calculate difference between trunk and channel */ 05464 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05465 /* Return as the sum of trunk time and the difference between trunk and real time */ 05466 return ms + ts; 05467 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 11383 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
11384 { 11385 struct iax2_context *conl; 11386 while(con) { 11387 conl = con; 11388 con = con->next; 11389 ast_free(conl); 11390 } 11391 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1575 of file chan_iax2.c.
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 13136 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::capability, chan, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13137 { 13138 struct iax2_peer *peer; 13139 char *peername, *colname; 13140 13141 peername = ast_strdupa(data); 13142 13143 /* if our channel, return the IP address of the endpoint of current channel */ 13144 if (!strcmp(peername,"CURRENTCHANNEL")) { 13145 unsigned short callno; 13146 if (chan->tech != &iax2_tech) 13147 return -1; 13148 callno = PTR_TO_CALLNO(chan->tech_pvt); 13149 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13150 return 0; 13151 } 13152 13153 if ((colname = strchr(peername, ','))) 13154 *colname++ = '\0'; 13155 else 13156 colname = "ip"; 13157 13158 if (!(peer = find_peer(peername, 1))) 13159 return -1; 13160 13161 if (!strcasecmp(colname, "ip")) { 13162 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 13163 } else if (!strcasecmp(colname, "status")) { 13164 peer_status(peer, buf, len); 13165 } else if (!strcasecmp(colname, "mailbox")) { 13166 ast_copy_string(buf, peer->mailbox, len); 13167 } else if (!strcasecmp(colname, "context")) { 13168 ast_copy_string(buf, peer->context, len); 13169 } else if (!strcasecmp(colname, "expire")) { 13170 snprintf(buf, len, "%d", peer->expire); 13171 } else if (!strcasecmp(colname, "dynamic")) { 13172 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13173 } else if (!strcasecmp(colname, "callerid_name")) { 13174 ast_copy_string(buf, peer->cid_name, len); 13175 } else if (!strcasecmp(colname, "callerid_num")) { 13176 ast_copy_string(buf, peer->cid_num, len); 13177 } else if (!strcasecmp(colname, "codecs")) { 13178 ast_getformatname_multiple(buf, len -1, peer->capability); 13179 } else if (!strncasecmp(colname, "codec[", 6)) { 13180 char *codecnum, *ptr; 13181 int codec = 0; 13182 13183 codecnum = strchr(colname, '['); 13184 *codecnum = '\0'; 13185 codecnum++; 13186 if ((ptr = strchr(codecnum, ']'))) { 13187 *ptr = '\0'; 13188 } 13189 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13190 ast_copy_string(buf, ast_getformatname(codec), len); 13191 } else { 13192 buf[0] = '\0'; 13193 } 13194 } else { 13195 buf[0] = '\0'; 13196 } 13197 13198 peer_unref(peer); 13199 13200 return 0; 13201 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 11603 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
11604 { 11605 int methods = 0; 11606 if (strstr(value, "rsa")) 11607 methods |= IAX_AUTH_RSA; 11608 if (strstr(value, "md5")) 11609 methods |= IAX_AUTH_MD5; 11610 if (strstr(value, "plaintext")) 11611 methods |= IAX_AUTH_PLAINTEXT; 11612 return methods; 11613 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1324 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01325 { 01326 int e; 01327 if (!strcasecmp(s, "aes128")) 01328 e = IAX_ENCRYPT_AES128; 01329 else if (ast_true(s)) 01330 e = IAX_ENCRYPT_AES128; 01331 else 01332 e = 0; 01333 return e; 01334 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3852 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03853 { 03854 #ifdef SCHED_MULTITHREADED 03855 if (schedule_action(__get_from_jb, data)) 03856 #endif 03857 __get_from_jb(data); 03858 return 0; 03859 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2326 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().
02327 { 02328 struct callno_entry *callno_entry = NULL; 02329 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02330 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02331 /* Minor optimization for the extreme case. */ 02332 return NULL; 02333 } 02334 02335 /* the callno_pool container is locked here primarily to ensure thread 02336 * safety of the total_nonval_callno_used check and increment */ 02337 ao2_lock(callno_pool); 02338 02339 /* only a certain number of nonvalidated call numbers should be allocated. 02340 * If there ever is an attack, this separates the calltoken validating 02341 * users from the non calltoken validating users. */ 02342 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02343 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02344 ao2_unlock(callno_pool); 02345 return NULL; 02346 } 02347 02348 /* unlink the object from the container, taking over ownership 02349 * of the reference the container had to the object */ 02350 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02351 02352 if (callno_entry) { 02353 callno_entry->validated = validated; 02354 if (!validated) { 02355 total_nonval_callno_used++; 02356 } 02357 } 02358 02359 ao2_unlock(callno_pool); 02360 return callno_entry; 02361 }
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 4531 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer, ast_str_set(), buf, 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().
04533 { 04534 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04535 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04536 struct ast_str *buf = ast_str_alloca(256); 04537 time_t t = time(NULL); 04538 char hash[41]; /* 40 char sha1 hash */ 04539 int subclass = uncompress_subclass(fh->csub); 04540 04541 /* ----- Case 1 ----- */ 04542 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04543 struct iax_ie_data ied = { 04544 .buf = { 0 }, 04545 .pos = 0, 04546 }; 04547 04548 /* create the hash with their address data and our timestamp */ 04549 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04550 ast_sha1_hash(hash, ast_str_buffer(buf)); 04551 04552 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04553 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04554 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04555 04556 return 1; 04557 04558 /* ----- Case 2 ----- */ 04559 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04560 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04561 char *rec_ts = NULL; /* received timestamp */ 04562 unsigned int rec_time; /* received time_t */ 04563 04564 /* split the timestamp from the hash data */ 04565 rec_hash = strchr((char *) ies->calltokendata, '?'); 04566 if (rec_hash) { 04567 *rec_hash++ = '\0'; 04568 rec_ts = (char *) ies->calltokendata; 04569 } 04570 04571 /* check that we have valid data before we do any comparisons */ 04572 if (!rec_hash || !rec_ts) { 04573 goto reject; 04574 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04575 goto reject; 04576 } 04577 04578 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04579 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04580 ast_sha1_hash(hash, ast_str_buffer(buf)); 04581 04582 /* compare hashes and then check timestamp delay */ 04583 if (strcmp(hash, rec_hash)) { 04584 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04585 goto reject; /* received hash does not match ours, reject */ 04586 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04587 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04588 goto reject; /* too much delay, reject */ 04589 } 04590 04591 /* at this point the call token is valid, returning 0 04592 * will allow socket_process to continue as usual */ 04593 requirecalltoken_mark_auto(ies->username, subclass); 04594 return 0; 04595 04596 /* ----- Case 3 ----- */ 04597 } else { /* calltokens are not supported for this client, how do we respond? */ 04598 if (calltoken_required(sin, ies->username, subclass)) { 04599 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")); 04600 goto reject; 04601 } 04602 return 0; /* calltoken is not required for this addr, so permit it. */ 04603 } 04604 04605 reject: 04606 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04607 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04608 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04609 } else { 04610 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04611 } 04612 04613 return 1; 04614 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11234 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.
11235 { 11236 int force = 0; 11237 int res; 11238 11239 switch (cmd) { 11240 case CLI_INIT: 11241 e->command = "iax2 provision"; 11242 e->usage = 11243 "Usage: iax2 provision <host> <template> [forced]\n" 11244 " Provisions the given peer or IP address using a template\n" 11245 " matching either 'template' or '*' if the template is not\n" 11246 " found. If 'forced' is specified, even empty provisioning\n" 11247 " fields will be provisioned as empty fields.\n"; 11248 return NULL; 11249 case CLI_GENERATE: 11250 if (a->pos == 3) 11251 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11252 return NULL; 11253 } 11254 11255 if (a->argc < 4) 11256 return CLI_SHOWUSAGE; 11257 if (a->argc > 4) { 11258 if (!strcasecmp(a->argv[4], "forced")) 11259 force = 1; 11260 else 11261 return CLI_SHOWUSAGE; 11262 } 11263 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11264 if (res < 0) 11265 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11266 else if (res < 1) 11267 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11268 else 11269 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11270 return CLI_SUCCESS; 11271 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3300 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_set_flag, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user, user_unref(), users, and ast_cli_args::word.
03301 { 03302 struct iax2_peer *peer = NULL; 03303 struct iax2_user *user = NULL; 03304 03305 switch (cmd) { 03306 case CLI_INIT: 03307 e->command = "iax2 prune realtime"; 03308 e->usage = 03309 "Usage: iax2 prune realtime [<peername>|all]\n" 03310 " Prunes object(s) from the cache\n"; 03311 return NULL; 03312 case CLI_GENERATE: 03313 if (a->pos == 3) 03314 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 03315 return NULL; 03316 } 03317 if (a->argc != 4) 03318 return CLI_SHOWUSAGE; 03319 if (!strcmp(a->argv[3], "all")) { 03320 prune_users(); 03321 prune_peers(); 03322 ast_cli(a->fd, "Cache flushed successfully.\n"); 03323 return CLI_SUCCESS; 03324 } 03325 peer = find_peer(a->argv[3], 0); 03326 user = find_user(a->argv[3]); 03327 if (peer || user) { 03328 if (peer) { 03329 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03330 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03331 expire_registry(peer_ref(peer)); 03332 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03333 } else { 03334 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03335 } 03336 peer_unref(peer); 03337 } 03338 if (user) { 03339 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03340 ast_set_flag(user, IAX_RTAUTOCLEAR); 03341 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03342 } else { 03343 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03344 } 03345 ao2_unlink(users,user); 03346 user_unref(user); 03347 } 03348 } else { 03349 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03350 } 03351 03352 return CLI_SUCCESS; 03353 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 12790 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
12791 { 12792 switch (cmd) { 12793 case CLI_INIT: 12794 e->command = "iax2 reload"; 12795 e->usage = 12796 "Usage: iax2 reload\n" 12797 " Reloads IAX configuration from iax.conf\n"; 12798 return NULL; 12799 case CLI_GENERATE: 12800 return NULL; 12801 } 12802 12803 reload_config(); 12804 12805 return CLI_SUCCESS; 12806 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6838 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.
06839 { 06840 switch (cmd) { 06841 case CLI_INIT: 06842 e->command = "iax2 set debug {on|off|peer}"; 06843 e->usage = 06844 "Usage: iax2 set debug {on|off|peer peername}\n" 06845 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 06846 return NULL; 06847 case CLI_GENERATE: 06848 if (a->pos == 4) 06849 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 06850 return NULL; 06851 } 06852 06853 if (a->argc < e->args || a->argc > e->args + 1) 06854 return CLI_SHOWUSAGE; 06855 06856 if (!strcasecmp(a->argv[3], "peer")) { 06857 struct iax2_peer *peer; 06858 06859 if (a->argc != e->args + 1) 06860 return CLI_SHOWUSAGE; 06861 06862 peer = find_peer(a->argv[4], 1); 06863 06864 if (!peer) { 06865 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 06866 return CLI_FAILURE; 06867 } 06868 06869 debugaddr.sin_addr = peer->addr.sin_addr; 06870 debugaddr.sin_port = peer->addr.sin_port; 06871 06872 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 06873 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 06874 06875 ao2_ref(peer, -1); 06876 } else if (!strncasecmp(a->argv[3], "on", 2)) { 06877 iaxdebug = 1; 06878 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 06879 } else { 06880 iaxdebug = 0; 06881 memset(&debugaddr, 0, sizeof(debugaddr)); 06882 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 06883 } 06884 return CLI_SUCCESS; 06885 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6913 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.
06914 { 06915 switch (cmd) { 06916 case CLI_INIT: 06917 e->command = "iax2 set debug jb {on|off}"; 06918 e->usage = 06919 "Usage: iax2 set debug jb {on|off}\n" 06920 " Enables/Disables jitterbuffer debugging information\n"; 06921 return NULL; 06922 case CLI_GENERATE: 06923 return NULL; 06924 } 06925 06926 if (a->argc != e->args) 06927 return CLI_SHOWUSAGE; 06928 06929 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 06930 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 06931 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 06932 } else { 06933 jb_setoutput(jb_error_output, jb_warning_output, NULL); 06934 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 06935 } 06936 return CLI_SUCCESS; 06937 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6887 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.
06888 { 06889 switch (cmd) { 06890 case CLI_INIT: 06891 e->command = "iax2 set debug trunk {on|off}"; 06892 e->usage = 06893 "Usage: iax2 set debug trunk {on|off}\n" 06894 " Enables/Disables debugging of IAX trunking\n"; 06895 return NULL; 06896 case CLI_GENERATE: 06897 return NULL; 06898 } 06899 06900 if (a->argc != e->args) 06901 return CLI_SHOWUSAGE; 06902 06903 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 06904 iaxtrunkdebug = 1; 06905 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 06906 } else { 06907 iaxtrunkdebug = 0; 06908 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 06909 } 06910 return CLI_SUCCESS; 06911 }
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 3611 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.
03612 { 03613 int mtuv; 03614 03615 switch (cmd) { 03616 case CLI_INIT: 03617 e->command = "iax2 set mtu"; 03618 e->usage = 03619 "Usage: iax2 set mtu <value>\n" 03620 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03621 " zero to disable. Disabling means that the operating system\n" 03622 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03623 " packet exceeds the UDP payload size. This is substantially\n" 03624 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03625 " greater for G.711 samples.\n"; 03626 return NULL; 03627 case CLI_GENERATE: 03628 return NULL; 03629 } 03630 03631 if (a->argc != 4) 03632 return CLI_SHOWUSAGE; 03633 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03634 mtuv = MAX_TRUNK_MTU; 03635 else 03636 mtuv = atoi(a->argv[3]); 03637 03638 if (mtuv == 0) { 03639 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03640 global_max_trunk_mtu = 0; 03641 return CLI_SUCCESS; 03642 } 03643 if (mtuv < 172 || mtuv > 4000) { 03644 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03645 return CLI_SHOWUSAGE; 03646 } 03647 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03648 global_max_trunk_mtu = mtuv; 03649 return CLI_SUCCESS; 03650 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3652 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.
03653 { 03654 struct iax2_dpcache *dp = NULL; 03655 char tmp[1024], *pc = NULL; 03656 int s, x, y; 03657 struct timeval now = ast_tvnow(); 03658 03659 switch (cmd) { 03660 case CLI_INIT: 03661 e->command = "iax2 show cache"; 03662 e->usage = 03663 "Usage: iax2 show cache\n" 03664 " Display currently cached IAX Dialplan results.\n"; 03665 return NULL; 03666 case CLI_GENERATE: 03667 return NULL; 03668 } 03669 03670 AST_LIST_LOCK(&dpcache); 03671 03672 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03673 03674 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03675 s = dp->expiry.tv_sec - now.tv_sec; 03676 tmp[0] = '\0'; 03677 if (dp->flags & CACHE_FLAG_EXISTS) 03678 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03679 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03680 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03681 if (dp->flags & CACHE_FLAG_CANEXIST) 03682 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03683 if (dp->flags & CACHE_FLAG_PENDING) 03684 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03685 if (dp->flags & CACHE_FLAG_TIMEOUT) 03686 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03687 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03688 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03689 if (dp->flags & CACHE_FLAG_MATCHMORE) 03690 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03691 if (dp->flags & CACHE_FLAG_UNKNOWN) 03692 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03693 /* Trim trailing pipe */ 03694 if (!ast_strlen_zero(tmp)) { 03695 tmp[strlen(tmp) - 1] = '\0'; 03696 } else { 03697 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03698 } 03699 y = 0; 03700 pc = strchr(dp->peercontext, '@'); 03701 if (!pc) { 03702 pc = dp->peercontext; 03703 } else { 03704 pc++; 03705 } 03706 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03707 if (dp->waiters[x] > -1) 03708 y++; 03709 } 03710 if (s > 0) { 03711 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03712 } else { 03713 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03714 } 03715 } 03716 03717 AST_LIST_UNLOCK(&dpcache); 03718 03719 return CLI_SUCCESS; 03720 }
static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2279 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, peercnts, and ast_cli_entry::usage.
02280 { 02281 struct ao2_iterator i; 02282 struct peercnt *peercnt; 02283 struct sockaddr_in sin; 02284 int found = 0; 02285 02286 switch (cmd) { 02287 case CLI_INIT: 02288 e->command = "iax2 show callnumber usage"; 02289 e->usage = 02290 "Usage: iax2 show callnumber usage <ip address (optional)>\n" 02291 " Shows current ip addresses which are consuming iax2 call numbers\n"; 02292 return NULL; 02293 case CLI_GENERATE: 02294 return NULL; 02295 case CLI_HANDLER: 02296 if (a->argc < 4 || a->argc > 5) 02297 return CLI_SHOWUSAGE; 02298 02299 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02300 i = ao2_iterator_init(peercnts, 0); 02301 while ((peercnt = ao2_iterator_next(&i))) { 02302 sin.sin_addr.s_addr = peercnt->addr; 02303 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02304 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02305 found = 1; 02306 break; 02307 } else { 02308 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02309 } 02310 ao2_ref(peercnt, -1); 02311 } 02312 ao2_iterator_destroy(&i); 02313 02314 if (a->argc == 4) { 02315 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02316 } else if (a->argc == 5 && !found) { 02317 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02318 } 02319 02320 return CLI_SUCCESS; 02321 default: 02322 return NULL; 02323 } 02324 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6665 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_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, iaxs, 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.
06666 { 06667 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 06668 #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" 06669 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 06670 int x; 06671 int numchans = 0; 06672 char first_message[10] = { 0, }; 06673 char last_message[10] = { 0, }; 06674 06675 switch (cmd) { 06676 case CLI_INIT: 06677 e->command = "iax2 show channels"; 06678 e->usage = 06679 "Usage: iax2 show channels\n" 06680 " Lists all currently active IAX channels.\n"; 06681 return NULL; 06682 case CLI_GENERATE: 06683 return NULL; 06684 } 06685 06686 if (a->argc != 3) 06687 return CLI_SHOWUSAGE; 06688 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06689 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06690 ast_mutex_lock(&iaxsl[x]); 06691 if (iaxs[x]) { 06692 int lag, jitter, localdelay; 06693 jb_info jbinfo; 06694 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06695 jb_getinfo(iaxs[x]->jb, &jbinfo); 06696 jitter = jbinfo.jitter; 06697 localdelay = jbinfo.current - jbinfo.min; 06698 } else { 06699 jitter = -1; 06700 localdelay = 0; 06701 } 06702 06703 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06704 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06705 lag = iaxs[x]->remote_rr.delay; 06706 ast_cli(a->fd, FORMAT, 06707 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06708 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06709 S_OR(iaxs[x]->username, "(None)"), 06710 iaxs[x]->callno, iaxs[x]->peercallno, 06711 iaxs[x]->oseqno, iaxs[x]->iseqno, 06712 lag, 06713 jitter, 06714 localdelay, 06715 ast_getformatname(iaxs[x]->voiceformat), 06716 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06717 first_message, 06718 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06719 last_message); 06720 numchans++; 06721 } 06722 ast_mutex_unlock(&iaxsl[x]); 06723 } 06724 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06725 return CLI_SUCCESS; 06726 #undef FORMAT 06727 #undef FORMAT2 06728 #undef FORMATB 06729 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6515 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, iax_firmware::list, ast_cli_entry::usage, and ast_iax2_firmware_header::version.
06516 { 06517 struct iax_firmware *cur = NULL; 06518 06519 switch (cmd) { 06520 case CLI_INIT: 06521 e->command = "iax2 show firmware"; 06522 e->usage = 06523 "Usage: iax2 show firmware\n" 06524 " Lists all known IAX firmware images.\n"; 06525 return NULL; 06526 case CLI_GENERATE: 06527 return NULL; 06528 } 06529 06530 if (a->argc != 3 && a->argc != 4) 06531 return CLI_SHOWUSAGE; 06532 06533 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06534 AST_LIST_LOCK(&firmwares); 06535 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06536 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06537 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06538 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06539 } 06540 } 06541 AST_LIST_UNLOCK(&firmwares); 06542 06543 return CLI_SUCCESS; 06544 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6815 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.
06816 { 06817 int numchans = 0; 06818 06819 switch (cmd) { 06820 case CLI_INIT: 06821 e->command = "iax2 show netstats"; 06822 e->usage = 06823 "Usage: iax2 show netstats\n" 06824 " Lists network status for all currently active IAX channels.\n"; 06825 return NULL; 06826 case CLI_GENERATE: 06827 return NULL; 06828 } 06829 if (a->argc != 3) 06830 return CLI_SHOWUSAGE; 06831 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06832 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06833 numchans = ast_cli_netstats(NULL, a->fd, 1); 06834 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06835 return CLI_SUCCESS; 06836 }
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 3469 of file chan_iax2.c.
References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, iax2_peer::defaddr, iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.
03470 { 03471 char status[30]; 03472 char cbuf[256]; 03473 struct iax2_peer *peer; 03474 char codec_buf[512]; 03475 int x = 0, codec = 0, load_realtime = 0; 03476 03477 switch (cmd) { 03478 case CLI_INIT: 03479 e->command = "iax2 show peer"; 03480 e->usage = 03481 "Usage: iax2 show peer <name>\n" 03482 " Display details on specific IAX peer\n"; 03483 return NULL; 03484 case CLI_GENERATE: 03485 if (a->pos == 3) 03486 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 03487 return NULL; 03488 } 03489 03490 if (a->argc < 4) 03491 return CLI_SHOWUSAGE; 03492 03493 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03494 03495 peer = find_peer(a->argv[3], load_realtime); 03496 if (peer) { 03497 ast_cli(a->fd, "\n\n"); 03498 ast_cli(a->fd, " * Name : %s\n", peer->name); 03499 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03500 ast_cli(a->fd, " Context : %s\n", peer->context); 03501 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03502 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03503 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03504 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03505 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03506 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03507 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03508 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03509 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03510 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)); 03511 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03512 ast_cli(a->fd, " Username : %s\n", peer->username); 03513 ast_cli(a->fd, " Codecs : "); 03514 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03515 ast_cli(a->fd, "%s\n", codec_buf); 03516 03517 ast_cli(a->fd, " Codec Order : ("); 03518 for(x = 0; x < 32 ; x++) { 03519 codec = ast_codec_pref_index(&peer->prefs,x); 03520 if(!codec) 03521 break; 03522 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03523 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03524 ast_cli(a->fd, "|"); 03525 } 03526 03527 if (!x) 03528 ast_cli(a->fd, "none"); 03529 ast_cli(a->fd, ")\n"); 03530 03531 ast_cli(a->fd, " Status : "); 03532 peer_status(peer, status, sizeof(status)); 03533 ast_cli(a->fd, "%s\n",status); 03534 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"); 03535 ast_cli(a->fd, "\n"); 03536 peer_unref(peer); 03537 } else { 03538 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03539 ast_cli(a->fd, "\n"); 03540 } 03541 03542 return CLI_SUCCESS; 03543 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6483 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.
06484 { 06485 switch (cmd) { 06486 case CLI_INIT: 06487 e->command = "iax2 show peers"; 06488 e->usage = 06489 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06490 " Lists all known IAX2 peers.\n" 06491 " Optional 'registered' argument lists only peers with known addresses.\n" 06492 " Optional regular expression pattern is used to filter the peer list.\n"; 06493 return NULL; 06494 case CLI_GENERATE: 06495 return NULL; 06496 } 06497 06498 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) { 06499 case RESULT_SHOWUSAGE: 06500 return CLI_SHOWUSAGE; 06501 case RESULT_FAILURE: 06502 return CLI_FAILURE; 06503 default: 06504 return CLI_SUCCESS; 06505 } 06506 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6624 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, iax2_registry::entry, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
06625 { 06626 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 06627 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 06628 struct iax2_registry *reg = NULL; 06629 char host[80]; 06630 char perceived[80]; 06631 int counter = 0; 06632 06633 switch (cmd) { 06634 case CLI_INIT: 06635 e->command = "iax2 show registry"; 06636 e->usage = 06637 "Usage: iax2 show registry\n" 06638 " Lists all registration requests and status.\n"; 06639 return NULL; 06640 case CLI_GENERATE: 06641 return NULL; 06642 } 06643 if (a->argc != 3) 06644 return CLI_SHOWUSAGE; 06645 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 06646 AST_LIST_LOCK(®istrations); 06647 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06648 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06649 if (reg->us.sin_addr.s_addr) 06650 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06651 else 06652 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06653 ast_cli(a->fd, FORMAT, host, 06654 (reg->dnsmgr) ? "Y" : "N", 06655 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 06656 counter++; 06657 } 06658 AST_LIST_UNLOCK(®istrations); 06659 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 06660 return CLI_SUCCESS; 06661 #undef FORMAT 06662 #undef FORMAT2 06663 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3567 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(), iax2_trunk_peer::list, iax_frame::retries, and ast_cli_entry::usage.
03568 { 03569 struct iax_frame *cur; 03570 int cnt = 0, dead = 0, final = 0; 03571 03572 switch (cmd) { 03573 case CLI_INIT: 03574 e->command = "iax2 show stats"; 03575 e->usage = 03576 "Usage: iax2 show stats\n" 03577 " Display statistics on IAX channel driver.\n"; 03578 return NULL; 03579 case CLI_GENERATE: 03580 return NULL; 03581 } 03582 03583 if (a->argc != 3) 03584 return CLI_SHOWUSAGE; 03585 03586 AST_LIST_LOCK(&frame_queue); 03587 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 03588 if (cur->retries < 0) 03589 dead++; 03590 if (cur->final) 03591 final++; 03592 cnt++; 03593 } 03594 AST_LIST_UNLOCK(&frame_queue); 03595 03596 ast_cli(a->fd, " IAX Statistics\n"); 03597 ast_cli(a->fd, "---------------------\n"); 03598 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03599 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03600 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03601 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03602 03603 trunk_timed = trunk_untimed = 0; 03604 if (trunk_maxmtu > trunk_nmaxmtu) 03605 trunk_nmaxmtu = trunk_maxmtu; 03606 03607 return CLI_SUCCESS; 03608 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6346 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, thread, and ast_cli_entry::usage.
06347 { 06348 struct iax2_thread *thread = NULL; 06349 time_t t; 06350 int threadcount = 0, dynamiccount = 0; 06351 char type; 06352 06353 switch (cmd) { 06354 case CLI_INIT: 06355 e->command = "iax2 show threads"; 06356 e->usage = 06357 "Usage: iax2 show threads\n" 06358 " Lists status of IAX helper threads\n"; 06359 return NULL; 06360 case CLI_GENERATE: 06361 return NULL; 06362 } 06363 if (a->argc != 3) 06364 return CLI_SHOWUSAGE; 06365 06366 ast_cli(a->fd, "IAX2 Thread Information\n"); 06367 time(&t); 06368 ast_cli(a->fd, "Idle Threads:\n"); 06369 AST_LIST_LOCK(&idle_list); 06370 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06371 #ifdef DEBUG_SCHED_MULTITHREAD 06372 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06373 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06374 #else 06375 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06376 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06377 #endif 06378 threadcount++; 06379 } 06380 AST_LIST_UNLOCK(&idle_list); 06381 ast_cli(a->fd, "Active Threads:\n"); 06382 AST_LIST_LOCK(&active_list); 06383 AST_LIST_TRAVERSE(&active_list, thread, list) { 06384 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06385 type = 'D'; 06386 else 06387 type = 'P'; 06388 #ifdef DEBUG_SCHED_MULTITHREAD 06389 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06390 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06391 #else 06392 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06393 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06394 #endif 06395 threadcount++; 06396 } 06397 AST_LIST_UNLOCK(&active_list); 06398 ast_cli(a->fd, "Dynamic Threads:\n"); 06399 AST_LIST_LOCK(&dynamic_list); 06400 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06401 #ifdef DEBUG_SCHED_MULTITHREAD 06402 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06403 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06404 #else 06405 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06406 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06407 #endif 06408 dynamiccount++; 06409 } 06410 AST_LIST_UNLOCK(&dynamic_list); 06411 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06412 return CLI_SUCCESS; 06413 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6143 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, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, user, user_unref(), and users.
06144 { 06145 regex_t regexbuf; 06146 int havepattern = 0; 06147 06148 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06149 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06150 06151 struct iax2_user *user = NULL; 06152 char auth[90]; 06153 char *pstr = ""; 06154 struct ao2_iterator i; 06155 06156 switch (cmd) { 06157 case CLI_INIT: 06158 e->command = "iax2 show users [like]"; 06159 e->usage = 06160 "Usage: iax2 show users [like <pattern>]\n" 06161 " Lists all known IAX2 users.\n" 06162 " Optional regular expression pattern is used to filter the user list.\n"; 06163 return NULL; 06164 case CLI_GENERATE: 06165 return NULL; 06166 } 06167 06168 switch (a->argc) { 06169 case 5: 06170 if (!strcasecmp(a->argv[3], "like")) { 06171 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06172 return CLI_SHOWUSAGE; 06173 havepattern = 1; 06174 } else 06175 return CLI_SHOWUSAGE; 06176 case 3: 06177 break; 06178 default: 06179 return CLI_SHOWUSAGE; 06180 } 06181 06182 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06183 i = ao2_iterator_init(users, 0); 06184 for (user = ao2_iterator_next(&i); user; 06185 user_unref(user), user = ao2_iterator_next(&i)) { 06186 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06187 continue; 06188 06189 if (!ast_strlen_zero(user->secret)) { 06190 ast_copy_string(auth,user->secret, sizeof(auth)); 06191 } else if (!ast_strlen_zero(user->inkeys)) { 06192 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06193 } else 06194 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06195 06196 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 06197 pstr = "REQ Only"; 06198 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 06199 pstr = "Disabled"; 06200 else 06201 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06202 06203 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06204 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06205 user->ha ? "Yes" : "No", pstr); 06206 } 06207 ao2_iterator_destroy(&i); 06208 06209 if (havepattern) 06210 regfree(®exbuf); 06211 06212 return CLI_SUCCESS; 06213 #undef FORMAT 06214 #undef FORMAT2 06215 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3355 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.
03356 { 03357 switch (cmd) { 03358 case CLI_INIT: 03359 e->command = "iax2 test losspct"; 03360 e->usage = 03361 "Usage: iax2 test losspct <percentage>\n" 03362 " For testing, throws away <percentage> percent of incoming packets\n"; 03363 return NULL; 03364 case CLI_GENERATE: 03365 return NULL; 03366 } 03367 if (a->argc != 4) 03368 return CLI_SHOWUSAGE; 03369 03370 test_losspct = atoi(a->argv[3]); 03371 03372 return CLI_SUCCESS; 03373 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6415 of file chan_iax2.c.
References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, iax2_peer::name, OBJ_POINTER, peer_ref(), peer_unref(), peers, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06416 { 06417 struct iax2_peer *p; 06418 06419 switch (cmd) { 06420 case CLI_INIT: 06421 e->command = "iax2 unregister"; 06422 e->usage = 06423 "Usage: iax2 unregister <peername>\n" 06424 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06425 return NULL; 06426 case CLI_GENERATE: 06427 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06428 } 06429 06430 if (a->argc != 3) 06431 return CLI_SHOWUSAGE; 06432 06433 p = find_peer(a->argv[2], 1); 06434 if (p) { 06435 if (p->expire > 0) { 06436 struct iax2_peer tmp_peer = { 06437 .name = a->argv[2], 06438 }; 06439 struct iax2_peer *peer; 06440 06441 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06442 if (peer) { 06443 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06444 peer_unref(peer); /* ref from ao2_find() */ 06445 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06446 } else { 06447 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06448 } 06449 } else { 06450 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06451 } 06452 } else { 06453 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06454 } 06455 return CLI_SUCCESS; 06456 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 8958 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.
08959 { 08960 struct iax2_pkt_buf *pkt_buf; 08961 08962 ast_mutex_lock(&thread->lock); 08963 08964 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 08965 ast_mutex_unlock(&thread->lock); 08966 08967 thread->buf = pkt_buf->buf; 08968 thread->buf_len = pkt_buf->len; 08969 thread->buf_size = pkt_buf->len + 1; 08970 08971 socket_process(thread); 08972 08973 thread->buf = NULL; 08974 ast_free(pkt_buf); 08975 08976 ast_mutex_lock(&thread->lock); 08977 } 08978 08979 ast_mutex_unlock(&thread->lock); 08980 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3023 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().
03024 { 03025 /* XXX Ideally we should figure out why an error occurred and then abort those 03026 rather than continuing to try. Unfortunately, the published interface does 03027 not seem to work XXX */ 03028 #if 0 03029 struct sockaddr_in *sin; 03030 int res; 03031 struct msghdr m; 03032 struct sock_extended_err e; 03033 m.msg_name = NULL; 03034 m.msg_namelen = 0; 03035 m.msg_iov = NULL; 03036 m.msg_control = &e; 03037 m.msg_controllen = sizeof(e); 03038 m.msg_flags = 0; 03039 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03040 if (res < 0) 03041 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03042 else { 03043 if (m.msg_controllen) { 03044 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03045 if (sin) 03046 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03047 else 03048 ast_log(LOG_WARNING, "No address detected??\n"); 03049 } else { 03050 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03051 } 03052 } 03053 #endif 03054 return 0; 03055 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 7925 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(), iaxs, 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, sched, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
07926 { 07927 struct iax2_registry *reg; 07928 /* Start pessimistic */ 07929 char peer[256] = ""; 07930 char msgstatus[60]; 07931 int refresh = 60; 07932 char ourip[256] = "<Unspecified>"; 07933 struct sockaddr_in oldus; 07934 struct sockaddr_in us; 07935 int oldmsgs; 07936 07937 memset(&us, 0, sizeof(us)); 07938 if (ies->apparent_addr) 07939 memmove(&us, ies->apparent_addr, sizeof(us)); 07940 if (ies->username) 07941 ast_copy_string(peer, ies->username, sizeof(peer)); 07942 if (ies->refresh) 07943 refresh = ies->refresh; 07944 if (ies->calling_number) { 07945 /* We don't do anything with it really, but maybe we should */ 07946 } 07947 reg = iaxs[callno]->reg; 07948 if (!reg) { 07949 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 07950 return -1; 07951 } 07952 memcpy(&oldus, ®->us, sizeof(oldus)); 07953 oldmsgs = reg->messages; 07954 if (inaddrcmp(®->addr, sin)) { 07955 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07956 return -1; 07957 } 07958 memcpy(®->us, &us, sizeof(reg->us)); 07959 if (ies->msgcount >= 0) 07960 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 07961 /* always refresh the registration at the interval requested by the server 07962 we are registering to 07963 */ 07964 reg->refresh = refresh; 07965 reg->expire = iax2_sched_replace(reg->expire, sched, 07966 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07967 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 07968 if (reg->messages > 255) 07969 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 07970 else if (reg->messages > 1) 07971 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 07972 else if (reg->messages > 0) 07973 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus)); 07974 else 07975 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus)); 07976 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07977 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 07978 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 07979 } 07980 reg->regstate = REG_STATE_REGISTERED; 07981 return 0; 07982 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2462 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().
02463 { 02464 if (frametype != AST_FRAME_IAX) { 02465 return 0; 02466 } 02467 switch (subclass) { 02468 case IAX_COMMAND_NEW: 02469 case IAX_COMMAND_REGREQ: 02470 case IAX_COMMAND_FWDOWNL: 02471 case IAX_COMMAND_REGREL: 02472 return 1; 02473 case IAX_COMMAND_POKE: 02474 if (!inbound) { 02475 return 1; 02476 } 02477 break; 02478 } 02479 return 0; 02480 }
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 1109 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().
01110 { 01111 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01112 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01113 pvt->owner ? pvt->owner->name : "", 01114 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01115 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5218 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), iax2_ami_channelupdate(), iaxs, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05219 { 05220 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05221 ast_debug(1, "Answering IAX2 call\n"); 05222 ast_mutex_lock(&iaxsl[callno]); 05223 if (iaxs[callno]) 05224 iax2_ami_channelupdate(iaxs[callno]); 05225 ast_mutex_unlock(&iaxsl[callno]); 05226 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05227 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 7984 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, iax2_registry::entry, IAX_DEFAULT_PORTNO, and IAX_DEFAULT_REG_EXPIRE.
Referenced by iax2_register().
07986 { 07987 struct iax2_registry *reg; 07988 07989 if (!(reg = ast_calloc(1, sizeof(*reg)))) 07990 return -1; 07991 07992 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 07993 ast_free(reg); 07994 return -1; 07995 } 07996 07997 ast_copy_string(reg->username, username, sizeof(reg->username)); 07998 07999 if (secret) 08000 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08001 08002 reg->expire = -1; 08003 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08004 reg->addr.sin_family = AF_INET; 08005 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 08006 08007 AST_LIST_LOCK(®istrations); 08008 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08009 AST_LIST_UNLOCK(®istrations); 08010 08011 return 0; 08012 }
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 5063 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verb, chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, lock_both(), PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and unlock_both().
05064 { 05065 struct ast_channel *cs[3]; 05066 struct ast_channel *who, *other; 05067 int to = -1; 05068 int res = -1; 05069 int transferstarted=0; 05070 struct ast_frame *f; 05071 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05072 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05073 struct timeval waittimer = {0, 0}; 05074 05075 /* We currently do not support native bridging if a timeoutms value has been provided */ 05076 if (timeoutms > 0) { 05077 return AST_BRIDGE_FAILED; 05078 } 05079 05080 timeoutms = -1; 05081 05082 lock_both(callno0, callno1); 05083 if (!iaxs[callno0] || !iaxs[callno1]) { 05084 unlock_both(callno0, callno1); 05085 return AST_BRIDGE_FAILED; 05086 } 05087 /* Put them in native bridge mode */ 05088 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05089 iaxs[callno0]->bridgecallno = callno1; 05090 iaxs[callno1]->bridgecallno = callno0; 05091 } 05092 unlock_both(callno0, callno1); 05093 05094 /* If not, try to bridge until we can execute a transfer, if we can */ 05095 cs[0] = c0; 05096 cs[1] = c1; 05097 for (/* ever */;;) { 05098 /* Check in case we got masqueraded into */ 05099 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05100 ast_verb(3, "Can't masquerade, we're different...\n"); 05101 /* Remove from native mode */ 05102 if (c0->tech == &iax2_tech) { 05103 ast_mutex_lock(&iaxsl[callno0]); 05104 iaxs[callno0]->bridgecallno = 0; 05105 ast_mutex_unlock(&iaxsl[callno0]); 05106 } 05107 if (c1->tech == &iax2_tech) { 05108 ast_mutex_lock(&iaxsl[callno1]); 05109 iaxs[callno1]->bridgecallno = 0; 05110 ast_mutex_unlock(&iaxsl[callno1]); 05111 } 05112 return AST_BRIDGE_FAILED_NOWARN; 05113 } 05114 if (c0->nativeformats != c1->nativeformats) { 05115 char buf0[255]; 05116 char buf1[255]; 05117 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 05118 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 05119 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 05120 /* Remove from native mode */ 05121 lock_both(callno0, callno1); 05122 if (iaxs[callno0]) 05123 iaxs[callno0]->bridgecallno = 0; 05124 if (iaxs[callno1]) 05125 iaxs[callno1]->bridgecallno = 0; 05126 unlock_both(callno0, callno1); 05127 return AST_BRIDGE_FAILED_NOWARN; 05128 } 05129 /* check if transfered and if we really want native bridging */ 05130 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 05131 /* Try the transfer */ 05132 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05133 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 05134 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05135 transferstarted = 1; 05136 } 05137 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05138 /* Call has been transferred. We're no longer involved */ 05139 struct timeval now = ast_tvnow(); 05140 if (ast_tvzero(waittimer)) { 05141 waittimer = now; 05142 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05143 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05144 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05145 *fo = NULL; 05146 *rc = c0; 05147 res = AST_BRIDGE_COMPLETE; 05148 break; 05149 } 05150 } 05151 to = 1000; 05152 who = ast_waitfor_n(cs, 2, &to); 05153 if (timeoutms > -1) { 05154 timeoutms -= (1000 - to); 05155 if (timeoutms < 0) 05156 timeoutms = 0; 05157 } 05158 if (!who) { 05159 if (!timeoutms) { 05160 res = AST_BRIDGE_RETRY; 05161 break; 05162 } 05163 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05164 res = AST_BRIDGE_FAILED; 05165 break; 05166 } 05167 continue; 05168 } 05169 f = ast_read(who); 05170 if (!f) { 05171 *fo = NULL; 05172 *rc = who; 05173 res = AST_BRIDGE_COMPLETE; 05174 break; 05175 } 05176 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 05177 *fo = f; 05178 *rc = who; 05179 res = AST_BRIDGE_COMPLETE; 05180 break; 05181 } 05182 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05183 if ((f->frametype == AST_FRAME_VOICE) || 05184 (f->frametype == AST_FRAME_TEXT) || 05185 (f->frametype == AST_FRAME_VIDEO) || 05186 (f->frametype == AST_FRAME_IMAGE) || 05187 (f->frametype == AST_FRAME_DTMF) || 05188 (f->frametype == AST_FRAME_CONTROL)) { 05189 /* monitored dtmf take out of the bridge. 05190 * check if we monitor the specific source. 05191 */ 05192 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05193 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05194 *rc = who; 05195 *fo = f; 05196 res = AST_BRIDGE_COMPLETE; 05197 /* Remove from native mode */ 05198 break; 05199 } 05200 /* everything else goes to the other side */ 05201 ast_write(other, f); 05202 } 05203 ast_frfree(f); 05204 /* Swap who gets priority */ 05205 cs[2] = cs[0]; 05206 cs[0] = cs[1]; 05207 cs[1] = cs[2]; 05208 } 05209 lock_both(callno0, callno1); 05210 if(iaxs[callno0]) 05211 iaxs[callno0]->bridgecallno = 0; 05212 if(iaxs[callno1]) 05213 iaxs[callno1]->bridgecallno = 0; 05214 unlock_both(callno0, callno1); 05215 return res; 05216 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4674 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), 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, ast_channel::context, create_addr(), ast_datastore::data, chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, chan_iax2_pvt::username, and var.
04675 { 04676 struct sockaddr_in sin; 04677 char *l=NULL, *n=NULL, *tmpstr; 04678 struct iax_ie_data ied; 04679 char *defaultrdest = "s"; 04680 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04681 struct parsed_dial_string pds; 04682 struct create_addr_info cai; 04683 struct ast_var_t *var; 04684 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04685 const char* osp_token_ptr; 04686 unsigned int osp_token_length; 04687 unsigned char osp_block_index; 04688 unsigned int osp_block_length; 04689 unsigned char osp_buffer[256]; 04690 04691 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04692 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04693 return -1; 04694 } 04695 04696 memset(&cai, 0, sizeof(cai)); 04697 cai.encmethods = iax2_encryption; 04698 04699 memset(&pds, 0, sizeof(pds)); 04700 tmpstr = ast_strdupa(dest); 04701 parse_dial_string(tmpstr, &pds); 04702 04703 if (ast_strlen_zero(pds.peer)) { 04704 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04705 return -1; 04706 } 04707 04708 if (!pds.exten) { 04709 pds.exten = defaultrdest; 04710 } 04711 04712 if (create_addr(pds.peer, c, &sin, &cai)) { 04713 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04714 return -1; 04715 } 04716 04717 if (!pds.username && !ast_strlen_zero(cai.username)) 04718 pds.username = cai.username; 04719 if (!pds.password && !ast_strlen_zero(cai.secret)) 04720 pds.password = cai.secret; 04721 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04722 pds.key = cai.outkey; 04723 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04724 pds.context = cai.peercontext; 04725 04726 /* Keep track of the context for outgoing calls too */ 04727 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04728 04729 if (pds.port) 04730 sin.sin_port = htons(atoi(pds.port)); 04731 04732 l = c->cid.cid_num; 04733 n = c->cid.cid_name; 04734 04735 /* Now build request */ 04736 memset(&ied, 0, sizeof(ied)); 04737 04738 /* On new call, first IE MUST be IAX version of caller */ 04739 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04740 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04741 if (pds.options && strchr(pds.options, 'a')) { 04742 /* Request auto answer */ 04743 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04744 } 04745 04746 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04747 04748 if (l) { 04749 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04750 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04751 } else { 04752 if (n) 04753 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04754 else 04755 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04756 } 04757 04758 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04759 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04760 04761 if (n) 04762 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04763 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04764 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04765 04766 if (!ast_strlen_zero(c->language)) 04767 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04768 if (!ast_strlen_zero(c->cid.cid_dnid)) 04769 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04770 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04771 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04772 04773 if (pds.context) 04774 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04775 04776 if (pds.username) 04777 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04778 04779 if (cai.encmethods) 04780 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04781 04782 ast_mutex_lock(&iaxsl[callno]); 04783 04784 if (!ast_strlen_zero(c->context)) 04785 ast_string_field_set(iaxs[callno], context, c->context); 04786 04787 if (pds.username) 04788 ast_string_field_set(iaxs[callno], username, pds.username); 04789 04790 iaxs[callno]->encmethods = cai.encmethods; 04791 04792 iaxs[callno]->adsi = cai.adsi; 04793 04794 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04795 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04796 04797 if (pds.key) 04798 ast_string_field_set(iaxs[callno], outkey, pds.key); 04799 if (pds.password) 04800 ast_string_field_set(iaxs[callno], secret, pds.password); 04801 04802 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04803 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04804 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04805 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04806 04807 if (iaxs[callno]->maxtime) { 04808 /* Initialize pingtime and auto-congest time */ 04809 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04810 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04811 } else if (autokill) { 04812 iaxs[callno]->pingtime = autokill / 2; 04813 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04814 } 04815 04816 /* Check if there is an OSP token */ 04817 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 04818 if (!ast_strlen_zero(osp_token_ptr)) { 04819 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 04820 osp_block_index = 0; 04821 while (osp_token_length > 0) { 04822 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 04823 osp_buffer[0] = osp_block_index; 04824 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 04825 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 04826 osp_block_index++; 04827 osp_token_ptr += osp_block_length; 04828 osp_token_length -= osp_block_length; 04829 } 04830 } else 04831 ast_log(LOG_WARNING, "OSP token is too long\n"); 04832 } else if (iaxdebug) 04833 ast_debug(1, "OSP token is undefined\n"); 04834 04835 /* send the command using the appropriate socket for this peer */ 04836 iaxs[callno]->sockfd = cai.sockfd; 04837 04838 /* Add remote vars */ 04839 if (variablestore) { 04840 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 04841 ast_debug(1, "Found an IAX variable store on this channel\n"); 04842 AST_LIST_LOCK(variablelist); 04843 AST_LIST_TRAVERSE(variablelist, var, entries) { 04844 char tmp[256]; 04845 int i; 04846 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 04847 /* Automatically divide the value up into sized chunks */ 04848 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 04849 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 04850 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 04851 } 04852 } 04853 AST_LIST_UNLOCK(variablelist); 04854 } 04855 04856 /* Transmit the string in a "NEW" request */ 04857 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04858 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04859 04860 ast_mutex_unlock(&iaxsl[callno]); 04861 ast_setstate(c, AST_STATE_RINGING); 04862 04863 return 0; 04864 }
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 13039 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, chan, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13040 { 13041 int res = 0; 13042 struct iax2_dpcache *dp = NULL; 13043 #if 0 13044 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13045 #endif 13046 if ((priority != 1) && (priority != 2)) 13047 return 0; 13048 13049 AST_LIST_LOCK(&dpcache); 13050 if ((dp = find_cache(chan, data, context, exten, priority))) { 13051 if (dp->flags & CACHE_FLAG_CANEXIST) 13052 res = 1; 13053 } else { 13054 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13055 } 13056 AST_LIST_UNLOCK(&dpcache); 13057 13058 return res; 13059 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4345 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().
04346 { 04347 struct timeval t = ast_tvnow(); 04348 struct ast_tm tm; 04349 unsigned int tmp; 04350 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04351 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04352 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04353 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04354 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04355 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04356 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04357 return tmp; 04358 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3129 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, 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().
03130 { 03131 struct chan_iax2_pvt *pvt = NULL; 03132 struct ast_channel *owner = NULL; 03133 03134 retry: 03135 if ((pvt = iaxs[callno])) { 03136 iax2_destroy_helper(pvt); 03137 } 03138 03139 owner = pvt ? pvt->owner : NULL; 03140 03141 if (owner) { 03142 if (ast_channel_trylock(owner)) { 03143 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03144 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03145 goto retry; 03146 } 03147 } 03148 03149 if (!owner) { 03150 iaxs[callno] = NULL; 03151 } 03152 03153 if (pvt) { 03154 if (!owner) { 03155 pvt->owner = NULL; 03156 } else { 03157 /* If there's an owner, prod it to give up */ 03158 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03159 * because we already hold the owner channel lock. */ 03160 ast_queue_hangup(owner); 03161 } 03162 03163 if (pvt->peercallno) { 03164 remove_by_peercallno(pvt); 03165 } 03166 03167 if (pvt->transfercallno) { 03168 remove_by_transfercallno(pvt); 03169 } 03170 03171 if (!owner) { 03172 ao2_ref(pvt, -1); 03173 pvt = NULL; 03174 } 03175 } 03176 03177 if (owner) { 03178 ast_channel_unlock(owner); 03179 } 03180 03181 if (callno & 0x4000) { 03182 update_max_trunk(); 03183 } 03184 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1528 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL, AST_SCHED_DEL_SPINLOCK, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, 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, sched, user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01529 { 01530 /* Decrement AUTHREQ count if needed */ 01531 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01532 struct iax2_user *user; 01533 struct iax2_user tmp_user = { 01534 .name = pvt->username, 01535 }; 01536 01537 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01538 if (user) { 01539 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01540 user_unref(user); 01541 } 01542 01543 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01544 } 01545 /* No more pings or lagrq's */ 01546 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01547 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01548 AST_SCHED_DEL(sched, pvt->autoid); 01549 AST_SCHED_DEL(sched, pvt->authid); 01550 AST_SCHED_DEL(sched, pvt->initid); 01551 AST_SCHED_DEL(sched, pvt->jbid); 01552 AST_SCHED_DEL(sched, pvt->keyrotateid); 01553 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13258 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), and peer_unref().
13259 { 13260 struct parsed_dial_string pds; 13261 char *tmp = ast_strdupa(data); 13262 struct iax2_peer *p; 13263 int res = AST_DEVICE_INVALID; 13264 13265 memset(&pds, 0, sizeof(pds)); 13266 parse_dial_string(tmp, &pds); 13267 13268 if (ast_strlen_zero(pds.peer)) { 13269 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13270 return res; 13271 } 13272 13273 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13274 13275 /* SLD: FIXME: second call to find_peer during registration */ 13276 if (!(p = find_peer(pds.peer, 1))) 13277 return res; 13278 13279 res = AST_DEVICE_UNAVAILABLE; 13280 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13281 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13282 13283 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 13284 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13285 /* Peer is registered, or have default IP address 13286 and a valid registration */ 13287 if (p->historicms == 0 || p->historicms <= p->maxms) 13288 /* let the core figure out whether it is in use or not */ 13289 res = AST_DEVICE_UNKNOWN; 13290 } 13291 13292 peer_unref(p); 13293 13294 return res; 13295 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 3969 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03970 { 03971 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 03972 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 3974 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03975 { 03976 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 03977 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11092 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(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, LOG_WARNING, NEW_FORCE, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
11093 { 11094 struct iax_ie_data ied; 11095 if (iaxdebug) 11096 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11097 11098 if (reg->dnsmgr && 11099 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 11100 /* Maybe the IP has changed, force DNS refresh */ 11101 ast_dnsmgr_refresh(reg->dnsmgr); 11102 } 11103 11104 /* 11105 * if IP has Changed, free allocated call to create a new one with new IP 11106 * call has the pointer to IP and must be updated to the new one 11107 */ 11108 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11109 int callno = reg->callno; 11110 ast_mutex_lock(&iaxsl[callno]); 11111 iax2_destroy(callno); 11112 ast_mutex_unlock(&iaxsl[callno]); 11113 reg->callno = 0; 11114 } 11115 if (!reg->addr.sin_addr.s_addr) { 11116 if (iaxdebug) 11117 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11118 /* Setup the next registration attempt */ 11119 reg->expire = iax2_sched_replace(reg->expire, sched, 11120 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11121 return -1; 11122 } 11123 11124 if (!reg->callno) { 11125 ast_debug(3, "Allocate call number\n"); 11126 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 11127 if (reg->callno < 1) { 11128 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11129 return -1; 11130 } else 11131 ast_debug(3, "Registration created on call %d\n", reg->callno); 11132 iaxs[reg->callno]->reg = reg; 11133 ast_mutex_unlock(&iaxsl[reg->callno]); 11134 } 11135 /* Setup the next registration a little early */ 11136 reg->expire = iax2_sched_replace(reg->expire, sched, 11137 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11138 /* Send the request */ 11139 memset(&ied, 0, sizeof(ied)); 11140 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11141 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11142 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11143 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11144 reg->regstate = REG_STATE_REGSENT; 11145 return 0; 11146 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7769 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
07770 { 07771 #ifdef SCHED_MULTITHREADED 07772 if (schedule_action(__iax2_do_register_s, data)) 07773 #endif 07774 __iax2_do_register_s(data); 07775 return 0; 07776 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 8519 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
08520 { 08521 struct iax_ie_data ied; 08522 /* Auto-hangup with 30 seconds of inactivity */ 08523 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 08524 sched, 30000, auto_hangup, (void *)(long)callno); 08525 memset(&ied, 0, sizeof(ied)); 08526 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 08527 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 08528 dp->flags |= CACHE_FLAG_TRANSMITTED; 08529 }
static void * iax2_dup_variable_datastore | ( | void * | ) | [static] |
Definition at line 1124 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.
01125 { 01126 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01127 struct ast_var_t *oldvar, *newvar; 01128 01129 newlist = ast_calloc(sizeof(*newlist), 1); 01130 if (!newlist) { 01131 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01132 return NULL; 01133 } 01134 01135 AST_LIST_HEAD_INIT(newlist); 01136 AST_LIST_LOCK(oldlist); 01137 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01138 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01139 if (newvar) 01140 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01141 else 01142 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01143 } 01144 AST_LIST_UNLOCK(oldlist); 01145 return newlist; 01146 }
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 13085 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, chan, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().
13086 { 13087 char odata[256]; 13088 char req[256]; 13089 char *ncontext; 13090 struct iax2_dpcache *dp = NULL; 13091 struct ast_app *dial = NULL; 13092 #if 0 13093 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); 13094 #endif 13095 if (priority == 2) { 13096 /* Indicate status, can be overridden in dialplan */ 13097 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13098 if (dialstatus) { 13099 dial = pbx_findapp(dialstatus); 13100 if (dial) 13101 pbx_exec(chan, dial, ""); 13102 } 13103 return -1; 13104 } else if (priority != 1) 13105 return -1; 13106 13107 AST_LIST_LOCK(&dpcache); 13108 if ((dp = find_cache(chan, data, context, exten, priority))) { 13109 if (dp->flags & CACHE_FLAG_EXISTS) { 13110 ast_copy_string(odata, data, sizeof(odata)); 13111 ncontext = strchr(odata, '/'); 13112 if (ncontext) { 13113 *ncontext = '\0'; 13114 ncontext++; 13115 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13116 } else { 13117 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13118 } 13119 ast_verb(3, "Executing Dial('%s')\n", req); 13120 } else { 13121 AST_LIST_UNLOCK(&dpcache); 13122 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13123 return -1; 13124 } 13125 } 13126 AST_LIST_UNLOCK(&dpcache); 13127 13128 if ((dial = pbx_findapp("Dial"))) 13129 return pbx_exec(chan, dial, req); 13130 else 13131 ast_log(LOG_WARNING, "No dial application registered\n"); 13132 13133 return -1; 13134 }
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 13016 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, chan, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13017 { 13018 int res = 0; 13019 struct iax2_dpcache *dp = NULL; 13020 #if 0 13021 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13022 #endif 13023 if ((priority != 1) && (priority != 2)) 13024 return 0; 13025 13026 AST_LIST_LOCK(&dpcache); 13027 if ((dp = find_cache(chan, data, context, exten, priority))) { 13028 if (dp->flags & CACHE_FLAG_EXISTS) 13029 res = 1; 13030 } else { 13031 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13032 } 13033 AST_LIST_UNLOCK(&dpcache); 13034 13035 return res; 13036 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3996 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
03997 { 03998 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 03999 ast_mutex_lock(&iaxsl[callno]); 04000 if (iaxs[callno]) 04001 iaxs[callno]->owner = newchan; 04002 else 04003 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04004 ast_mutex_unlock(&iaxsl[callno]); 04005 return 0; 04006 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1555 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01556 { 01557 AST_SCHED_DEL(sched, fr->retrans); 01558 iax_frame_free(fr); 01559 }
static void iax2_free_variable_datastore | ( | void * | ) | [static] |
Definition at line 1148 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.
01149 { 01150 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01151 struct ast_var_t *oldvar; 01152 01153 AST_LIST_LOCK(oldlist); 01154 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01155 ast_free(oldvar); 01156 } 01157 AST_LIST_UNLOCK(oldlist); 01158 AST_LIST_HEAD_DESTROY(oldlist); 01159 ast_free(oldlist); 01160 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1495 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(), peers, and realtime_peer().
Referenced by __find_callno().
01496 { 01497 struct iax2_peer *peer = NULL; 01498 int res = 0; 01499 struct ao2_iterator i; 01500 01501 i = ao2_iterator_init(peers, 0); 01502 while ((peer = ao2_iterator_next(&i))) { 01503 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01504 (peer->addr.sin_port == sin.sin_port)) { 01505 ast_copy_string(host, peer->name, len); 01506 peer_unref(peer); 01507 res = 1; 01508 break; 01509 } 01510 peer_unref(peer); 01511 } 01512 ao2_iterator_destroy(&i); 01513 01514 if (!peer) { 01515 peer = realtime_peer(NULL, &sin); 01516 if (peer) { 01517 ast_copy_string(host, peer->name, len); 01518 peer_unref(peer); 01519 res = 1; 01520 } 01521 } 01522 01523 return res; 01524 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5286 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag, IAX_TRUNK, peer_unref(), and peers.
Referenced by check_access().
05287 { 05288 struct iax2_peer *peer; 05289 int res = 0; 05290 struct ao2_iterator i; 05291 05292 i = ao2_iterator_init(peers, 0); 05293 while ((peer = ao2_iterator_next(&i))) { 05294 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05295 (peer->addr.sin_port == sin.sin_port)) { 05296 res = ast_test_flag(peer, IAX_TRUNK); 05297 peer_unref(peer); 05298 break; 05299 } 05300 peer_unref(peer); 05301 } 05302 ao2_iterator_destroy(&i); 05303 05304 return res; 05305 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4866 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_test_flag, ast_verb, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, LOG_ERROR, LOG_WARNING, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
04867 { 04868 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04869 struct iax_ie_data ied; 04870 int alreadygone; 04871 memset(&ied, 0, sizeof(ied)); 04872 ast_mutex_lock(&iaxsl[callno]); 04873 if (callno && iaxs[callno]) { 04874 ast_debug(1, "We're hanging up %s now...\n", c->name); 04875 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04876 /* Send the hangup unless we have had a transmission error or are already gone */ 04877 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04878 if (!iaxs[callno]->error && !alreadygone) { 04879 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04880 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04881 } 04882 if (!iaxs[callno]) { 04883 ast_mutex_unlock(&iaxsl[callno]); 04884 return 0; 04885 } 04886 } 04887 /* Explicitly predestroy it */ 04888 iax2_predestroy(callno); 04889 /* If we were already gone to begin with, destroy us now */ 04890 if (iaxs[callno] && alreadygone) { 04891 ast_debug(1, "Really destroying %s now...\n", c->name); 04892 iax2_destroy(callno); 04893 } else if (iaxs[callno]) { 04894 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 04895 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 04896 iax2_destroy(callno); 04897 } 04898 } 04899 } else if (c->tech_pvt) { 04900 /* If this call no longer exists, but the channel still 04901 * references it we need to set the channel's tech_pvt to null 04902 * to avoid ast_channel_free() trying to free it. 04903 */ 04904 c->tech_pvt = NULL; 04905 } 04906 ast_mutex_unlock(&iaxsl[callno]); 04907 ast_verb(3, "Hungup '%s'\n", c->name); 04908 return 0; 04909 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5229 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(), iaxs, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05230 { 05231 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05232 struct chan_iax2_pvt *pvt; 05233 int res = 0; 05234 05235 if (iaxdebug) 05236 ast_debug(1, "Indicating condition %d\n", condition); 05237 05238 ast_mutex_lock(&iaxsl[callno]); 05239 pvt = iaxs[callno]; 05240 05241 if (wait_for_peercallno(pvt)) { 05242 res = -1; 05243 goto done; 05244 } 05245 05246 switch (condition) { 05247 case AST_CONTROL_HOLD: 05248 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05249 ast_moh_start(c, data, pvt->mohinterpret); 05250 goto done; 05251 } 05252 break; 05253 case AST_CONTROL_UNHOLD: 05254 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05255 ast_moh_stop(c); 05256 goto done; 05257 } 05258 } 05259 05260 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05261 05262 done: 05263 ast_mutex_unlock(&iaxsl[callno]); 05264 05265 return res; 05266 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 4981 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_sched_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, chan_iax2_pvt::keyrotateid, md5(), MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, sched, and send_command().
Referenced by iax2_send().
04982 { 04983 int res = 0; 04984 struct chan_iax2_pvt *pvt = (void *) vpvt; 04985 struct MD5Context md5; 04986 char key[17] = ""; 04987 struct iax_ie_data ied = { 04988 .pos = 0, 04989 }; 04990 04991 ast_mutex_lock(&iaxsl[pvt->callno]); 04992 pvt->keyrotateid = 04993 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 04994 04995 snprintf(key, sizeof(key), "%lX", ast_random()); 04996 04997 MD5Init(&md5); 04998 MD5Update(&md5, (unsigned char *) key, strlen(key)); 04999 MD5Final((unsigned char *) key, &md5); 05000 05001 IAX_DEBUGDIGEST("Sending", key); 05002 05003 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05004 05005 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05006 05007 build_ecx_key((unsigned char *) key, pvt); 05008 05009 ast_mutex_unlock(&iaxsl[pvt->callno]); 05010 05011 return res; 05012 }
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 13062 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, chan, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13063 { 13064 int res = 0; 13065 struct iax2_dpcache *dp = NULL; 13066 #if 0 13067 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13068 #endif 13069 if ((priority != 1) && (priority != 2)) 13070 return 0; 13071 13072 AST_LIST_LOCK(&dpcache); 13073 if ((dp = find_cache(chan, data, context, exten, priority))) { 13074 if (dp->flags & CACHE_FLAG_MATCHMORE) 13075 res = 1; 13076 } else { 13077 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13078 } 13079 AST_LIST_UNLOCK(&dpcache); 13080 13081 return res; 13082 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11296 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11297 { 11298 struct iax2_peer *peer = (struct iax2_peer *)data; 11299 peer->pokeexpire = -1; 11300 #ifdef SCHED_MULTITHREADED 11301 if (schedule_action(__iax2_poke_noanswer, data)) 11302 #endif 11303 __iax2_poke_noanswer(data); 11304 peer_unref(peer); 11305 return 0; 11306 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 11317 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
11318 { 11319 int callno; 11320 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 11321 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11322 immediately after clearing things out */ 11323 peer->lastms = 0; 11324 peer->historicms = 0; 11325 peer->pokeexpire = -1; 11326 peer->callno = 0; 11327 return 0; 11328 } 11329 11330 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 11331 if ((callno = peer->callno) > 0) { 11332 ast_log(LOG_NOTICE, "Still have a callno...\n"); 11333 ast_mutex_lock(&iaxsl[callno]); 11334 iax2_destroy(callno); 11335 ast_mutex_unlock(&iaxsl[callno]); 11336 } 11337 if (heldcall) 11338 ast_mutex_unlock(&iaxsl[heldcall]); 11339 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 11340 if (heldcall) 11341 ast_mutex_lock(&iaxsl[heldcall]); 11342 if (peer->callno < 1) { 11343 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 11344 return -1; 11345 } 11346 11347 /* Speed up retransmission times for this qualify call */ 11348 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 11349 iaxs[peer->callno]->peerpoke = peer; 11350 11351 if (peer->pokeexpire > -1) { 11352 if (!ast_sched_del(sched, peer->pokeexpire)) { 11353 peer->pokeexpire = -1; 11354 peer_unref(peer); 11355 } 11356 } 11357 11358 /* Queue up a new task to handle no reply */ 11359 /* If the host is already unreachable then use the unreachable interval instead */ 11360 if (peer->lastms < 0) 11361 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 11362 else 11363 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 11364 11365 if (peer->pokeexpire == -1) 11366 peer_unref(peer); 11367 11368 /* And send the poke */ 11369 ast_mutex_lock(&iaxsl[callno]); 11370 if (iaxs[callno]) { 11371 struct iax_ie_data ied = { 11372 .buf = { 0 }, 11373 .pos = 0, 11374 }; 11375 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11376 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 11377 } 11378 ast_mutex_unlock(&iaxsl[callno]); 11379 11380 return 0; 11381 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11308 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11309 { 11310 struct iax2_peer *peer = obj; 11311 11312 iax2_poke_peer(peer, 0); 11313 11314 return 0; 11315 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8559 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
08560 { 08561 struct iax2_peer *peer = (struct iax2_peer *)data; 08562 peer->pokeexpire = -1; 08563 #ifdef SCHED_MULTITHREADED 08564 if (schedule_action(__iax2_poke_peer_s, data)) 08565 #endif 08566 __iax2_poke_peer_s(data); 08567 return 0; 08568 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3106 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag, ast_test_flag, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03107 { 03108 struct ast_channel *c = NULL; 03109 struct chan_iax2_pvt *pvt = iaxs[callno]; 03110 03111 if (!pvt) 03112 return -1; 03113 03114 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 03115 iax2_destroy_helper(pvt); 03116 ast_set_flag(pvt, IAX_ALREADYGONE); 03117 } 03118 03119 if ((c = pvt->owner)) { 03120 c->tech_pvt = NULL; 03121 iax2_queue_hangup(callno); 03122 pvt->owner = NULL; 03123 ast_module_unref(ast_module_info->self); 03124 } 03125 03126 return 0; 03127 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 10963 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), signal_condition(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
10964 { 10965 struct iax2_thread *thread = data; 10966 struct timeval wait; 10967 struct timespec ts; 10968 int put_into_idle = 0; 10969 int first_time = 1; 10970 10971 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 10972 pthread_cleanup_push(iax2_process_thread_cleanup, data); 10973 for(;;) { 10974 /* Wait for something to signal us to be awake */ 10975 ast_mutex_lock(&thread->lock); 10976 10977 /* Flag that we're ready to accept signals */ 10978 if (first_time) { 10979 signal_condition(&thread->init_lock, &thread->init_cond); 10980 first_time = 0; 10981 } 10982 10983 /* Put into idle list if applicable */ 10984 if (put_into_idle) 10985 insert_idle_thread(thread); 10986 10987 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 10988 struct iax2_thread *t = NULL; 10989 /* Wait to be signalled or time out */ 10990 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 10991 ts.tv_sec = wait.tv_sec; 10992 ts.tv_nsec = wait.tv_usec * 1000; 10993 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 10994 /* This thread was never put back into the available dynamic 10995 * thread list, so just go away. */ 10996 if (!put_into_idle) { 10997 ast_mutex_unlock(&thread->lock); 10998 break; 10999 } 11000 AST_LIST_LOCK(&dynamic_list); 11001 /* Account for the case where this thread is acquired *right* after a timeout */ 11002 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11003 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11004 AST_LIST_UNLOCK(&dynamic_list); 11005 if (t) { 11006 /* This dynamic thread timed out waiting for a task and was 11007 * not acquired immediately after the timeout, 11008 * so it's time to go away. */ 11009 ast_mutex_unlock(&thread->lock); 11010 break; 11011 } 11012 /* Someone grabbed our thread *right* after we timed out. 11013 * Wait for them to set us up with something to do and signal 11014 * us to continue. */ 11015 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11016 ts.tv_sec = wait.tv_sec; 11017 ts.tv_nsec = wait.tv_usec * 1000; 11018 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 11019 { 11020 ast_mutex_unlock(&thread->lock); 11021 break; 11022 } 11023 } 11024 } else { 11025 ast_cond_wait(&thread->cond, &thread->lock); 11026 } 11027 11028 /* Go back into our respective list */ 11029 put_into_idle = 1; 11030 11031 ast_mutex_unlock(&thread->lock); 11032 11033 if (thread->iostate == IAX_IOSTATE_IDLE) 11034 continue; 11035 11036 /* Add ourselves to the active list now */ 11037 AST_LIST_LOCK(&active_list); 11038 AST_LIST_INSERT_HEAD(&active_list, thread, list); 11039 AST_LIST_UNLOCK(&active_list); 11040 11041 /* See what we need to do */ 11042 switch(thread->iostate) { 11043 case IAX_IOSTATE_READY: 11044 thread->actions++; 11045 thread->iostate = IAX_IOSTATE_PROCESSING; 11046 socket_process(thread); 11047 handle_deferred_full_frames(thread); 11048 break; 11049 case IAX_IOSTATE_SCHEDREADY: 11050 thread->actions++; 11051 thread->iostate = IAX_IOSTATE_PROCESSING; 11052 #ifdef SCHED_MULTITHREADED 11053 thread->schedfunc(thread->scheddata); 11054 #endif 11055 default: 11056 break; 11057 } 11058 time(&thread->checktime); 11059 thread->iostate = IAX_IOSTATE_IDLE; 11060 #ifdef DEBUG_SCHED_MULTITHREAD 11061 thread->curfunc[0]='\0'; 11062 #endif 11063 11064 /* Now... remove ourselves from the active list, and return to the idle list */ 11065 AST_LIST_LOCK(&active_list); 11066 AST_LIST_REMOVE(&active_list, thread, list); 11067 AST_LIST_UNLOCK(&active_list); 11068 11069 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11070 handle_deferred_full_frames(thread); 11071 } 11072 11073 /*!\note For some reason, idle threads are exiting without being removed 11074 * from an idle list, which is causing memory corruption. Forcibly remove 11075 * it from the list, if it's there. 11076 */ 11077 AST_LIST_LOCK(&idle_list); 11078 AST_LIST_REMOVE(&idle_list, thread, list); 11079 AST_LIST_UNLOCK(&idle_list); 11080 11081 AST_LIST_LOCK(&dynamic_list); 11082 AST_LIST_REMOVE(&dynamic_list, thread, list); 11083 AST_LIST_UNLOCK(&dynamic_list); 11084 11085 /* I am exiting here on my own volition, I need to clean up my own data structures 11086 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11087 */ 11088 pthread_cleanup_pop(1); 11089 return NULL; 11090 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 10952 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy(), ast_free, ast_mutex_destroy(), iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
10953 { 10954 struct iax2_thread *thread = data; 10955 ast_mutex_destroy(&thread->lock); 10956 ast_cond_destroy(&thread->cond); 10957 ast_mutex_destroy(&thread->init_lock); 10958 ast_cond_destroy(&thread->init_cond); 10959 ast_free(thread); 10960 ast_atomic_dec_and_test(&iaxactivethreadcount); 10961 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11148 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(), iaxs, NEW_FORCE, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
11149 { 11150 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11151 is found for template */ 11152 struct iax_ie_data provdata; 11153 struct iax_ie_data ied; 11154 unsigned int sig; 11155 struct sockaddr_in sin; 11156 int callno; 11157 struct create_addr_info cai; 11158 11159 memset(&cai, 0, sizeof(cai)); 11160 11161 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11162 11163 if (iax_provision_build(&provdata, &sig, template, force)) { 11164 ast_debug(1, "No provisioning found for template '%s'\n", template); 11165 return 0; 11166 } 11167 11168 if (end) { 11169 memcpy(&sin, end, sizeof(sin)); 11170 cai.sockfd = sockfd; 11171 } else if (create_addr(dest, NULL, &sin, &cai)) 11172 return -1; 11173 11174 /* Build the rest of the message */ 11175 memset(&ied, 0, sizeof(ied)); 11176 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11177 11178 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11179 if (!callno) 11180 return -1; 11181 11182 if (iaxs[callno]) { 11183 /* Schedule autodestruct in case they don't ever give us anything back */ 11184 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11185 sched, 15000, auto_hangup, (void *)(long)callno); 11186 ast_set_flag(iaxs[callno], IAX_PROVISION); 11187 /* Got a call number now, so go ahead and send the provisioning information */ 11188 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11189 } 11190 ast_mutex_unlock(&iaxsl[callno]); 11191 11192 return 1; 11193 }
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 2731 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::owner.
Referenced by socket_process().
02733 { 02734 for (;;) { 02735 if (iaxs[callno] && iaxs[callno]->owner) { 02736 if (ast_channel_trylock(iaxs[callno]->owner)) { 02737 /* Avoid deadlock by pausing and trying again */ 02738 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02739 } else { 02740 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02741 ast_channel_unlock(iaxs[callno]->owner); 02742 break; 02743 } 02744 } else 02745 break; 02746 } 02747 return 0; 02748 }
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 2669 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxs, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02670 { 02671 for (;;) { 02672 if (iaxs[callno] && iaxs[callno]->owner) { 02673 if (ast_channel_trylock(iaxs[callno]->owner)) { 02674 /* Avoid deadlock by pausing and trying again */ 02675 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02676 } else { 02677 ast_queue_frame(iaxs[callno]->owner, f); 02678 ast_channel_unlock(iaxs[callno]->owner); 02679 break; 02680 } 02681 } else 02682 break; 02683 } 02684 return 0; 02685 }
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 2700 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02701 { 02702 for (;;) { 02703 if (iaxs[callno] && iaxs[callno]->owner) { 02704 if (ast_channel_trylock(iaxs[callno]->owner)) { 02705 /* Avoid deadlock by pausing and trying again */ 02706 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02707 } else { 02708 ast_queue_hangup(iaxs[callno]->owner); 02709 ast_channel_unlock(iaxs[callno]->owner); 02710 break; 02711 } 02712 } else 02713 break; 02714 } 02715 return 0; 02716 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4975 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
04976 { 04977 ast_log(LOG_NOTICE, "I should never be called!\n"); 04978 return &ast_null_frame; 04979 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8014 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, secret, and strsep().
Referenced by set_config().
08015 { 08016 char copy[256]; 08017 char *username, *hostname, *secret; 08018 char *porta; 08019 char *stringp=NULL; 08020 08021 if (!value) 08022 return -1; 08023 08024 ast_copy_string(copy, value, sizeof(copy)); 08025 stringp = copy; 08026 username = strsep(&stringp, "@"); 08027 hostname = strsep(&stringp, "@"); 08028 08029 if (!hostname) { 08030 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08031 return -1; 08032 } 08033 08034 stringp = username; 08035 username = strsep(&stringp, ":"); 08036 secret = strsep(&stringp, ":"); 08037 stringp = hostname; 08038 hostname = strsep(&stringp, ":"); 08039 porta = strsep(&stringp, ":"); 08040 08041 if (porta && !atoi(porta)) { 08042 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08043 return -1; 08044 } 08045 08046 return iax2_append_register(hostname, username, secret, porta); 08047 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 11393 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.
11394 { 11395 int callno; 11396 int res; 11397 int fmt, native; 11398 struct sockaddr_in sin; 11399 struct ast_channel *c; 11400 struct parsed_dial_string pds; 11401 struct create_addr_info cai; 11402 char *tmpstr; 11403 11404 memset(&pds, 0, sizeof(pds)); 11405 tmpstr = ast_strdupa(data); 11406 parse_dial_string(tmpstr, &pds); 11407 11408 if (ast_strlen_zero(pds.peer)) { 11409 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 11410 return NULL; 11411 } 11412 11413 memset(&cai, 0, sizeof(cai)); 11414 cai.capability = iax2_capability; 11415 11416 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11417 11418 /* Populate our address from the given */ 11419 if (create_addr(pds.peer, NULL, &sin, &cai)) { 11420 *cause = AST_CAUSE_UNREGISTERED; 11421 return NULL; 11422 } 11423 11424 if (pds.port) 11425 sin.sin_port = htons(atoi(pds.port)); 11426 11427 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11428 if (callno < 1) { 11429 ast_log(LOG_WARNING, "Unable to create call\n"); 11430 *cause = AST_CAUSE_CONGESTION; 11431 return NULL; 11432 } 11433 11434 /* If this is a trunk, update it now */ 11435 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11436 if (ast_test_flag(&cai, IAX_TRUNK)) { 11437 int new_callno; 11438 if ((new_callno = make_trunk(callno, 1)) != -1) 11439 callno = new_callno; 11440 } 11441 iaxs[callno]->maxtime = cai.maxtime; 11442 if (cai.found) 11443 ast_string_field_set(iaxs[callno], host, pds.peer); 11444 11445 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 11446 11447 ast_mutex_unlock(&iaxsl[callno]); 11448 11449 if (c) { 11450 /* Choose a format we can live with */ 11451 if (c->nativeformats & format) 11452 c->nativeformats &= format; 11453 else { 11454 native = c->nativeformats; 11455 fmt = format; 11456 res = ast_translator_best_choice(&fmt, &native); 11457 if (res < 0) { 11458 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 11459 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 11460 ast_hangup(c); 11461 return NULL; 11462 } 11463 c->nativeformats = native; 11464 } 11465 c->readformat = ast_best_codec(c->nativeformats); 11466 c->writeformat = c->readformat; 11467 } 11468 11469 return c; 11470 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1281 of file chan_iax2.c.
References ast_sched_add(), sched_lock, and signal_condition().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_thread(), reg_source_db(), sched_delay_remove(), socket_process(), and update_registry().
01282 { 01283 int res; 01284 01285 res = ast_sched_add(con, when, callback, data); 01286 signal_condition(&sched_lock, &sched_cond); 01287 01288 return res; 01289 }
static int iax2_sched_replace | ( | int | id, | |
struct sched_context * | con, | |||
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1273 of file chan_iax2.c.
References AST_SCHED_REPLACE, sched_lock, and signal_condition().
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01274 { 01275 AST_SCHED_REPLACE(id, con, when, callback, data); 01276 signal_condition(&sched_lock, &sched_cond); 01277 01278 return id; 01279 }
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 5938 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_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, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
05939 { 05940 /* Queue a packet for delivery on a given private structure. Use "ts" for 05941 timestamp, or calculate if ts is 0. Send immediately without retransmission 05942 or delayed, with retransmission */ 05943 struct ast_iax2_full_hdr *fh; 05944 struct ast_iax2_mini_hdr *mh; 05945 struct ast_iax2_video_hdr *vh; 05946 struct { 05947 struct iax_frame fr2; 05948 unsigned char buffer[4096]; 05949 } frb; 05950 struct iax_frame *fr; 05951 int res; 05952 int sendmini=0; 05953 unsigned int lastsent; 05954 unsigned int fts; 05955 05956 frb.fr2.afdatalen = sizeof(frb.buffer); 05957 05958 if (!pvt) { 05959 ast_log(LOG_WARNING, "No private structure for packet?\n"); 05960 return -1; 05961 } 05962 05963 lastsent = pvt->lastsent; 05964 05965 /* Calculate actual timestamp */ 05966 fts = calc_timestamp(pvt, ts, f); 05967 05968 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 05969 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 05970 * increment the "predicted timestamps" for voice, if we're predicting */ 05971 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 05972 return 0; 05973 #if 0 05974 ast_log(LOG_NOTICE, 05975 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 05976 *("=!" + (f->frametype == AST_FRAME_VOICE)), 05977 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 05978 pvt->keyrotateid != -1 ? "" : "no " 05979 ); 05980 #endif 05981 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 05982 iax2_key_rotate(pvt); 05983 } 05984 05985 if ((ast_test_flag(pvt, IAX_TRUNK) || 05986 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 05987 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 05988 /* High two bytes are the same on timestamp, or sending on a trunk */ && 05989 (f->frametype == AST_FRAME_VOICE) 05990 /* is a voice frame */ && 05991 (f->subclass == pvt->svoiceformat) 05992 /* is the same type */ ) { 05993 /* Force immediate rather than delayed transmission */ 05994 now = 1; 05995 /* Mark that mini-style frame is appropriate */ 05996 sendmini = 1; 05997 } 05998 if ( f->frametype == AST_FRAME_VIDEO ) { 05999 /* 06000 * If the lower 15 bits of the timestamp roll over, or if 06001 * the video format changed then send a full frame. 06002 * Otherwise send a mini video frame 06003 */ 06004 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06005 ((f->subclass & ~0x1) == pvt->svideoformat) 06006 ) { 06007 now = 1; 06008 sendmini = 1; 06009 } else { 06010 now = 0; 06011 sendmini = 0; 06012 } 06013 pvt->lastvsent = fts; 06014 } 06015 if (f->frametype == AST_FRAME_IAX) { 06016 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06017 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 06018 if (!pvt->first_iax_message) { 06019 pvt->first_iax_message = pvt->last_iax_message; 06020 } 06021 } 06022 /* Allocate an iax_frame */ 06023 if (now) { 06024 fr = &frb.fr2; 06025 } else 06026 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)); 06027 if (!fr) { 06028 ast_log(LOG_WARNING, "Out of memory\n"); 06029 return -1; 06030 } 06031 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06032 iax_frame_wrap(fr, f); 06033 06034 fr->ts = fts; 06035 fr->callno = pvt->callno; 06036 fr->transfer = transfer; 06037 fr->final = final; 06038 fr->encmethods = 0; 06039 if (!sendmini) { 06040 /* We need a full frame */ 06041 if (seqno > -1) 06042 fr->oseqno = seqno; 06043 else 06044 fr->oseqno = pvt->oseqno++; 06045 fr->iseqno = pvt->iseqno; 06046 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06047 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06048 fh->ts = htonl(fr->ts); 06049 fh->oseqno = fr->oseqno; 06050 if (transfer) { 06051 fh->iseqno = 0; 06052 } else 06053 fh->iseqno = fr->iseqno; 06054 /* Keep track of the last thing we've acknowledged */ 06055 if (!transfer) 06056 pvt->aseqno = fr->iseqno; 06057 fh->type = fr->af.frametype & 0xFF; 06058 if (fr->af.frametype == AST_FRAME_VIDEO) 06059 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 06060 else 06061 fh->csub = compress_subclass(fr->af.subclass); 06062 if (transfer) { 06063 fr->dcallno = pvt->transfercallno; 06064 } else 06065 fr->dcallno = pvt->peercallno; 06066 fh->dcallno = htons(fr->dcallno); 06067 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06068 fr->data = fh; 06069 fr->retries = 0; 06070 /* Retry after 2x the ping time has passed */ 06071 fr->retrytime = pvt->pingtime * 2; 06072 if (fr->retrytime < MIN_RETRY_TIME) 06073 fr->retrytime = MIN_RETRY_TIME; 06074 if (fr->retrytime > MAX_RETRY_TIME) 06075 fr->retrytime = MAX_RETRY_TIME; 06076 /* Acks' don't get retried */ 06077 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 06078 fr->retries = -1; 06079 else if (f->frametype == AST_FRAME_VOICE) 06080 pvt->svoiceformat = f->subclass; 06081 else if (f->frametype == AST_FRAME_VIDEO) 06082 pvt->svideoformat = f->subclass & ~0x1; 06083 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06084 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06085 if (fr->transfer) 06086 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06087 else 06088 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06089 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06090 fr->encmethods = pvt->encmethods; 06091 fr->ecx = pvt->ecx; 06092 fr->mydcx = pvt->mydcx; 06093 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06094 } else 06095 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06096 } 06097 06098 if (now) { 06099 res = send_packet(fr); 06100 } else 06101 res = iax2_transmit(fr); 06102 } else { 06103 if (ast_test_flag(pvt, IAX_TRUNK)) { 06104 iax2_trunk_queue(pvt, fr); 06105 res = 0; 06106 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06107 /* Video frame have no sequence number */ 06108 fr->oseqno = -1; 06109 fr->iseqno = -1; 06110 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06111 vh->zeros = 0; 06112 vh->callno = htons(0x8000 | fr->callno); 06113 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 06114 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06115 fr->data = vh; 06116 fr->retries = -1; 06117 res = send_packet(fr); 06118 } else { 06119 /* Mini-frames have no sequence number */ 06120 fr->oseqno = -1; 06121 fr->iseqno = -1; 06122 /* Mini frame will do */ 06123 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06124 mh->callno = htons(fr->callno); 06125 mh->ts = htons(fr->ts & 0xFFFF); 06126 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06127 fr->data = mh; 06128 fr->retries = -1; 06129 if (pvt->transferring == TRANSFER_MEDIAPASS) 06130 fr->transfer = 1; 06131 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06132 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06133 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06134 } else 06135 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06136 } 06137 res = send_packet(fr); 06138 } 06139 } 06140 return res; 06141 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3991 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03992 { 03993 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 03994 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 3986 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.
03987 { 03988 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1); 03989 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 3979 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03980 { 03981 03982 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 03983 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 03984 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4933 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, iaxs, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
04934 { 04935 struct ast_option_header *h; 04936 int res; 04937 04938 switch (option) { 04939 case AST_OPTION_TXGAIN: 04940 case AST_OPTION_RXGAIN: 04941 /* these two cannot be sent, because they require a result */ 04942 errno = ENOSYS; 04943 return -1; 04944 default: 04945 { 04946 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04947 struct chan_iax2_pvt *pvt; 04948 04949 ast_mutex_lock(&iaxsl[callno]); 04950 pvt = iaxs[callno]; 04951 04952 if (wait_for_peercallno(pvt)) { 04953 ast_mutex_unlock(&iaxsl[callno]); 04954 return -1; 04955 } 04956 04957 ast_mutex_unlock(&iaxsl[callno]); 04958 04959 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 04960 return -1; 04961 } 04962 04963 h->flag = AST_OPTION_FLAG_REQUEST; 04964 h->option = htons(option); 04965 memcpy(h->data, data, datalen); 04966 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 04967 AST_CONTROL_OPTION, 0, (unsigned char *) h, 04968 datalen + sizeof(*h), -1); 04969 ast_free(h); 04970 return res; 04971 } 04972 } 04973 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5014 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
05015 { 05016 int res; 05017 struct iax_ie_data ied0; 05018 struct iax_ie_data ied1; 05019 unsigned int transferid = (unsigned int)ast_random(); 05020 05021 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05022 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05023 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER); 05024 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER); 05025 return 0; 05026 } 05027 05028 memset(&ied0, 0, sizeof(ied0)); 05029 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05030 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05031 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05032 05033 memset(&ied1, 0, sizeof(ied1)); 05034 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05035 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05036 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05037 05038 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05039 if (res) 05040 return -1; 05041 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05042 if (res) 05043 return -1; 05044 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05045 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05046 return 0; 05047 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5268 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_FRAME_IAX, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05269 { 05270 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05271 struct iax_ie_data ied = { "", }; 05272 char tmp[256], *context; 05273 ast_copy_string(tmp, dest, sizeof(tmp)); 05274 context = strchr(tmp, '@'); 05275 if (context) { 05276 *context = '\0'; 05277 context++; 05278 } 05279 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05280 if (context) 05281 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05282 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05283 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05284 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3951 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iax2_trunk_peer::list, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
03952 { 03953 /* Lock the queue and place this packet at the end */ 03954 /* By setting this to 0, the network thread will send it for us, and 03955 queue retransmission if necessary */ 03956 fr->sentyet = 0; 03957 AST_LIST_LOCK(&frame_queue); 03958 AST_LIST_INSERT_TAIL(&frame_queue, fr, list); 03959 AST_LIST_UNLOCK(&frame_queue); 03960 /* Wake up the network and scheduler thread */ 03961 if (netthreadid != AST_PTHREADT_NULL) 03962 pthread_kill(netthreadid, SIGURG); 03963 signal_condition(&sched_lock, &sched_cond); 03964 return 0; 03965 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 8613 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
08614 { 08615 /* Drop when trunk is about 5 seconds idle */ 08616 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 08617 return 1; 08618 return 0; 08619 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 5677 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, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
05678 { 05679 struct ast_frame *f; 05680 struct iax2_trunk_peer *tpeer; 05681 void *tmp, *ptr; 05682 struct timeval now; 05683 int res; 05684 struct ast_iax2_meta_trunk_entry *met; 05685 struct ast_iax2_meta_trunk_mini *mtm; 05686 05687 f = &fr->af; 05688 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05689 if (tpeer) { 05690 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05691 /* Need to reallocate space */ 05692 if (tpeer->trunkdataalloc < trunkmaxsize) { 05693 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05694 ast_mutex_unlock(&tpeer->lock); 05695 return -1; 05696 } 05697 05698 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05699 tpeer->trunkdata = tmp; 05700 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); 05701 } else { 05702 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)); 05703 ast_mutex_unlock(&tpeer->lock); 05704 return -1; 05705 } 05706 } 05707 05708 /* Append to meta frame */ 05709 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05710 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05711 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05712 mtm->len = htons(f->datalen); 05713 mtm->mini.callno = htons(pvt->callno); 05714 mtm->mini.ts = htons(0xffff & fr->ts); 05715 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05716 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05717 } else { 05718 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05719 /* Store call number and length in meta header */ 05720 met->callno = htons(pvt->callno); 05721 met->len = htons(f->datalen); 05722 /* Advance pointers/decrease length past trunk entry header */ 05723 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05724 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05725 } 05726 /* Copy actual trunk data */ 05727 memcpy(ptr, f->data.ptr, f->datalen); 05728 tpeer->trunkdatalen += f->datalen; 05729 05730 tpeer->calls++; 05731 05732 /* track the largest mtu we actually have sent */ 05733 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 05734 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 05735 05736 /* if we have enough for a full MTU, ship it now without waiting */ 05737 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 05738 now = ast_tvnow(); 05739 res = send_trunk(tpeer, &now); 05740 trunk_untimed ++; 05741 } 05742 05743 ast_mutex_unlock(&tpeer->lock); 05744 } 05745 return 0; 05746 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 8531 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
08532 { 08533 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 08534 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 6939 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, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, PTR_TO_CALLNO, and ast_channel::tech_pvt.
06940 { 06941 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 06942 int res = -1; 06943 ast_mutex_lock(&iaxsl[callno]); 06944 if (iaxs[callno]) { 06945 /* If there's an outstanding error, return failure now */ 06946 if (!iaxs[callno]->error) { 06947 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 06948 res = 0; 06949 /* Don't waste bandwidth sending null frames */ 06950 else if (f->frametype == AST_FRAME_NULL) 06951 res = 0; 06952 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 06953 res = 0; 06954 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 06955 res = 0; 06956 else 06957 /* Simple, just queue for transmission */ 06958 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 06959 } else { 06960 ast_debug(1, "Write error: %s\n", strerror(errno)); 06961 } 06962 } 06963 /* If it's already gone, just return */ 06964 ast_mutex_unlock(&iaxsl[callno]); 06965 return res; 06966 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2898 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, iax2_trunk_peer::list, and ast_iax2_firmware_header::version.
Referenced by update_registry().
02899 { 02900 int res = 0; 02901 struct iax_firmware *cur = NULL; 02902 02903 if (ast_strlen_zero(dev)) 02904 return 0; 02905 02906 AST_LIST_LOCK(&firmwares); 02907 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02908 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02909 res = ntohs(cur->fwh->version); 02910 break; 02911 } 02912 } 02913 AST_LIST_UNLOCK(&firmwares); 02914 02915 return res; 02916 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 979 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
00980 { 00981 if (iaxdebug) 00982 ast_verbose("%s", data); 00983 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 985 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00986 { 00987 ast_log(LOG_WARNING, "%s", data); 00988 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 2918 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, and iax2_trunk_peer::list.
Referenced by socket_process().
02919 { 02920 int res = -1; 02921 unsigned int bs = desc & 0xff; 02922 unsigned int start = (desc >> 8) & 0xffffff; 02923 unsigned int bytes; 02924 struct iax_firmware *cur; 02925 02926 if (ast_strlen_zero((char *)dev) || !bs) 02927 return -1; 02928 02929 start *= bs; 02930 02931 AST_LIST_LOCK(&firmwares); 02932 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02933 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 02934 continue; 02935 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02936 if (start < ntohl(cur->fwh->datalen)) { 02937 bytes = ntohl(cur->fwh->datalen) - start; 02938 if (bytes > bs) 02939 bytes = bs; 02940 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02941 } else { 02942 bytes = 0; 02943 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02944 } 02945 if (bytes == bs) 02946 res = 0; 02947 else 02948 res = 1; 02949 break; 02950 } 02951 AST_LIST_UNLOCK(&firmwares); 02952 02953 return res; 02954 }
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 962 of file chan_iax2.c.
References debugaddr, f, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
00963 { 00964 if (iaxdebug || 00965 (sin && debugaddr.sin_addr.s_addr && 00966 (!ntohs(debugaddr.sin_port) || 00967 debugaddr.sin_port == sin->sin_port) && 00968 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 00969 if (iaxdebug) { 00970 iax_showframe(f, fhi, rx, sin, datalen); 00971 } else { 00972 iaxdebug = 1; 00973 iax_showframe(f, fhi, rx, sin, datalen); 00974 iaxdebug = 0; 00975 } 00976 } 00977 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 8775 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, iax_park_thread(), LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
08776 { 08777 struct iax_dual *d; 08778 struct ast_channel *chan1m, *chan2m; 08779 pthread_t th; 08780 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 08781 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 08782 if (chan2m && chan1m) { 08783 /* Make formats okay */ 08784 chan1m->readformat = chan1->readformat; 08785 chan1m->writeformat = chan1->writeformat; 08786 ast_channel_masquerade(chan1m, chan1); 08787 /* Setup the extensions and such */ 08788 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08789 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08790 chan1m->priority = chan1->priority; 08791 08792 /* We make a clone of the peer channel too, so we can play 08793 back the announcement */ 08794 /* Make formats okay */ 08795 chan2m->readformat = chan2->readformat; 08796 chan2m->writeformat = chan2->writeformat; 08797 ast_channel_masquerade(chan2m, chan2); 08798 /* Setup the extensions and such */ 08799 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08800 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08801 chan2m->priority = chan2->priority; 08802 if (ast_do_masquerade(chan2m)) { 08803 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08804 ast_hangup(chan2m); 08805 return -1; 08806 } 08807 } else { 08808 if (chan1m) 08809 ast_hangup(chan1m); 08810 if (chan2m) 08811 ast_hangup(chan2m); 08812 return -1; 08813 } 08814 if ((d = ast_calloc(1, sizeof(*d)))) { 08815 d->chan1 = chan1m; 08816 d->chan2 = chan2m; 08817 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) { 08818 return 0; 08819 } 08820 ast_free(d); 08821 } 08822 return -1; 08823 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 8755 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().
08756 { 08757 struct ast_channel *chan1, *chan2; 08758 struct iax_dual *d; 08759 struct ast_frame *f; 08760 int ext; 08761 int res; 08762 d = stuff; 08763 chan1 = d->chan1; 08764 chan2 = d->chan2; 08765 ast_free(d); 08766 f = ast_read(chan1); 08767 if (f) 08768 ast_frfree(f); 08769 res = ast_park_call(chan1, chan2, 0, &ext); 08770 ast_hangup(chan2); 08771 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 08772 return NULL; 08773 }
Definition at line 1710 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().
01711 { 01712 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01713 if (new) { 01714 size_t afdatalen = new->afdatalen; 01715 memcpy(new, fr, sizeof(*new)); 01716 iax_frame_wrap(new, &fr->af); 01717 new->afdatalen = afdatalen; 01718 new->data = NULL; 01719 new->datalen = 0; 01720 new->direction = DIRECTION_INGRESS; 01721 new->retrans = -1; 01722 } 01723 return new; 01724 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1166 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, iax2_trunk_peer::list, and thread.
Referenced by iax2_process_thread().
01167 { 01168 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01169 AST_LIST_LOCK(&dynamic_list); 01170 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01171 AST_LIST_UNLOCK(&dynamic_list); 01172 } else { 01173 AST_LIST_LOCK(&idle_list); 01174 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01175 AST_LIST_UNLOCK(&idle_list); 01176 } 01177 01178 return; 01179 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1014 of file chan_iax2.c.
References ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01015 { 01016 va_list args; 01017 char buf[1024]; 01018 01019 va_start(args, fmt); 01020 vsnprintf(buf, sizeof(buf), fmt, args); 01021 va_end(args); 01022 01023 ast_verbose("%s", buf); 01024 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 990 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
00991 { 00992 va_list args; 00993 char buf[1024]; 00994 00995 va_start(args, fmt); 00996 vsnprintf(buf, sizeof(buf), fmt, args); 00997 va_end(args); 00998 00999 ast_log(LOG_ERROR, "%s", buf); 01000 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1002 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01003 { 01004 va_list args; 01005 char buf[1024]; 01006 01007 va_start(args, fmt); 01008 vsnprintf(buf, sizeof(buf), fmt, args); 01009 va_end(args); 01010 01011 ast_log(LOG_WARNING, "%s", buf); 01012 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 13641 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application, ast_register_switch(), ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, iax2_registry::entry, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxvar_function, io, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), netsock, outsock, papp, pdescrip, peer_set_sock_cb(), peers, psyn, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, sched_context_create(), sched_context_destroy(), SENTINEL, set_config(), start_network_thread(), and timer.
13642 { 13643 13644 static const char config[] = "iax.conf"; 13645 int x = 0; 13646 struct iax2_registry *reg = NULL; 13647 13648 if (load_objects()) { 13649 return AST_MODULE_LOAD_FAILURE; 13650 } 13651 13652 randomcalltokendata = ast_random(); 13653 ast_custom_function_register(&iaxpeer_function); 13654 ast_custom_function_register(&iaxvar_function); 13655 13656 iax_set_output(iax_debug_output); 13657 iax_set_error(iax_error_output); 13658 jb_setoutput(jb_error_output, jb_warning_output, NULL); 13659 13660 memset(iaxs, 0, sizeof(iaxs)); 13661 13662 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13663 ast_mutex_init(&iaxsl[x]); 13664 } 13665 13666 ast_cond_init(&sched_cond, NULL); 13667 13668 if (!(sched = sched_context_create())) { 13669 ast_log(LOG_ERROR, "Failed to create scheduler context\n"); 13670 return AST_MODULE_LOAD_FAILURE; 13671 } 13672 13673 if (!(io = io_context_create())) { 13674 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 13675 sched_context_destroy(sched); 13676 return AST_MODULE_LOAD_FAILURE; 13677 } 13678 13679 if (!(netsock = ast_netsock_list_alloc())) { 13680 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 13681 io_context_destroy(io); 13682 sched_context_destroy(sched); 13683 return AST_MODULE_LOAD_FAILURE; 13684 } 13685 ast_netsock_init(netsock); 13686 13687 outsock = ast_netsock_list_alloc(); 13688 if (!outsock) { 13689 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13690 io_context_destroy(io); 13691 sched_context_destroy(sched); 13692 return AST_MODULE_LOAD_FAILURE; 13693 } 13694 ast_netsock_init(outsock); 13695 13696 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 13697 13698 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 13699 13700 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" ); 13701 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" ); 13702 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" ); 13703 13704 if ((timer = ast_timer_open())) { 13705 ast_timer_set_rate(timer, trunkfreq); 13706 } 13707 13708 if (set_config(config, 0) == -1) { 13709 if (timer) { 13710 ast_timer_close(timer); 13711 } 13712 return AST_MODULE_LOAD_DECLINE; 13713 } 13714 13715 if (ast_channel_register(&iax2_tech)) { 13716 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 13717 __unload_module(); 13718 return AST_MODULE_LOAD_FAILURE; 13719 } 13720 13721 if (ast_register_switch(&iax2_switch)) 13722 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 13723 13724 if (start_network_thread()) { 13725 ast_log(LOG_ERROR, "Unable to start network thread\n"); 13726 __unload_module(); 13727 return AST_MODULE_LOAD_FAILURE; 13728 } else 13729 ast_verb(2, "IAX Ready and Listening\n"); 13730 13731 AST_LIST_LOCK(®istrations); 13732 AST_LIST_TRAVERSE(®istrations, reg, entry) 13733 iax2_do_register(reg); 13734 AST_LIST_UNLOCK(®istrations); 13735 13736 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 13737 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 13738 13739 13740 reload_firmware(0); 13741 iax_provision_reload(0); 13742 13743 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 13744 13745 return AST_MODULE_LOAD_SUCCESS; 13746 }
static int load_objects | ( | void | ) | [static] |
Definition at line 13582 of file chan_iax2.c.
References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, callno_limits, calltoken_ignores, create_callno_pools(), IAX_MAX_CALLS, iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.
Referenced by load_module().
13583 { 13584 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 13585 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 13586 13587 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 13588 goto container_fail; 13589 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 13590 goto container_fail; 13591 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 13592 goto container_fail; 13593 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 13594 goto container_fail; 13595 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 13596 goto container_fail; 13597 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13598 goto container_fail; 13599 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13600 goto container_fail; 13601 } else if (create_callno_pools()) { 13602 goto container_fail; 13603 } 13604 13605 return 0; 13606 13607 container_fail: 13608 if (peers) { 13609 ao2_ref(peers, -1); 13610 } 13611 if (users) { 13612 ao2_ref(users, -1); 13613 } 13614 if (iax_peercallno_pvts) { 13615 ao2_ref(iax_peercallno_pvts, -1); 13616 } 13617 if (iax_transfercallno_pvts) { 13618 ao2_ref(iax_transfercallno_pvts, -1); 13619 } 13620 if (peercnts) { 13621 ao2_ref(peercnts, -1); 13622 } 13623 if (callno_limits) { 13624 ao2_ref(callno_limits, -1); 13625 } 13626 if (calltoken_ignores) { 13627 ao2_ref(calltoken_ignores, -1); 13628 } 13629 if (callno_pool) { 13630 ao2_ref(callno_pool, -1); 13631 } 13632 if (callno_pool_trunk) { 13633 ao2_ref(callno_pool_trunk, -1); 13634 } 13635 return AST_MODULE_LOAD_FAILURE; 13636 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5049 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), and DEADLOCK_AVOIDANCE.
Referenced by iax2_bridge().
05050 { 05051 ast_mutex_lock(&iaxsl[callno0]); 05052 while (ast_mutex_trylock(&iaxsl[callno1])) { 05053 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05054 } 05055 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 8898 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, iaxs, 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().
08899 { 08900 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 08901 jb_info jbinfo; 08902 08903 ast_mutex_lock(&iaxsl[callno]); 08904 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 08905 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) { 08906 jb_getinfo(iaxs[callno]->jb, &jbinfo); 08907 localjitter = jbinfo.jitter; 08908 localdelay = jbinfo.current - jbinfo.min; 08909 locallost = jbinfo.frames_lost; 08910 locallosspct = jbinfo.losspct/1000; 08911 localdropped = jbinfo.frames_dropped; 08912 localooo = jbinfo.frames_ooo; 08913 localpackets = jbinfo.frames_in; 08914 } 08915 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", 08916 iaxs[callno]->owner->name, 08917 iaxs[callno]->pingtime, 08918 localjitter, 08919 localdelay, 08920 locallost, 08921 locallosspct, 08922 localdropped, 08923 localooo, 08924 localpackets, 08925 iaxs[callno]->remote_rr.jitter, 08926 iaxs[callno]->remote_rr.delay, 08927 iaxs[callno]->remote_rr.losscnt, 08928 iaxs[callno]->remote_rr.losspct/1000, 08929 iaxs[callno]->remote_rr.dropped, 08930 iaxs[callno]->remote_rr.ooo, 08931 iaxs[callno]->remote_rr.packets); 08932 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", 08933 iaxs[callno]->owner->name, 08934 iaxs[callno]->pingtime, 08935 localjitter, 08936 localdelay, 08937 locallost, 08938 locallosspct, 08939 localdropped, 08940 localooo, 08941 localpackets, 08942 iaxs[callno]->remote_rr.jitter, 08943 iaxs[callno]->remote_rr.delay, 08944 iaxs[callno]->remote_rr.losscnt, 08945 iaxs[callno]->remote_rr.losspct/1000, 08946 iaxs[callno]->remote_rr.dropped, 08947 iaxs[callno]->remote_rr.ooo, 08948 iaxs[callno]->remote_rr.packets); 08949 } 08950 ast_mutex_unlock(&iaxsl[callno]); 08951 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1790 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
01791 { 01792 int x; 01793 int res= 0; 01794 struct callno_entry *callno_entry; 01795 if (iaxs[callno]->oseqno) { 01796 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01797 return -1; 01798 } 01799 if (callno & TRUNK_CALL_START) { 01800 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01801 return -1; 01802 } 01803 01804 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01805 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01806 return -1; 01807 } 01808 01809 x = callno_entry->callno; 01810 ast_mutex_lock(&iaxsl[x]); 01811 01812 /*! 01813 * \note We delete these before switching the slot, because if 01814 * they fire in the meantime, they will generate a warning. 01815 */ 01816 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01817 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01818 iaxs[x] = iaxs[callno]; 01819 iaxs[x]->callno = x; 01820 01821 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01822 * before assigning the new one */ 01823 if (iaxs[x]->callno_entry) { 01824 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01825 } 01826 iaxs[x]->callno_entry = callno_entry; 01827 01828 iaxs[callno] = NULL; 01829 /* Update the two timers that should have been started */ 01830 iaxs[x]->pingid = iax2_sched_add(sched, 01831 ping_time * 1000, send_ping, (void *)(long)x); 01832 iaxs[x]->lagid = iax2_sched_add(sched, 01833 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01834 01835 if (locked) 01836 ast_mutex_unlock(&iaxsl[callno]); 01837 res = x; 01838 if (!locked) 01839 ast_mutex_unlock(&iaxsl[x]); 01840 01841 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 01842 /* We move this call from a non-trunked to a trunked call */ 01843 update_max_trunk(); 01844 update_max_nontrunk(); 01845 return res; 01846 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6508 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
06509 { 06510 ast_cli_netstats(s, -1, 0); 06511 astman_append(s, "\r\n"); 06512 return RESULT_SUCCESS; 06513 }
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 6560 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), IAX_DYNAMIC, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), peers, RESULT_SUCCESS, s, status, and iax2_peer::username.
Referenced by load_module().
06561 { 06562 struct iax2_peer *peer = NULL; 06563 int peer_count = 0; 06564 char nm[20]; 06565 char status[20]; 06566 const char *id = astman_get_header(m,"ActionID"); 06567 char idtext[256] = ""; 06568 struct ao2_iterator i; 06569 06570 if (!ast_strlen_zero(id)) 06571 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06572 06573 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06574 06575 06576 i = ao2_iterator_init(peers, 0); 06577 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) { 06578 06579 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06580 if (!ast_strlen_zero(peer->username)) { 06581 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 06582 } else { 06583 astman_append(s, "ObjectName: %s\r\n", peer->name); 06584 } 06585 astman_append(s, "ChanObjectType: peer\r\n"); 06586 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-"); 06587 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06588 astman_append(s, "Mask: %s\r\n", nm); 06589 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port)); 06590 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 06591 peer_status(peer, status, sizeof(status)); 06592 astman_append(s, "Status: %s\r\n\r\n", status); 06593 peer_count++; 06594 } 06595 ao2_iterator_destroy(&i); 06596 06597 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 06598 return RESULT_SUCCESS; 06599 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6547 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and s.
Referenced by load_module().
06548 { 06549 char *a[] = { "iax2", "show", "users" }; 06550 const char *id = astman_get_header(m,"ActionID"); 06551 char idtext[256] = ""; 06552 06553 if (!ast_strlen_zero(id)) 06554 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06555 astman_send_ack(s, m, "Peer status list will follow"); 06556 return __iax2_show_peers(1, -1, s, 3, a ); 06557 }
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 1739 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __ao2_callback(), __find_callno(), ast_parse_device_state(), check_blacklist(), find_command(), handle_updates(), lua_find_extension(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().
01740 { 01741 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01742 (cur->addr.sin_port == sin->sin_port)) { 01743 /* This is the main host */ 01744 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01745 (check_dcallno ? dcallno == cur->callno : 1) ) { 01746 /* That's us. Be sure we keep track of the peer call number */ 01747 return 1; 01748 } 01749 } 01750 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01751 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01752 /* We're transferring */ 01753 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01754 return 1; 01755 } 01756 return 0; 01757 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_decrypt_key * | dcx | |||
) | [static] |
Definition at line 5776 of file chan_iax2.c.
References ast_aes_decrypt, ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05777 { 05778 #if 0 05779 /* Debug with "fake encryption" */ 05780 int x; 05781 if (len % 16) 05782 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05783 for (x=0;x<len;x++) 05784 dst[x] = src[x] ^ 0xff; 05785 #else 05786 unsigned char lastblock[16] = { 0 }; 05787 int x; 05788 while(len > 0) { 05789 ast_aes_decrypt(src, dst, dcx); 05790 for (x=0;x<16;x++) 05791 dst[x] ^= lastblock[x]; 05792 memcpy(lastblock, src, sizeof(lastblock)); 05793 dst += 16; 05794 src += 16; 05795 len -= 16; 05796 } 05797 #endif 05798 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 5800 of file chan_iax2.c.
References ast_aes_encrypt, ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05801 { 05802 #if 0 05803 /* Debug with "fake encryption" */ 05804 int x; 05805 if (len % 16) 05806 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05807 for (x=0;x<len;x++) 05808 dst[x] = src[x] ^ 0xff; 05809 #else 05810 unsigned char curblock[16] = { 0 }; 05811 int x; 05812 while(len > 0) { 05813 for (x=0;x<16;x++) 05814 curblock[x] ^= src[x]; 05815 ast_aes_encrypt(curblock, dst, ecx); 05816 memcpy(curblock, dst, sizeof(curblock)); 05817 dst += 16; 05818 src += 16; 05819 len -= 16; 05820 } 05821 #endif 05822 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7283 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().
07284 { 07285 /* Select exactly one common encryption if there are any */ 07286 p->encmethods &= enc; 07287 if (p->encmethods) { 07288 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07289 p->keyrotateid = -2; 07290 } 07291 if (p->encmethods & IAX_ENCRYPT_AES128) 07292 p->encmethods = IAX_ENCRYPT_AES128; 07293 else 07294 p->encmethods = 0; 07295 } 07296 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1100 of file chan_iax2.c.
01101 { 01102 /* The MWI subscriptions exist just so the core knows we care about those 01103 * mailboxes. However, we just grab the events out of the cache when it 01104 * is time to send MWI, since it is only sent with a REGACK. */ 01105 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 11500 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(), f, iax2_sched_add(), iax_frame_free(), iaxs, io, iax_frame::list, sched, send_packet(), timer, and timing_read().
Referenced by start_network_thread().
11501 { 11502 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 11503 from the network, and queue them for delivery to the channels */ 11504 int res, count, wakeup; 11505 struct iax_frame *f; 11506 11507 if (timer) 11508 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 11509 11510 for(;;) { 11511 pthread_testcancel(); 11512 11513 /* Go through the queue, sending messages which have not yet been 11514 sent, and scheduling retransmissions if appropriate */ 11515 AST_LIST_LOCK(&frame_queue); 11516 count = 0; 11517 wakeup = -1; 11518 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) { 11519 if (f->sentyet) 11520 continue; 11521 11522 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 11523 if (ast_mutex_trylock(&iaxsl[f->callno])) { 11524 wakeup = 1; 11525 continue; 11526 } 11527 11528 f->sentyet = 1; 11529 11530 if (iaxs[f->callno]) { 11531 send_packet(f); 11532 count++; 11533 } 11534 11535 ast_mutex_unlock(&iaxsl[f->callno]); 11536 11537 if (f->retries < 0) { 11538 /* This is not supposed to be retransmitted */ 11539 AST_LIST_REMOVE_CURRENT(list); 11540 /* Free the iax frame */ 11541 iax_frame_free(f); 11542 } else { 11543 /* We need reliable delivery. Schedule a retransmission */ 11544 f->retries++; 11545 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 11546 } 11547 } 11548 AST_LIST_TRAVERSE_SAFE_END; 11549 AST_LIST_UNLOCK(&frame_queue); 11550 11551 pthread_testcancel(); 11552 if (count >= 20) 11553 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 11554 11555 /* Now do the IO, and run scheduled tasks */ 11556 res = ast_io_wait(io, wakeup); 11557 if (res >= 0) { 11558 if (res >= 20) 11559 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 11560 } 11561 } 11562 return NULL; 11563 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1668 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.
Referenced by __find_callno().
01669 { 01670 struct chan_iax2_pvt *tmp; 01671 jb_conf jbconf; 01672 01673 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01674 return NULL; 01675 } 01676 01677 if (ast_string_field_init(tmp, 32)) { 01678 ao2_ref(tmp, -1); 01679 tmp = NULL; 01680 return NULL; 01681 } 01682 01683 tmp->prefs = prefs; 01684 tmp->pingid = -1; 01685 tmp->lagid = -1; 01686 tmp->autoid = -1; 01687 tmp->authid = -1; 01688 tmp->initid = -1; 01689 tmp->keyrotateid = -1; 01690 01691 ast_string_field_set(tmp,exten, "s"); 01692 ast_string_field_set(tmp,host, host); 01693 01694 tmp->jb = jb_new(); 01695 tmp->jbid = -1; 01696 jbconf.max_jitterbuf = maxjitterbuffer; 01697 jbconf.resync_threshold = resyncthreshold; 01698 jbconf.max_contig_interp = maxjitterinterps; 01699 jbconf.target_extra = jittertargetextra; 01700 jb_setconf(tmp->jb,&jbconf); 01701 01702 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01703 01704 tmp->hold_signaling = 1; 01705 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01706 01707 return tmp; 01708 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 4634 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
04635 { 04636 if (ast_strlen_zero(data)) 04637 return; 04638 04639 pds->peer = strsep(&data, "/"); 04640 pds->exten = strsep(&data, "/"); 04641 pds->options = data; 04642 04643 if (pds->exten) { 04644 data = pds->exten; 04645 pds->exten = strsep(&data, "@"); 04646 pds->context = data; 04647 } 04648 04649 if (strchr(pds->peer, '@')) { 04650 data = pds->peer; 04651 pds->username = strsep(&data, "@"); 04652 pds->peer = data; 04653 } 04654 04655 if (pds->username) { 04656 data = pds->username; 04657 pds->username = strsep(&data, ":"); 04658 pds->password = data; 04659 } 04660 04661 data = pds->peer; 04662 pds->peer = strsep(&data, ":"); 04663 pds->port = data; 04664 04665 /* check for a key name wrapped in [] in the secret position, if found, 04666 move it to the key field instead 04667 */ 04668 if (pds->password && (pds->password[0] == '[')) { 04669 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04670 pds->password = NULL; 04671 } 04672 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1416 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_module(), and load_objects().
01417 { 01418 struct iax2_peer *peer = obj, *peer2 = arg; 01419 01420 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01421 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12231 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
12232 { 12233 struct iax2_peer *peer = obj; 12234 12235 ast_set_flag(peer, IAX_DELME); 12236 12237 return 0; 12238 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 11716 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().
11717 { 11718 struct iax2_peer *peer = obj; 11719 int callno = peer->callno; 11720 11721 ast_free_ha(peer->ha); 11722 11723 if (callno > 0) { 11724 ast_mutex_lock(&iaxsl[callno]); 11725 iax2_destroy(callno); 11726 ast_mutex_unlock(&iaxsl[callno]); 11727 } 11728 11729 register_peer_exten(peer, 0); 11730 11731 if (peer->dnsmgr) 11732 ast_dnsmgr_release(peer->dnsmgr); 11733 11734 if (peer->mwi_event_sub) 11735 ast_event_unsubscribe(peer->mwi_event_sub); 11736 11737 ast_string_field_free_memory(peer); 11738 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1406 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module(), and load_objects().
01407 { 01408 const struct iax2_peer *peer = obj; 01409 01410 return ast_str_hash(peer->name); 01411 }
Definition at line 1463 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), reg_source_db(), socket_process(), and update_registry().
01464 { 01465 ao2_ref(peer, +1); 01466 return peer; 01467 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 13536 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
13537 { 13538 struct iax2_peer *peer = obj; 13539 13540 if (peer->sockfd < 0) 13541 peer->sockfd = defaultsockfd; 13542 13543 return 0; 13544 }
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 11644 of file chan_iax2.c.
References ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, outsock, qos, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
11645 { 11646 struct sockaddr_in sin; 11647 int nonlocal = 1; 11648 int port = IAX_DEFAULT_PORTNO; 11649 int sockfd = defaultsockfd; 11650 char *tmp; 11651 char *addr; 11652 char *portstr; 11653 11654 if (!(tmp = ast_strdupa(srcaddr))) 11655 return -1; 11656 11657 addr = strsep(&tmp, ":"); 11658 portstr = tmp; 11659 11660 if (portstr) { 11661 port = atoi(portstr); 11662 if (port < 1) 11663 port = IAX_DEFAULT_PORTNO; 11664 } 11665 11666 if (!ast_get_ip(&sin, addr)) { 11667 struct ast_netsock *sock; 11668 int res; 11669 11670 sin.sin_port = 0; 11671 sin.sin_family = AF_INET; 11672 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 11673 if (res == 0) { 11674 /* ip address valid. */ 11675 sin.sin_port = htons(port); 11676 if (!(sock = ast_netsock_find(netsock, &sin))) 11677 sock = ast_netsock_find(outsock, &sin); 11678 if (sock) { 11679 sockfd = ast_netsock_sockfd(sock); 11680 nonlocal = 0; 11681 } else { 11682 unsigned int orig_saddr = sin.sin_addr.s_addr; 11683 /* INADDR_ANY matches anyway! */ 11684 sin.sin_addr.s_addr = INADDR_ANY; 11685 if (ast_netsock_find(netsock, &sin)) { 11686 sin.sin_addr.s_addr = orig_saddr; 11687 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 11688 if (sock) { 11689 sockfd = ast_netsock_sockfd(sock); 11690 ast_netsock_unref(sock); 11691 nonlocal = 0; 11692 } else { 11693 nonlocal = 2; 11694 } 11695 } 11696 } 11697 } 11698 } 11699 11700 peer->sockfd = sockfd; 11701 11702 if (nonlocal == 1) { 11703 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 11704 srcaddr, peer->name); 11705 return -1; 11706 } else if (nonlocal == 2) { 11707 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 11708 srcaddr, peer->name); 11709 return -1; 11710 } else { 11711 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 11712 return 0; 11713 } 11714 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3446 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), handle_cli_iax2_show_peer(), and manager_iax2_show_peer_list().
03447 { 03448 int res = 0; 03449 if (peer->maxms) { 03450 if (peer->lastms < 0) { 03451 ast_copy_string(status, "UNREACHABLE", statuslen); 03452 } else if (peer->lastms > peer->maxms) { 03453 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03454 res = 1; 03455 } else if (peer->lastms) { 03456 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03457 res = 1; 03458 } else { 03459 ast_copy_string(status, "UNKNOWN", statuslen); 03460 } 03461 } else { 03462 ast_copy_string(status, "Unmonitored", statuslen); 03463 res = -1; 03464 } 03465 return res; 03466 }
Definition at line 1469 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(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01470 { 01471 ao2_ref(peer, -1); 01472 return NULL; 01473 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2074 of file chan_iax2.c.
References peercnt::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02075 { 02076 struct peercnt *peercnt; 02077 unsigned long addr = sin->sin_addr.s_addr; 02078 int res = 0; 02079 struct peercnt tmp = { 02080 .addr = addr, 02081 }; 02082 02083 /* Reasoning for peercnts container lock: Two identical ip addresses 02084 * could be added by different threads at the "same time". Without the container 02085 * lock, both threads could alloc space for the same object and attempt 02086 * to link to table. With the lock, one would create the object and link 02087 * to table while the other would find the already created peercnt object 02088 * rather than creating a new one. */ 02089 ao2_lock(peercnts); 02090 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02091 ao2_lock(peercnt); 02092 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02093 ao2_lock(peercnt); 02094 /* create and set defaults */ 02095 peercnt->addr = addr; 02096 set_peercnt_limit(peercnt); 02097 /* guarantees it does not go away after unlocking table 02098 * ao2_find automatically adds this */ 02099 ao2_link(peercnts, peercnt); 02100 } else { 02101 ao2_unlock(peercnts); 02102 return -1; 02103 } 02104 02105 /* check to see if the address has hit its callno limit. If not increment cur. */ 02106 if (peercnt->limit > peercnt->cur) { 02107 peercnt->cur++; 02108 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02109 } else { /* max num call numbers for this peer has been reached! */ 02110 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02111 res = -1; 02112 } 02113 02114 /* clean up locks and ref count */ 02115 ao2_unlock(peercnt); 02116 ao2_unlock(peercnts); 02117 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02118 02119 return res; 02120 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1914 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
01915 { 01916 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 01917 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 01918 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1908 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 2046 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), peercnt::limit, OBJ_POINTER, peercnts, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02047 { 02048 /* this function turns off and on custom callno limits set by peer registration */ 02049 struct peercnt *peercnt; 02050 struct peercnt tmp = { 02051 .addr = sin->sin_addr.s_addr, 02052 }; 02053 02054 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02055 peercnt->reg = reg; 02056 if (limit) { 02057 peercnt->limit = limit; 02058 } else { 02059 set_peercnt_limit(peercnt); 02060 } 02061 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 02062 ao2_ref(peercnt, -1); /* decrement ref from find */ 02063 } 02064 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2126 of file chan_iax2.c.
References peercnt::addr, ao2_lock(), ao2_unlink, ao2_unlock(), ast_debug, ast_inet_ntoa(), peercnt::cur, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02127 { 02128 struct sockaddr_in sin = { 02129 .sin_addr.s_addr = peercnt->addr, 02130 }; 02131 02132 if (peercnt) { 02133 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02134 * peercnt_add could try and grab this entry from the table and modify it at the 02135 * "same time" this thread attemps to unlink it.*/ 02136 ao2_lock(peercnts); 02137 peercnt->cur--; 02138 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02139 /* if this was the last connection from the peer remove it from table */ 02140 if (peercnt->cur == 0) { 02141 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02142 } 02143 ao2_unlock(peercnts); 02144 } 02145 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2165 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
02166 { 02167 struct peercnt *peercnt; 02168 struct peercnt tmp = { 02169 .addr = sin->sin_addr.s_addr, 02170 }; 02171 02172 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02173 peercnt_remove(peercnt); 02174 ao2_ref(peercnt, -1); /* decrement ref from find */ 02175 } 02176 return 0; 02177 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2151 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02152 { 02153 struct peercnt *peercnt = (struct peercnt *) obj; 02154 02155 peercnt_remove(peercnt); 02156 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02157 02158 return 0; 02159 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 12747 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
12748 { 12749 struct ao2_iterator i; 12750 struct iax2_peer *peer; 12751 12752 i = ao2_iterator_init(peers, 0); 12753 while ((peer = ao2_iterator_next(&i))) { 12754 iax2_poke_peer(peer, 0); 12755 peer_unref(peer); 12756 } 12757 ao2_iterator_destroy(&i); 12758 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2035 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02036 { 02037 struct addr_range *addr_range = obj; 02038 02039 return addr_range->delme ? CMP_MATCH : 0; 02040 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 12292 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), peers, and unlink_peer().
12293 { 12294 struct iax2_peer *peer; 12295 struct ao2_iterator i; 12296 12297 i = ao2_iterator_init(peers, 0); 12298 while ((peer = ao2_iterator_next(&i))) { 12299 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 12300 unlink_peer(peer); 12301 } 12302 peer_unref(peer); 12303 } 12304 ao2_iterator_destroy(&i); 12305 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12276 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, user, user_unref(), and users.
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
12277 { 12278 struct iax2_user *user; 12279 struct ao2_iterator i; 12280 12281 i = ao2_iterator_init(users, 0); 12282 while ((user = ao2_iterator_next(&i))) { 12283 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 12284 ao2_unlink(users, user); 12285 } 12286 user_unref(user); 12287 } 12288 ao2_iterator_destroy(&i); 12289 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 13553 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
13554 { 13555 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13556 13557 /* The frames_received field is used to hold whether we're matching 13558 * against a full frame or not ... */ 13559 13560 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 13561 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13562 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1620 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, iax2_trunk_peer::list, iax2_trunk_peer::next, 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.
01621 { 01622 struct chan_iax2_pvt *pvt = obj; 01623 struct iax_frame *cur = NULL; 01624 struct signaling_queue_entry *s = NULL; 01625 01626 ast_mutex_lock(&iaxsl[pvt->callno]); 01627 iax2_destroy_helper(pvt); 01628 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01629 pvt->callno_entry = NULL; 01630 ast_mutex_unlock(&iaxsl[pvt->callno]); 01631 01632 /* Already gone */ 01633 ast_set_flag(pvt, IAX_ALREADYGONE); 01634 01635 AST_LIST_LOCK(&frame_queue); 01636 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 01637 /* Cancel any pending transmissions */ 01638 if (cur->callno == pvt->callno) { 01639 cur->retries = -1; 01640 } 01641 } 01642 AST_LIST_UNLOCK(&frame_queue); 01643 01644 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01645 free_signaling_queue_entry(s); 01646 } 01647 01648 if (pvt->reg) { 01649 pvt->reg->callno = 0; 01650 } 01651 01652 if (!pvt->owner) { 01653 jb_frame frame; 01654 if (pvt->vars) { 01655 ast_variables_destroy(pvt->vars); 01656 pvt->vars = NULL; 01657 } 01658 01659 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01660 iax2_frame_free(frame.data); 01661 } 01662 01663 jb_destroy(pvt->jb); 01664 ast_string_field_free_memory(pvt); 01665 } 01666 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 13546 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
13547 { 13548 const struct chan_iax2_pvt *pvt = obj; 13549 13550 return pvt->peercallno; 13551 }
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 1596 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01597 { 01598 struct signaling_queue_entry *new; 01599 01600 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01601 return 1; /* do not queue this frame */ 01602 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01603 return -1; /* out of memory */ 01604 } 01605 01606 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01607 01608 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01609 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01610 free_signaling_queue_entry(new); 01611 return -1; 01612 } 01613 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01614 } 01615 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01616 01617 return 0; 01618 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 7264 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().
07265 { 07266 struct ast_iax2_full_hdr fh; 07267 fh.scallno = htons(src | IAX_FLAG_FULL); 07268 fh.dcallno = htons(dst); 07269 fh.ts = 0; 07270 fh.oseqno = 0; 07271 fh.iseqno = 0; 07272 fh.type = AST_FRAME_IAX; 07273 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07274 iax_outputframe(NULL, &fh, 0, sin, 0); 07275 #if 0 07276 if (option_debug) 07277 #endif 07278 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07279 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07280 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07281 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4012 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04013 { 04014 struct ast_variable *var = NULL; 04015 struct ast_variable *tmp; 04016 struct iax2_peer *peer=NULL; 04017 time_t regseconds = 0, nowtime; 04018 int dynamic=0; 04019 04020 if (peername) { 04021 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04022 if (!var && sin) 04023 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04024 } else if (sin) { 04025 char porta[25]; 04026 sprintf(porta, "%d", ntohs(sin->sin_port)); 04027 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04028 if (var) { 04029 /* We'll need the peer name in order to build the structure! */ 04030 for (tmp = var; tmp; tmp = tmp->next) { 04031 if (!strcasecmp(tmp->name, "name")) 04032 peername = tmp->value; 04033 } 04034 } 04035 } 04036 if (!var && peername) { /* Last ditch effort */ 04037 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04038 /*!\note 04039 * If this one loaded something, then we need to ensure that the host 04040 * field matched. The only reason why we can't have this as a criteria 04041 * is because we only have the IP address and the host field might be 04042 * set as a name (and the reverse PTR might not match). 04043 */ 04044 if (var && sin) { 04045 for (tmp = var; tmp; tmp = tmp->next) { 04046 if (!strcasecmp(tmp->name, "host")) { 04047 struct ast_hostent ahp; 04048 struct hostent *hp; 04049 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04050 /* No match */ 04051 ast_variables_destroy(var); 04052 var = NULL; 04053 } 04054 break; 04055 } 04056 } 04057 } 04058 } 04059 if (!var) 04060 return NULL; 04061 04062 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04063 04064 if (!peer) { 04065 ast_variables_destroy(var); 04066 return NULL; 04067 } 04068 04069 for (tmp = var; tmp; tmp = tmp->next) { 04070 /* Make sure it's not a user only... */ 04071 if (!strcasecmp(tmp->name, "type")) { 04072 if (strcasecmp(tmp->value, "friend") && 04073 strcasecmp(tmp->value, "peer")) { 04074 /* Whoops, we weren't supposed to exist! */ 04075 peer = peer_unref(peer); 04076 break; 04077 } 04078 } else if (!strcasecmp(tmp->name, "regseconds")) { 04079 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04080 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04081 inet_aton(tmp->value, &(peer->addr.sin_addr)); 04082 } else if (!strcasecmp(tmp->name, "port")) { 04083 peer->addr.sin_port = htons(atoi(tmp->value)); 04084 } else if (!strcasecmp(tmp->name, "host")) { 04085 if (!strcasecmp(tmp->value, "dynamic")) 04086 dynamic = 1; 04087 } 04088 } 04089 04090 ast_variables_destroy(var); 04091 04092 if (!peer) 04093 return NULL; 04094 04095 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04096 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04097 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 04098 if (peer->expire > -1) { 04099 if (!ast_sched_del(sched, peer->expire)) { 04100 peer->expire = -1; 04101 peer_unref(peer); 04102 } 04103 } 04104 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04105 if (peer->expire == -1) 04106 peer_unref(peer); 04107 } 04108 ao2_link(peers, peer); 04109 if (ast_test_flag(peer, IAX_DYNAMIC)) 04110 reg_source_db(peer); 04111 } else { 04112 ast_set_flag(peer, IAX_TEMPONLY); 04113 } 04114 04115 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04116 time(&nowtime); 04117 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04118 memset(&peer->addr, 0, sizeof(peer->addr)); 04119 realtime_update_peer(peer->name, &peer->addr, 0); 04120 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04121 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04122 } 04123 else { 04124 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04125 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04126 } 04127 } 04128 04129 return peer; 04130 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4203 of file chan_iax2.c.
References ast_inet_ntoa(), ast_update_realtime(), and SENTINEL.
Referenced by __expire_registry(), update_peer(), and update_registry().
04204 { 04205 char port[10]; 04206 char regseconds[20]; 04207 04208 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04209 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 04210 ast_update_realtime("iaxpeers", "name", peername, 04211 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 04212 "regseconds", regseconds, SENTINEL); 04213 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4132 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04133 { 04134 struct ast_variable *var; 04135 struct ast_variable *tmp; 04136 struct iax2_user *user=NULL; 04137 04138 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04139 if (!var) 04140 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04141 if (!var && sin) { 04142 char porta[6]; 04143 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04144 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04145 if (!var) 04146 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04147 } 04148 if (!var) { /* Last ditch effort */ 04149 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04150 /*!\note 04151 * If this one loaded something, then we need to ensure that the host 04152 * field matched. The only reason why we can't have this as a criteria 04153 * is because we only have the IP address and the host field might be 04154 * set as a name (and the reverse PTR might not match). 04155 */ 04156 if (var) { 04157 for (tmp = var; tmp; tmp = tmp->next) { 04158 if (!strcasecmp(tmp->name, "host")) { 04159 struct ast_hostent ahp; 04160 struct hostent *hp; 04161 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04162 /* No match */ 04163 ast_variables_destroy(var); 04164 var = NULL; 04165 } 04166 break; 04167 } 04168 } 04169 } 04170 } 04171 if (!var) 04172 return NULL; 04173 04174 tmp = var; 04175 while(tmp) { 04176 /* Make sure it's not a peer only... */ 04177 if (!strcasecmp(tmp->name, "type")) { 04178 if (strcasecmp(tmp->value, "friend") && 04179 strcasecmp(tmp->value, "user")) { 04180 return NULL; 04181 } 04182 } 04183 tmp = tmp->next; 04184 } 04185 04186 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 04187 04188 ast_variables_destroy(var); 04189 04190 if (!user) 04191 return NULL; 04192 04193 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04194 ast_set_flag(user, IAX_RTCACHEFRIENDS); 04195 ao2_link(users, user); 04196 } else { 04197 ast_set_flag(user, IAX_TEMPONLY); 04198 } 04199 04200 return user; 04201 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8131 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, inet_aton(), iax2_peer::name, peer_ref(), peer_unref(), register_peer_exten(), and sched.
Referenced by build_peer(), set_config(), and temp_peer().
08132 { 08133 char data[80]; 08134 struct in_addr in; 08135 char *c, *d; 08136 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 08137 c = strchr(data, ':'); 08138 if (c) { 08139 *c = '\0'; 08140 c++; 08141 if (inet_aton(data, &in)) { 08142 d = strchr(c, ':'); 08143 if (d) { 08144 *d = '\0'; 08145 d++; 08146 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name, 08147 ast_inet_ntoa(in), atoi(c), atoi(d)); 08148 iax2_poke_peer(p, 0); 08149 p->expiry = atoi(d); 08150 memset(&p->addr, 0, sizeof(p->addr)); 08151 p->addr.sin_family = AF_INET; 08152 p->addr.sin_addr = in; 08153 p->addr.sin_port = htons(atoi(c)); 08154 if (p->expire > -1) { 08155 if (!ast_sched_del(sched, p->expire)) { 08156 p->expire = -1; 08157 peer_unref(p); 08158 } 08159 } 08160 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08161 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08162 if (p->expire == -1) 08163 peer_unref(p); 08164 if (iax2_regfunk) 08165 iax2_regfunk(p->name, 1); 08166 register_peer_exten(p, 1); 08167 } 08168 08169 } 08170 } 08171 } 08172 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8050 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().
08051 { 08052 char multi[256]; 08053 char *stringp, *ext; 08054 if (!ast_strlen_zero(regcontext)) { 08055 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08056 stringp = multi; 08057 while((ext = strsep(&stringp, "&"))) { 08058 if (onoff) { 08059 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08060 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08061 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08062 } else 08063 ast_context_remove_extension(regcontext, ext, 1, NULL); 08064 } 08065 } 08066 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7435 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
07436 { 07437 char requeststr[256] = ""; 07438 char peer[256] = ""; 07439 char md5secret[256] = ""; 07440 char rsasecret[256] = ""; 07441 char secret[256] = ""; 07442 struct iax2_peer *p = NULL; 07443 struct ast_key *key; 07444 char *keyn; 07445 int x; 07446 int expire = 0; 07447 int res = -1; 07448 07449 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07450 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07451 if (ies->username) 07452 ast_copy_string(peer, ies->username, sizeof(peer)); 07453 if (ies->password) 07454 ast_copy_string(secret, ies->password, sizeof(secret)); 07455 if (ies->md5_result) 07456 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07457 if (ies->rsa_result) 07458 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07459 if (ies->refresh) 07460 expire = ies->refresh; 07461 07462 if (ast_strlen_zero(peer)) { 07463 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07464 return -1; 07465 } 07466 07467 /* SLD: first call to lookup peer during registration */ 07468 ast_mutex_unlock(&iaxsl[callno]); 07469 p = find_peer(peer, 1); 07470 ast_mutex_lock(&iaxsl[callno]); 07471 if (!p || !iaxs[callno]) { 07472 if (iaxs[callno]) { 07473 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07474 /* Anything, as long as it's non-blank */ 07475 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07476 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07477 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07478 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07479 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07480 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07481 * 07482 * If none of these cases exist, res will be returned as 0 without authentication indicating 07483 * an AUTHREQ needs to be sent out. */ 07484 07485 if (ast_strlen_zero(iaxs[callno]->challenge) && 07486 !(!ast_strlen_zero(secret) && plaintext)) { 07487 /* by setting res to 0, an REGAUTH will be sent */ 07488 res = 0; 07489 } 07490 } 07491 if (authdebug && !p) 07492 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07493 goto return_unref; 07494 } 07495 07496 if (!ast_test_flag(p, IAX_DYNAMIC)) { 07497 if (authdebug) 07498 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07499 goto return_unref; 07500 } 07501 07502 if (!ast_apply_ha(p->ha, sin)) { 07503 if (authdebug) 07504 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07505 goto return_unref; 07506 } 07507 ast_string_field_set(iaxs[callno], secret, p->secret); 07508 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07509 /* Check secret against what we have on file */ 07510 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07511 if (!ast_strlen_zero(p->inkeys)) { 07512 char tmpkeys[256]; 07513 char *stringp=NULL; 07514 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07515 stringp=tmpkeys; 07516 keyn = strsep(&stringp, ":"); 07517 while(keyn) { 07518 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07519 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07520 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07521 break; 07522 } else if (!key) 07523 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 07524 keyn = strsep(&stringp, ":"); 07525 } 07526 if (!keyn) { 07527 if (authdebug) 07528 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 07529 goto return_unref; 07530 } 07531 } else { 07532 if (authdebug) 07533 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 07534 goto return_unref; 07535 } 07536 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07537 struct MD5Context md5; 07538 unsigned char digest[16]; 07539 char *tmppw, *stringp; 07540 07541 tmppw = ast_strdupa(p->secret); 07542 stringp = tmppw; 07543 while((tmppw = strsep(&stringp, ";"))) { 07544 MD5Init(&md5); 07545 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 07546 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07547 MD5Final(digest, &md5); 07548 for (x=0;x<16;x++) 07549 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07550 if (!strcasecmp(requeststr, md5secret)) 07551 break; 07552 } 07553 if (tmppw) { 07554 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07555 } else { 07556 if (authdebug) 07557 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 07558 goto return_unref; 07559 } 07560 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 07561 /* They've provided a plain text password and we support that */ 07562 if (strcmp(secret, p->secret)) { 07563 if (authdebug) 07564 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07565 goto return_unref; 07566 } else 07567 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07568 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 07569 /* if challenge has been sent, but no challenge response if given, reject. */ 07570 goto return_unref; 07571 } 07572 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 07573 07574 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 07575 res = 0; 07576 07577 return_unref: 07578 if (iaxs[callno]) { 07579 ast_string_field_set(iaxs[callno], peer, peer); 07580 07581 /* Choose lowest expiry number */ 07582 if (expire && (expire < iaxs[callno]->expiry)) { 07583 iaxs[callno]->expiry = expire; 07584 } 07585 } 07586 07587 if (p) { 07588 peer_unref(p); 07589 } 07590 return res; 07591 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8339 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, peer_unref(), and send_command().
Referenced by socket_process().
08340 { 08341 struct iax_ie_data ied; 08342 struct iax2_peer *p; 08343 char challenge[10]; 08344 const char *peer_name; 08345 int sentauthmethod; 08346 08347 peer_name = ast_strdupa(iaxs[callno]->peer); 08348 08349 /* SLD: third call to find_peer in registration */ 08350 ast_mutex_unlock(&iaxsl[callno]); 08351 if ((p = find_peer(peer_name, 1))) { 08352 last_authmethod = p->authmethods; 08353 } 08354 08355 ast_mutex_lock(&iaxsl[callno]); 08356 if (!iaxs[callno]) 08357 goto return_unref; 08358 08359 memset(&ied, 0, sizeof(ied)); 08360 /* The selection of which delayed reject is sent may leak information, 08361 * if it sets a static response. For example, if a host is known to only 08362 * use MD5 authentication, then an RSA response would indicate that the 08363 * peer does not exist, and vice-versa. 08364 * Therefore, we use whatever the last peer used (which may vary over the 08365 * course of a server, which should leak minimal information). */ 08366 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08367 if (!p) { 08368 iaxs[callno]->authmethods = sentauthmethod; 08369 } 08370 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08371 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08372 /* Build the challenge */ 08373 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08374 ast_string_field_set(iaxs[callno], challenge, challenge); 08375 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08376 } 08377 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08378 08379 return_unref: 08380 if (p) { 08381 peer_unref(p); 08382 } 08383 08384 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08385 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8387 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_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
08388 { 08389 struct iax2_registry *reg; 08390 /* Start pessimistic */ 08391 struct iax_ie_data ied; 08392 char peer[256] = ""; 08393 char challenge[256] = ""; 08394 int res; 08395 int authmethods = 0; 08396 if (ies->authmethods) 08397 authmethods = ies->authmethods; 08398 if (ies->username) 08399 ast_copy_string(peer, ies->username, sizeof(peer)); 08400 if (ies->challenge) 08401 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08402 memset(&ied, 0, sizeof(ied)); 08403 reg = iaxs[callno]->reg; 08404 if (reg) { 08405 if (inaddrcmp(®->addr, sin)) { 08406 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08407 return -1; 08408 } 08409 if (ast_strlen_zero(reg->secret)) { 08410 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08411 reg->regstate = REG_STATE_NOAUTH; 08412 return -1; 08413 } 08414 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08415 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08416 if (reg->secret[0] == '[') { 08417 char tmpkey[256]; 08418 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08419 tmpkey[strlen(tmpkey) - 1] = '\0'; 08420 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08421 } else 08422 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08423 if (!res) { 08424 reg->regstate = REG_STATE_AUTHSENT; 08425 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08426 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08427 } else 08428 return -1; 08429 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08430 } else 08431 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08432 return -1; 08433 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 6602 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
06603 { 06604 switch(regstate) { 06605 case REG_STATE_UNREGISTERED: 06606 return "Unregistered"; 06607 case REG_STATE_REGSENT: 06608 return "Request Sent"; 06609 case REG_STATE_AUTHSENT: 06610 return "Auth. Sent"; 06611 case REG_STATE_REGISTERED: 06612 return "Registered"; 06613 case REG_STATE_REJECTED: 06614 return "Rejected"; 06615 case REG_STATE_TIMEOUT: 06616 return "Timeout"; 06617 case REG_STATE_NOAUTH: 06618 return "No Authentication"; 06619 default: 06620 return "Unknown"; 06621 } 06622 }
static int reload | ( | void | ) | [static] |
Definition at line 12808 of file chan_iax2.c.
References reload_config().
12809 { 12810 return reload_config(); 12811 }
static int reload_config | ( | void | ) | [static] |
Definition at line 12759 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
12760 { 12761 static const char config[] = "iax.conf"; 12762 struct iax2_registry *reg; 12763 12764 if (set_config(config, 1) > 0) { 12765 prune_peers(); 12766 prune_users(); 12767 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12768 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12769 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 12770 trunk_timed = trunk_untimed = 0; 12771 trunk_nmaxmtu = trunk_maxmtu = 0; 12772 memset(&debugaddr, '\0', sizeof(debugaddr)); 12773 12774 AST_LIST_LOCK(®istrations); 12775 AST_LIST_TRAVERSE(®istrations, reg, entry) 12776 iax2_do_register(reg); 12777 AST_LIST_UNLOCK(®istrations); 12778 12779 /* Qualify hosts, too */ 12780 poke_all_peers(); 12781 } 12782 12783 reload_firmware(0); 12784 iax_provision_reload(1); 12785 ast_unload_realtime("iaxpeers"); 12786 12787 return 0; 12788 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2957 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, iax2_trunk_peer::list, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
02958 { 02959 struct iax_firmware *cur = NULL; 02960 DIR *fwd; 02961 struct dirent *de; 02962 char dir[256], fn[256]; 02963 02964 AST_LIST_LOCK(&firmwares); 02965 02966 /* Mark all as dead */ 02967 AST_LIST_TRAVERSE(&firmwares, cur, list) 02968 cur->dead = 1; 02969 02970 /* Now that we have marked them dead... load new ones */ 02971 if (!unload) { 02972 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 02973 fwd = opendir(dir); 02974 if (fwd) { 02975 while((de = readdir(fwd))) { 02976 if (de->d_name[0] != '.') { 02977 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02978 if (!try_firmware(fn)) { 02979 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 02980 } 02981 } 02982 } 02983 closedir(fwd); 02984 } else 02985 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02986 } 02987 02988 /* Clean up leftovers */ 02989 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 02990 if (!cur->dead) 02991 continue; 02992 AST_LIST_REMOVE_CURRENT(list); 02993 destroy_firmware(cur); 02994 } 02995 AST_LIST_TRAVERSE_SAFE_END; 02996 02997 AST_LIST_UNLOCK(&firmwares); 02998 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1877 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
01878 { 01879 if (!pvt->peercallno) { 01880 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01881 return; 01882 } 01883 01884 ao2_unlink(iax_peercallno_pvts, pvt); 01885 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1858 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
01859 { 01860 if (!pvt->transfercallno) { 01861 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01862 return; 01863 } 01864 01865 ao2_unlink(iax_transfercallno_pvts, pvt); 01866 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2363 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().
02364 { 02365 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02366 02367 /* the callno_pool container is locked here primarily to ensure thread 02368 * safety of the total_nonval_callno_used check and decrement */ 02369 ao2_lock(callno_pool); 02370 02371 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02372 total_nonval_callno_used--; 02373 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02374 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02375 } 02376 02377 if (callno_entry->callno < TRUNK_CALL_START) { 02378 ao2_link(callno_pool, callno_entry); 02379 } else { 02380 ao2_link(callno_pool_trunk, callno_entry); 02381 } 02382 ao2_ref(callno_entry, -1); /* only container ref remains */ 02383 02384 ao2_unlock(callno_pool); 02385 return 0; 02386 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4491 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), user, and user_unref().
Referenced by handle_call_token().
04492 { 04493 struct iax2_user *user = NULL; 04494 struct iax2_peer *peer = NULL; 04495 04496 if (ast_strlen_zero(name)) { 04497 return; /* no username given */ 04498 } 04499 04500 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04501 user->calltoken_required = CALLTOKEN_YES; 04502 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04503 peer->calltoken_required = CALLTOKEN_YES; 04504 } 04505 04506 if (peer) { 04507 peer_unref(peer); 04508 } 04509 if (user) { 04510 user_unref(user); 04511 } 04512 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4407 of file chan_iax2.c.
References 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, f, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().
Referenced by socket_process().
04408 { 04409 struct chan_iax2_pvt *pvt = iaxs[callno]; 04410 int frametype = f->af.frametype; 04411 int subclass = f->af.subclass; 04412 struct { 04413 struct ast_iax2_full_hdr fh; 04414 struct iax_ie_data ied; 04415 } data = { 04416 .ied.buf = { 0 }, 04417 .ied.pos = 0, 04418 }; 04419 /* total len - header len gives us the frame's IE len */ 04420 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04421 04422 if (!pvt) { 04423 return; /* this should not be possible if called from socket_process() */ 04424 } 04425 04426 /* 04427 * Check to make sure last frame sent is valid for call token resend 04428 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04429 * 2. Frame should _NOT_ already have a destination callno 04430 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04431 * 4. Pvt must have a calltoken_ie_len which represents the number of 04432 * bytes at the end of the frame used for the previous calltoken ie. 04433 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04434 * 6. Total length of f->data must be _LESS_ than size of our data struct 04435 * because f->data must be able to fit within data. 04436 */ 04437 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04438 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04439 (f->datalen > sizeof(data))) { 04440 04441 return; /* ignore resend, token was not valid for the dialog */ 04442 } 04443 04444 /* token is valid 04445 * 1. Copy frame data over 04446 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04447 * NOTE: Having the ie always be last is not protocol specified, 04448 * it is only an implementation choice. Since we only expect the ie to 04449 * be last for frames we have sent, this can no way be affected by 04450 * another end point. 04451 * 3. Remove frame from queue 04452 * 4. Free old frame 04453 * 5. Clear previous seqnos 04454 * 6. Resend with CALLTOKEN ie. 04455 */ 04456 04457 /* ---1.--- */ 04458 memcpy(&data, f->data, f->datalen); 04459 data.ied.pos = ie_data_pos; 04460 04461 /* ---2.--- */ 04462 /* move to the beginning of the calltoken ie so we can write over it */ 04463 data.ied.pos -= pvt->calltoken_ie_len; 04464 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04465 04466 /* make sure to update token length incase it ever has to be stripped off again */ 04467 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04468 04469 /* ---3.--- */ 04470 AST_LIST_LOCK(&frame_queue); 04471 AST_LIST_REMOVE(&frame_queue, f, list); 04472 AST_LIST_UNLOCK(&frame_queue); 04473 04474 /* ---4.--- */ 04475 iax2_frame_free(f); 04476 04477 /* ---5.--- */ 04478 pvt->oseqno = 0; 04479 pvt->rseqno = 0; 04480 pvt->iseqno = 0; 04481 pvt->aseqno = 0; 04482 if (pvt->peercallno) { 04483 remove_by_peercallno(pvt); 04484 pvt->peercallno = 0; 04485 } 04486 04487 /* ---6.--- */ 04488 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04489 }
Definition at line 8868 of file chan_iax2.c.
References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iaxs, iax_ies::ospblocklength, and iax_ies::osptokenblock.
Referenced by socket_process().
08869 { 08870 int i; 08871 unsigned int length, offset = 0; 08872 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 08873 08874 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 08875 length = ies->ospblocklength[i]; 08876 if (length != 0) { 08877 if (length > IAX_MAX_OSPBLOCK_SIZE) { 08878 /* OSP token block length wrong, clear buffer */ 08879 offset = 0; 08880 break; 08881 } else { 08882 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 08883 offset += length; 08884 } 08885 } else { 08886 break; 08887 } 08888 } 08889 *(full_osptoken + offset) = '\0'; 08890 if (strlen(full_osptoken) != offset) { 08891 /* OSP token length wrong, clear buffer */ 08892 *full_osptoken = '\0'; 08893 } 08894 08895 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 08896 }
Definition at line 8857 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
08858 { 08859 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 08860 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 08861 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 08862 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 08863 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 08864 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 08865 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 08866 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2435 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and sched.
Referenced by pvt_destructor().
02436 { 02437 int i; 02438 struct peercnt *peercnt; 02439 struct peercnt tmp = { 02440 .addr = sin->sin_addr.s_addr, 02441 }; 02442 02443 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02444 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02445 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02446 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02447 if (i == -1) { 02448 ao2_ref(peercnt, -1); 02449 } 02450 } 02451 02452 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02453 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 11472 of file chan_iax2.c.
References ast_cond_timedwait(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), sched, and sched_lock.
11473 { 11474 int count; 11475 int res; 11476 struct timeval wait; 11477 struct timespec ts; 11478 11479 for (;;) { 11480 pthread_testcancel(); 11481 ast_mutex_lock(&sched_lock); 11482 res = ast_sched_wait(sched); 11483 if ((res > 1000) || (res < 0)) 11484 res = 1000; 11485 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 11486 ts.tv_sec = wait.tv_sec; 11487 ts.tv_nsec = wait.tv_usec * 1000; 11488 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 11489 ast_mutex_unlock(&sched_lock); 11490 pthread_testcancel(); 11491 11492 count = ast_sched_runq(sched); 11493 if (count >= 20) 11494 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 11495 } 11496 11497 return NULL; 11498 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 3867 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
03868 { 03869 int type, len; 03870 int ret; 03871 int needfree = 0; 03872 struct ast_channel *owner = NULL; 03873 struct ast_channel *bridge = NULL; 03874 03875 /* Attempt to recover wrapped timestamps */ 03876 unwrap_timestamp(fr); 03877 03878 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03879 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03880 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03881 else { 03882 #if 0 03883 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03884 #endif 03885 fr->af.delivery = ast_tv(0,0); 03886 } 03887 03888 type = JB_TYPE_CONTROL; 03889 len = 0; 03890 03891 if(fr->af.frametype == AST_FRAME_VOICE) { 03892 type = JB_TYPE_VOICE; 03893 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03894 } else if(fr->af.frametype == AST_FRAME_CNG) { 03895 type = JB_TYPE_SILENCE; 03896 } 03897 03898 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 03899 if (tsout) 03900 *tsout = fr->ts; 03901 __do_deliver(fr); 03902 return -1; 03903 } 03904 03905 if ((owner = iaxs[fr->callno]->owner)) 03906 bridge = ast_bridged_channel(owner); 03907 03908 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 03909 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 03910 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 03911 jb_frame frame; 03912 03913 /* deliver any frames in the jb */ 03914 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 03915 __do_deliver(frame.data); 03916 /* __do_deliver() can make the call disappear */ 03917 if (!iaxs[fr->callno]) 03918 return -1; 03919 } 03920 03921 jb_reset(iaxs[fr->callno]->jb); 03922 03923 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 03924 03925 /* deliver this frame now */ 03926 if (tsout) 03927 *tsout = fr->ts; 03928 __do_deliver(fr); 03929 return -1; 03930 } 03931 03932 /* insert into jitterbuffer */ 03933 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 03934 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 03935 calc_rxstamp(iaxs[fr->callno],fr->ts)); 03936 if (ret == JB_DROP) { 03937 needfree++; 03938 } else if (ret == JB_SCHED) { 03939 update_jbsched(iaxs[fr->callno]); 03940 } 03941 if (tsout) 03942 *tsout = fr->ts; 03943 if (needfree) { 03944 /* Free our iax frame */ 03945 iax2_frame_free(fr); 03946 return -1; 03947 } 03948 return 0; 03949 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1561 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_destroy(), iaxs, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01562 { 01563 unsigned short callno = PTR_TO_CALLNO(vid); 01564 ast_mutex_lock(&iaxsl[callno]); 01565 if (iaxs[callno]) { 01566 if (option_debug) { 01567 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01568 } 01569 iax2_destroy(callno); 01570 } 01571 ast_mutex_unlock(&iaxsl[callno]); 01572 return 0; 01573 }
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 4371 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), f, and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04374 { 04375 struct { 04376 struct ast_iax2_full_hdr f; 04377 struct iax_ie_data ied; 04378 } data; 04379 size_t size = sizeof(struct ast_iax2_full_hdr); 04380 04381 if (ied) { 04382 size += ied->pos; 04383 memcpy(&data.ied, ied->buf, ied->pos); 04384 } 04385 04386 data.f.scallno = htons(0x8000 | callno); 04387 data.f.dcallno = htons(dcallno); 04388 data.f.ts = htonl(ts); 04389 data.f.iseqno = seqno; 04390 data.f.oseqno = 0; 04391 data.f.type = AST_FRAME_IAX; 04392 data.f.csub = compress_subclass(command); 04393 04394 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04395 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6987 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().
06988 { 06989 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 06990 }
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 7006 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
07007 { 07008 int call_num = i->callno; 07009 /* It is assumed that the callno has already been locked */ 07010 iax2_predestroy(i->callno); 07011 if (!iaxs[call_num]) 07012 return -1; 07013 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07014 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7016 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07017 { 07018 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07019 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6992 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iaxs, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
06993 { 06994 int res; 06995 ast_mutex_lock(&iaxsl[callno]); 06996 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 06997 ast_mutex_unlock(&iaxsl[callno]); 06998 return res; 06999 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 7021 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07022 { 07023 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07024 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1359 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01360 { 01361 #ifdef SCHED_MULTITHREADED 01362 if (schedule_action(__send_lagrq, data)) 01363 #endif 01364 __send_lagrq(data); 01365 01366 return 0; 01367 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3070 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_debug, ast_inet_ntoa(), errno, f, handle_error(), iax_showframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, and chan_iax2_pvt::transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
03071 { 03072 int res; 03073 int callno = f->callno; 03074 03075 /* Don't send if there was an error, but return error instead */ 03076 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03077 return -1; 03078 03079 /* Called with iaxsl held */ 03080 if (iaxdebug) 03081 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)); 03082 03083 if (f->transfer) { 03084 if (iaxdebug) 03085 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03086 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03087 } else { 03088 if (iaxdebug) 03089 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03090 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03091 } 03092 if (res < 0) { 03093 if (iaxdebug) 03094 ast_debug(1, "Received error: %s\n", strerror(errno)); 03095 handle_error(); 03096 } else 03097 res = 0; 03098 03099 return res; 03100 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1314 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), do_monitor(), init_phone_step2(), and make_trunk().
01315 { 01316 #ifdef SCHED_MULTITHREADED 01317 if (schedule_action(__send_ping, data)) 01318 #endif 01319 __send_ping(data); 01320 01321 return 0; 01322 }
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 1583 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_trunk_peer::next, s, and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01584 { 01585 struct signaling_queue_entry *s = NULL; 01586 01587 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01588 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01589 free_signaling_queue_entry(s); 01590 } 01591 pvt->hold_signaling = 0; 01592 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 8570 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, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by iax2_trunk_queue(), and timing_read().
08571 { 08572 int res = 0; 08573 struct iax_frame *fr; 08574 struct ast_iax2_meta_hdr *meta; 08575 struct ast_iax2_meta_trunk_hdr *mth; 08576 int calls = 0; 08577 08578 /* Point to frame */ 08579 fr = (struct iax_frame *)tpeer->trunkdata; 08580 /* Point to meta data */ 08581 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 08582 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 08583 if (tpeer->trunkdatalen) { 08584 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 08585 meta->zeros = 0; 08586 meta->metacmd = IAX_META_TRUNK; 08587 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 08588 meta->cmddata = IAX_META_TRUNK_MINI; 08589 else 08590 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 08591 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 08592 /* And the rest of the ast_iax2 header */ 08593 fr->direction = DIRECTION_OUTGRESS; 08594 fr->retrans = -1; 08595 fr->transfer = 0; 08596 /* Any appropriate call will do */ 08597 fr->data = fr->afdata; 08598 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 08599 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 08600 calls = tpeer->calls; 08601 #if 0 08602 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)); 08603 #endif 08604 /* Reset transmit trunk side data */ 08605 tpeer->trunkdatalen = 0; 08606 tpeer->calls = 0; 08607 } 08608 if (res < 0) 08609 return res; 08610 return calls; 08611 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 12326 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_flags, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_ENCRYPT_KEYROTATE, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user, user_unref(), users, and ast_variable::value.
Referenced by load_module(), reload(), and reload_config().
12327 { 12328 struct ast_config *cfg, *ucfg; 12329 int capability=iax2_capability; 12330 struct ast_variable *v; 12331 char *cat; 12332 const char *utype; 12333 const char *tosval; 12334 int format; 12335 int portno = IAX_DEFAULT_PORTNO; 12336 int x; 12337 int mtuv; 12338 struct iax2_user *user; 12339 struct iax2_peer *peer; 12340 struct ast_netsock *ns; 12341 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 12342 #if 0 12343 static unsigned short int last_port=0; 12344 #endif 12345 12346 cfg = ast_config_load(config_file, config_flags); 12347 12348 if (!cfg) { 12349 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 12350 return -1; 12351 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 12352 ucfg = ast_config_load("users.conf", config_flags); 12353 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 12354 return 0; 12355 /* Otherwise we need to reread both files */ 12356 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12357 cfg = ast_config_load(config_file, config_flags); 12358 } else { /* iax.conf changed, gotta reread users.conf, too */ 12359 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12360 ucfg = ast_config_load("users.conf", config_flags); 12361 } 12362 12363 if (reload) { 12364 set_config_destroy(); 12365 } 12366 12367 /* Reset global codec prefs */ 12368 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 12369 12370 /* Reset Global Flags */ 12371 memset(&globalflags, 0, sizeof(globalflags)); 12372 ast_set_flag(&globalflags, IAX_RTUPDATE); 12373 ast_set_flag(&globalflags, IAX_SHRINKCALLERID); 12374 12375 /* Turns on support for key rotation during encryption. */ 12376 iax2_encryption |= IAX_ENCRYPT_KEYROTATE; 12377 #ifdef SO_NO_CHECK 12378 nochecksums = 0; 12379 #endif 12380 /* Reset default parking lot */ 12381 default_parkinglot[0] = '\0'; 12382 12383 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12384 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12385 global_max_trunk_mtu = MAX_TRUNK_MTU; 12386 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 12387 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 12388 12389 maxauthreq = 3; 12390 12391 srvlookup = 0; 12392 12393 v = ast_variable_browse(cfg, "general"); 12394 12395 /* Seed initial tos value */ 12396 tosval = ast_variable_retrieve(cfg, "general", "tos"); 12397 if (tosval) { 12398 if (ast_str2tos(tosval, &qos.tos)) 12399 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 12400 } 12401 /* Seed initial cos value */ 12402 tosval = ast_variable_retrieve(cfg, "general", "cos"); 12403 if (tosval) { 12404 if (ast_str2cos(tosval, &qos.cos)) 12405 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 12406 } 12407 while(v) { 12408 if (!strcasecmp(v->name, "bindport")){ 12409 if (reload) 12410 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 12411 else 12412 portno = atoi(v->value); 12413 } else if (!strcasecmp(v->name, "pingtime")) 12414 ping_time = atoi(v->value); 12415 else if (!strcasecmp(v->name, "iaxthreadcount")) { 12416 if (reload) { 12417 if (atoi(v->value) != iaxthreadcount) 12418 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 12419 } else { 12420 iaxthreadcount = atoi(v->value); 12421 if (iaxthreadcount < 1) { 12422 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 12423 iaxthreadcount = 1; 12424 } else if (iaxthreadcount > 256) { 12425 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 12426 iaxthreadcount = 256; 12427 } 12428 } 12429 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 12430 if (reload) { 12431 AST_LIST_LOCK(&dynamic_list); 12432 iaxmaxthreadcount = atoi(v->value); 12433 AST_LIST_UNLOCK(&dynamic_list); 12434 } else { 12435 iaxmaxthreadcount = atoi(v->value); 12436 if (iaxmaxthreadcount < 0) { 12437 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 12438 iaxmaxthreadcount = 0; 12439 } else if (iaxmaxthreadcount > 256) { 12440 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 12441 iaxmaxthreadcount = 256; 12442 } 12443 } 12444 } else if (!strcasecmp(v->name, "nochecksums")) { 12445 #ifdef SO_NO_CHECK 12446 if (ast_true(v->value)) 12447 nochecksums = 1; 12448 else 12449 nochecksums = 0; 12450 #else 12451 if (ast_true(v->value)) 12452 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 12453 #endif 12454 } 12455 else if (!strcasecmp(v->name, "maxjitterbuffer")) 12456 maxjitterbuffer = atoi(v->value); 12457 else if (!strcasecmp(v->name, "resyncthreshold")) 12458 resyncthreshold = atoi(v->value); 12459 else if (!strcasecmp(v->name, "maxjitterinterps")) 12460 maxjitterinterps = atoi(v->value); 12461 else if (!strcasecmp(v->name, "jittertargetextra")) 12462 jittertargetextra = atoi(v->value); 12463 else if (!strcasecmp(v->name, "lagrqtime")) 12464 lagrq_time = atoi(v->value); 12465 else if (!strcasecmp(v->name, "maxregexpire")) 12466 max_reg_expire = atoi(v->value); 12467 else if (!strcasecmp(v->name, "minregexpire")) 12468 min_reg_expire = atoi(v->value); 12469 else if (!strcasecmp(v->name, "bindaddr")) { 12470 if (reload) { 12471 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 12472 } else { 12473 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 12474 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 12475 } else { 12476 if (strchr(v->value, ':')) 12477 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 12478 else 12479 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 12480 if (defaultsockfd < 0) 12481 defaultsockfd = ast_netsock_sockfd(ns); 12482 ast_netsock_unref(ns); 12483 } 12484 } 12485 } else if (!strcasecmp(v->name, "authdebug")) 12486 authdebug = ast_true(v->value); 12487 else if (!strcasecmp(v->name, "encryption")) 12488 iax2_encryption |= get_encrypt_methods(v->value); 12489 else if (!strcasecmp(v->name, "transfer")) { 12490 if (!strcasecmp(v->value, "mediaonly")) { 12491 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12492 } else if (ast_true(v->value)) { 12493 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12494 } else 12495 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12496 } else if (!strcasecmp(v->name, "codecpriority")) { 12497 if(!strcasecmp(v->value, "caller")) 12498 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 12499 else if(!strcasecmp(v->value, "disabled")) 12500 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12501 else if(!strcasecmp(v->value, "reqonly")) { 12502 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 12503 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12504 } 12505 } else if (!strcasecmp(v->name, "jitterbuffer")) 12506 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 12507 else if (!strcasecmp(v->name, "forcejitterbuffer")) 12508 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 12509 else if (!strcasecmp(v->name, "delayreject")) 12510 delayreject = ast_true(v->value); 12511 else if (!strcasecmp(v->name, "allowfwdownload")) 12512 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 12513 else if (!strcasecmp(v->name, "rtcachefriends")) 12514 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 12515 else if (!strcasecmp(v->name, "rtignoreregexpire")) 12516 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 12517 else if (!strcasecmp(v->name, "rtupdate")) 12518 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 12519 else if (!strcasecmp(v->name, "trunktimestamps")) 12520 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 12521 else if (!strcasecmp(v->name, "rtautoclear")) { 12522 int i = atoi(v->value); 12523 if(i > 0) 12524 global_rtautoclear = i; 12525 else 12526 i = 0; 12527 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 12528 } else if (!strcasecmp(v->name, "trunkfreq")) { 12529 trunkfreq = atoi(v->value); 12530 if (trunkfreq < 10) 12531 trunkfreq = 10; 12532 } else if (!strcasecmp(v->name, "trunkmtu")) { 12533 mtuv = atoi(v->value); 12534 if (mtuv == 0 ) 12535 global_max_trunk_mtu = 0; 12536 else if (mtuv >= 172 && mtuv < 4000) 12537 global_max_trunk_mtu = mtuv; 12538 else 12539 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 12540 mtuv, v->lineno); 12541 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 12542 trunkmaxsize = atoi(v->value); 12543 if (trunkmaxsize == 0) 12544 trunkmaxsize = MAX_TRUNKDATA; 12545 } else if (!strcasecmp(v->name, "autokill")) { 12546 if (sscanf(v->value, "%30d", &x) == 1) { 12547 if (x >= 0) 12548 autokill = x; 12549 else 12550 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 12551 } else if (ast_true(v->value)) { 12552 autokill = DEFAULT_MAXMS; 12553 } else { 12554 autokill = 0; 12555 } 12556 } else if (!strcasecmp(v->name, "bandwidth")) { 12557 if (!strcasecmp(v->value, "low")) { 12558 capability = IAX_CAPABILITY_LOWBANDWIDTH; 12559 } else if (!strcasecmp(v->value, "medium")) { 12560 capability = IAX_CAPABILITY_MEDBANDWIDTH; 12561 } else if (!strcasecmp(v->value, "high")) { 12562 capability = IAX_CAPABILITY_FULLBANDWIDTH; 12563 } else 12564 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 12565 } else if (!strcasecmp(v->name, "allow")) { 12566 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 12567 } else if (!strcasecmp(v->name, "disallow")) { 12568 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 12569 } else if (!strcasecmp(v->name, "register")) { 12570 iax2_register(v->value, v->lineno); 12571 } else if (!strcasecmp(v->name, "iaxcompat")) { 12572 iaxcompat = ast_true(v->value); 12573 } else if (!strcasecmp(v->name, "regcontext")) { 12574 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12575 /* Create context if it doesn't exist already */ 12576 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 12577 } else if (!strcasecmp(v->name, "tos")) { 12578 if (ast_str2tos(v->value, &qos.tos)) 12579 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 12580 } else if (!strcasecmp(v->name, "cos")) { 12581 if (ast_str2cos(v->value, &qos.cos)) 12582 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 12583 } else if (!strcasecmp(v->name, "parkinglot")) { 12584 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 12585 } else if (!strcasecmp(v->name, "accountcode")) { 12586 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 12587 } else if (!strcasecmp(v->name, "mohinterpret")) { 12588 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 12589 } else if (!strcasecmp(v->name, "mohsuggest")) { 12590 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 12591 } else if (!strcasecmp(v->name, "amaflags")) { 12592 format = ast_cdr_amaflags2int(v->value); 12593 if (format < 0) { 12594 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12595 } else { 12596 amaflags = format; 12597 } 12598 } else if (!strcasecmp(v->name, "language")) { 12599 ast_copy_string(language, v->value, sizeof(language)); 12600 } else if (!strcasecmp(v->name, "maxauthreq")) { 12601 maxauthreq = atoi(v->value); 12602 if (maxauthreq < 0) 12603 maxauthreq = 0; 12604 } else if (!strcasecmp(v->name, "adsi")) { 12605 adsi = ast_true(v->value); 12606 } else if (!strcasecmp(v->name, "srvlookup")) { 12607 srvlookup = ast_true(v->value); 12608 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12609 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 12610 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 12611 } 12612 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 12613 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 12614 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); 12615 } 12616 } else if (!strcasecmp(v->name, "calltokenoptional")) { 12617 if (add_calltoken_ignore(v->value)) { 12618 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 12619 } 12620 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 12621 if (ast_true(v->value)) { 12622 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 12623 } else if (ast_false(v->value)) { 12624 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID); 12625 } else { 12626 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 12627 } 12628 }/*else if (strcasecmp(v->name,"type")) */ 12629 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12630 v = v->next; 12631 } 12632 12633 if (defaultsockfd < 0) { 12634 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 12635 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 12636 } else { 12637 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 12638 defaultsockfd = ast_netsock_sockfd(ns); 12639 ast_netsock_unref(ns); 12640 } 12641 } 12642 if (reload) { 12643 ast_netsock_release(outsock); 12644 outsock = ast_netsock_list_alloc(); 12645 if (!outsock) { 12646 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12647 return -1; 12648 } 12649 ast_netsock_init(outsock); 12650 } 12651 12652 if (min_reg_expire > max_reg_expire) { 12653 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 12654 min_reg_expire, max_reg_expire, max_reg_expire); 12655 min_reg_expire = max_reg_expire; 12656 } 12657 iax2_capability = capability; 12658 12659 if (ucfg) { 12660 struct ast_variable *gen; 12661 int genhasiax; 12662 int genregisteriax; 12663 const char *hasiax, *registeriax; 12664 12665 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 12666 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 12667 gen = ast_variable_browse(ucfg, "general"); 12668 cat = ast_category_browse(ucfg, NULL); 12669 while (cat) { 12670 if (strcasecmp(cat, "general")) { 12671 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 12672 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 12673 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 12674 /* Start with general parameters, then specific parameters, user and peer */ 12675 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 12676 if (user) { 12677 ao2_link(users, user); 12678 user = user_unref(user); 12679 } 12680 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 12681 if (peer) { 12682 if (ast_test_flag(peer, IAX_DYNAMIC)) 12683 reg_source_db(peer); 12684 ao2_link(peers, peer); 12685 peer = peer_unref(peer); 12686 } 12687 } 12688 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 12689 char tmp[256]; 12690 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 12691 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 12692 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 12693 if (!host) 12694 host = ast_variable_retrieve(ucfg, "general", "host"); 12695 if (!username) 12696 username = ast_variable_retrieve(ucfg, "general", "username"); 12697 if (!secret) 12698 secret = ast_variable_retrieve(ucfg, "general", "secret"); 12699 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 12700 if (!ast_strlen_zero(secret)) 12701 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 12702 else 12703 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 12704 iax2_register(tmp, 0); 12705 } 12706 } 12707 } 12708 cat = ast_category_browse(ucfg, cat); 12709 } 12710 ast_config_destroy(ucfg); 12711 } 12712 12713 cat = ast_category_browse(cfg, NULL); 12714 while(cat) { 12715 if (strcasecmp(cat, "general")) { 12716 utype = ast_variable_retrieve(cfg, cat, "type"); 12717 if (!strcasecmp(cat, "callnumberlimits")) { 12718 build_callno_limits(ast_variable_browse(cfg, cat)); 12719 } else if (utype) { 12720 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12721 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 12722 if (user) { 12723 ao2_link(users, user); 12724 user = user_unref(user); 12725 } 12726 } 12727 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12728 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 12729 if (peer) { 12730 if (ast_test_flag(peer, IAX_DYNAMIC)) 12731 reg_source_db(peer); 12732 ao2_link(peers, peer); 12733 peer = peer_unref(peer); 12734 } 12735 } else if (strcasecmp(utype, "user")) { 12736 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 12737 } 12738 } else 12739 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12740 } 12741 cat = ast_category_browse(cfg, cat); 12742 } 12743 ast_config_destroy(cfg); 12744 return 1; 12745 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12307 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
12308 { 12309 strcpy(accountcode, ""); 12310 strcpy(language, ""); 12311 strcpy(mohinterpret, "default"); 12312 strcpy(mohsuggest, ""); 12313 trunkmaxsize = MAX_TRUNKDATA; 12314 amaflags = 0; 12315 delayreject = 0; 12316 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 12317 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 12318 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 12319 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 12320 delete_users(); 12321 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12322 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12323 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1995 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), callno_limits, addr_range::limit, peercnt::limit, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
01996 { 01997 uint16_t limit = global_maxcallno; 01998 struct addr_range *addr_range; 01999 struct sockaddr_in sin = { 02000 .sin_addr.s_addr = peercnt->addr, 02001 }; 02002 02003 02004 if (peercnt->reg && peercnt->limit) { 02005 return; /* this peercnt has a custom limit set by a registration */ 02006 } 02007 02008 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02009 limit = addr_range->limit; 02010 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02011 ao2_ref(addr_range, -1); 02012 } 02013 02014 peercnt->limit = limit; 02015 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2021 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02022 { 02023 struct peercnt *peercnt = obj; 02024 02025 set_peercnt_limit(peercnt); 02026 ast_debug(1, "Reset limits for peercnts table\n"); 02027 02028 return 0; 02029 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 911 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_process_thread(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and socket_read().
00912 { 00913 ast_mutex_lock(lock); 00914 ast_cond_signal(cond); 00915 ast_mutex_unlock(lock); 00916 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9294 of file chan_iax2.c.
References ast_aes_decrypt_key, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, iax_frame::list, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_OR, save_osptoken(), save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames().
09295 { 09296 struct sockaddr_in sin; 09297 int res; 09298 int updatehistory=1; 09299 int new = NEW_PREVENT; 09300 int dcallno = 0; 09301 char decrypted = 0; 09302 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09303 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09304 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09305 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09306 struct iax_frame *fr; 09307 struct iax_frame *cur; 09308 struct ast_frame f = { 0, }; 09309 struct ast_channel *c = NULL; 09310 struct iax2_dpcache *dp; 09311 struct iax2_peer *peer; 09312 struct iax_ies ies; 09313 struct iax_ie_data ied0, ied1; 09314 int format; 09315 int fd; 09316 int exists; 09317 int minivid = 0; 09318 char empty[32]=""; /* Safety measure */ 09319 struct iax_frame *duped_fr; 09320 char host_pref_buf[128]; 09321 char caller_pref_buf[128]; 09322 struct ast_codec_pref pref; 09323 char *using_prefs = "mine"; 09324 09325 /* allocate an iax_frame with 4096 bytes of data buffer */ 09326 fr = alloca(sizeof(*fr) + 4096); 09327 memset(fr, 0, sizeof(*fr)); 09328 fr->afdatalen = 4096; /* From alloca() above */ 09329 09330 /* Copy frequently used parameters to the stack */ 09331 res = thread->buf_len; 09332 fd = thread->iofd; 09333 memcpy(&sin, &thread->iosin, sizeof(sin)); 09334 09335 if (res < sizeof(*mh)) { 09336 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09337 return 1; 09338 } 09339 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09340 if (res < sizeof(*vh)) { 09341 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)); 09342 return 1; 09343 } 09344 09345 /* This is a video frame, get call number */ 09346 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09347 minivid = 1; 09348 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09349 return socket_process_meta(res, meta, &sin, fd, fr); 09350 09351 #ifdef DEBUG_SUPPORT 09352 if (res >= sizeof(*fh)) 09353 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09354 #endif 09355 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09356 if (res < sizeof(*fh)) { 09357 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)); 09358 return 1; 09359 } 09360 09361 /* Get the destination call number */ 09362 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09363 09364 09365 /* check to make sure this full frame isn't encrypted before we attempt 09366 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09367 * callno is not found here, that just means one hasn't been allocated for 09368 * this connection yet. */ 09369 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09370 ast_mutex_lock(&iaxsl[fr->callno]); 09371 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 09372 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09373 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09374 ast_mutex_unlock(&iaxsl[fr->callno]); 09375 return 1; 09376 } 09377 decrypted = 1; 09378 } 09379 ast_mutex_unlock(&iaxsl[fr->callno]); 09380 } 09381 09382 /* Retrieve the type and subclass */ 09383 f.frametype = fh->type; 09384 if (f.frametype == AST_FRAME_VIDEO) { 09385 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09386 } else { 09387 f.subclass = uncompress_subclass(fh->csub); 09388 } 09389 09390 /* Deal with POKE/PONG without allocating a callno */ 09391 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 09392 /* Reply back with a PONG, but don't care about the result. */ 09393 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09394 return 1; 09395 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 09396 /* Ignore */ 09397 return 1; 09398 } 09399 09400 f.datalen = res - sizeof(*fh); 09401 if (f.datalen) { 09402 if (f.frametype == AST_FRAME_IAX) { 09403 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09404 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09405 return 1; 09406 } 09407 f.data.ptr = NULL; 09408 f.datalen = 0; 09409 } else { 09410 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09411 memset(&ies, 0, sizeof(ies)); 09412 } 09413 } else { 09414 if (f.frametype == AST_FRAME_IAX) 09415 f.data.ptr = NULL; 09416 else 09417 f.data.ptr = empty; 09418 memset(&ies, 0, sizeof(ies)); 09419 } 09420 09421 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 09422 /* only set NEW_ALLOW if calltoken checks out */ 09423 if (handle_call_token(fh, &ies, &sin, fd)) { 09424 return 1; 09425 } 09426 09427 if (ies.calltoken && ies.calltokendata) { 09428 /* if we've gotten this far, and the calltoken ie data exists, 09429 * then calltoken validation _MUST_ have taken place. If calltoken 09430 * data is provided, it is always validated reguardless of any 09431 * calltokenoptional or requirecalltoken options */ 09432 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 09433 } else { 09434 new = NEW_ALLOW; 09435 } 09436 } 09437 } else { 09438 /* Don't know anything about it yet */ 09439 f.frametype = AST_FRAME_NULL; 09440 f.subclass = 0; 09441 } 09442 09443 if (!fr->callno) { 09444 int check_dcallno = 0; 09445 09446 /* 09447 * We enforce accurate destination call numbers for ACKs. This forces the other 09448 * end to know the destination call number before call setup can complete. 09449 * 09450 * Discussed in the following thread: 09451 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 09452 */ 09453 09454 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) { 09455 check_dcallno = 1; 09456 } 09457 09458 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 09459 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 09460 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09461 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 09462 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09463 } 09464 return 1; 09465 } 09466 } 09467 09468 if (fr->callno > 0) 09469 ast_mutex_lock(&iaxsl[fr->callno]); 09470 09471 if (!fr->callno || !iaxs[fr->callno]) { 09472 /* A call arrived for a nonexistent destination. Unless it's an "inval" 09473 frame, reply with an inval */ 09474 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09475 /* We can only raw hangup control frames */ 09476 if (((f.subclass != IAX_COMMAND_INVAL) && 09477 (f.subclass != IAX_COMMAND_TXCNT) && 09478 (f.subclass != IAX_COMMAND_TXACC) && 09479 (f.subclass != IAX_COMMAND_FWDOWNL))|| 09480 (f.frametype != AST_FRAME_IAX)) 09481 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 09482 fd); 09483 } 09484 if (fr->callno > 0) 09485 ast_mutex_unlock(&iaxsl[fr->callno]); 09486 return 1; 09487 } 09488 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 09489 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09490 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09491 ast_mutex_unlock(&iaxsl[fr->callno]); 09492 return 1; 09493 } 09494 decrypted = 1; 09495 } 09496 #ifdef DEBUG_SUPPORT 09497 if (decrypted) { 09498 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 09499 } 09500 #endif 09501 09502 /* count this frame */ 09503 iaxs[fr->callno]->frames_received++; 09504 09505 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 09506 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 09507 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 09508 unsigned short new_peercallno; 09509 09510 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 09511 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 09512 if (iaxs[fr->callno]->peercallno) { 09513 remove_by_peercallno(iaxs[fr->callno]); 09514 } 09515 iaxs[fr->callno]->peercallno = new_peercallno; 09516 store_by_peercallno(iaxs[fr->callno]); 09517 } 09518 } 09519 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09520 if (iaxdebug) 09521 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 09522 /* Check if it's out of order (and not an ACK or INVAL) */ 09523 fr->oseqno = fh->oseqno; 09524 fr->iseqno = fh->iseqno; 09525 fr->ts = ntohl(fh->ts); 09526 #ifdef IAXTESTS 09527 if (test_resync) { 09528 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 09529 fr->ts += test_resync; 09530 } 09531 #endif /* IAXTESTS */ 09532 #if 0 09533 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 09534 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 09535 (f.subclass == IAX_COMMAND_NEW || 09536 f.subclass == IAX_COMMAND_AUTHREQ || 09537 f.subclass == IAX_COMMAND_ACCEPT || 09538 f.subclass == IAX_COMMAND_REJECT)) ) ) 09539 #endif 09540 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 09541 updatehistory = 0; 09542 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 09543 (iaxs[fr->callno]->iseqno || 09544 ((f.subclass != IAX_COMMAND_TXCNT) && 09545 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09546 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09547 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09548 (f.subclass != IAX_COMMAND_TXACC)) || 09549 (f.frametype != AST_FRAME_IAX))) { 09550 if ( 09551 ((f.subclass != IAX_COMMAND_ACK) && 09552 (f.subclass != IAX_COMMAND_INVAL) && 09553 (f.subclass != IAX_COMMAND_TXCNT) && 09554 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09555 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09556 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09557 (f.subclass != IAX_COMMAND_TXACC) && 09558 (f.subclass != IAX_COMMAND_VNAK)) || 09559 (f.frametype != AST_FRAME_IAX)) { 09560 /* If it's not an ACK packet, it's out of order. */ 09561 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 09562 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 09563 /* Check to see if we need to request retransmission, 09564 * and take sequence number wraparound into account */ 09565 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 09566 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 09567 if ((f.frametype != AST_FRAME_IAX) || 09568 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 09569 ast_debug(1, "Acking anyway\n"); 09570 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 09571 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 09572 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09573 } 09574 } else { 09575 /* Send a VNAK requesting retransmission */ 09576 iax2_vnak(fr->callno); 09577 } 09578 ast_mutex_unlock(&iaxsl[fr->callno]); 09579 return 1; 09580 } 09581 } else { 09582 /* Increment unless it's an ACK or VNAK */ 09583 if (((f.subclass != IAX_COMMAND_ACK) && 09584 (f.subclass != IAX_COMMAND_INVAL) && 09585 (f.subclass != IAX_COMMAND_TXCNT) && 09586 (f.subclass != IAX_COMMAND_TXACC) && 09587 (f.subclass != IAX_COMMAND_VNAK)) || 09588 (f.frametype != AST_FRAME_IAX)) 09589 iaxs[fr->callno]->iseqno++; 09590 } 09591 /* Ensure text frames are NULL-terminated */ 09592 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 09593 if (res < thread->buf_size) 09594 thread->buf[res++] = '\0'; 09595 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 09596 thread->buf[res - 1] = '\0'; 09597 } 09598 09599 /* Handle implicit ACKing unless this is an INVAL, and only if this is 09600 from the real peer, not the transfer peer */ 09601 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09602 ((f.subclass != IAX_COMMAND_INVAL) || 09603 (f.frametype != AST_FRAME_IAX))) { 09604 unsigned char x; 09605 int call_to_destroy; 09606 /* First we have to qualify that the ACKed value is within our window */ 09607 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 09608 x = fr->iseqno; 09609 else 09610 x = iaxs[fr->callno]->oseqno; 09611 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 09612 /* The acknowledgement is within our window. Time to acknowledge everything 09613 that it says to */ 09614 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 09615 /* Ack the packet with the given timestamp */ 09616 if (iaxdebug) 09617 ast_debug(1, "Cancelling transmission of packet %d\n", x); 09618 call_to_destroy = 0; 09619 AST_LIST_LOCK(&frame_queue); 09620 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 09621 /* If it's our call, and our timestamp, mark -1 retries */ 09622 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 09623 cur->retries = -1; 09624 /* Destroy call if this is the end */ 09625 if (cur->final) 09626 call_to_destroy = fr->callno; 09627 } 09628 } 09629 AST_LIST_UNLOCK(&frame_queue); 09630 if (call_to_destroy) { 09631 if (iaxdebug) 09632 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 09633 ast_mutex_lock(&iaxsl[call_to_destroy]); 09634 iax2_destroy(call_to_destroy); 09635 ast_mutex_unlock(&iaxsl[call_to_destroy]); 09636 } 09637 } 09638 /* Note how much we've received acknowledgement for */ 09639 if (iaxs[fr->callno]) 09640 iaxs[fr->callno]->rseqno = fr->iseqno; 09641 else { 09642 /* Stop processing now */ 09643 ast_mutex_unlock(&iaxsl[fr->callno]); 09644 return 1; 09645 } 09646 } else { 09647 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 09648 } 09649 } 09650 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09651 ((f.frametype != AST_FRAME_IAX) || 09652 ((f.subclass != IAX_COMMAND_TXACC) && 09653 (f.subclass != IAX_COMMAND_TXCNT)))) { 09654 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 09655 ast_mutex_unlock(&iaxsl[fr->callno]); 09656 return 1; 09657 } 09658 09659 /* when we receive the first full frame for a new incoming channel, 09660 it is safe to start the PBX on the channel because we have now 09661 completed a 3-way handshake with the peer */ 09662 if ((f.frametype == AST_FRAME_VOICE) || 09663 (f.frametype == AST_FRAME_VIDEO) || 09664 (f.frametype == AST_FRAME_IAX)) { 09665 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 09666 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09667 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 09668 ast_mutex_unlock(&iaxsl[fr->callno]); 09669 return 1; 09670 } 09671 } 09672 09673 if (ies.vars) { 09674 struct ast_datastore *variablestore = NULL; 09675 struct ast_variable *var, *prev = NULL; 09676 AST_LIST_HEAD(, ast_var_t) *varlist; 09677 if ((c = iaxs[fr->callno]->owner)) { 09678 varlist = ast_calloc(1, sizeof(*varlist)); 09679 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09680 09681 if (variablestore && varlist) { 09682 variablestore->data = varlist; 09683 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09684 AST_LIST_HEAD_INIT(varlist); 09685 ast_debug(1, "I can haz IAX vars?\n"); 09686 for (var = ies.vars; var; var = var->next) { 09687 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 09688 if (prev) { 09689 ast_free(prev); 09690 } 09691 prev = var; 09692 if (!newvar) { 09693 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 09694 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09695 } else { 09696 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 09697 } 09698 } 09699 if (prev) { 09700 ast_free(prev); 09701 } 09702 ies.vars = NULL; 09703 ast_channel_datastore_add(c, variablestore); 09704 } else { 09705 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09706 if (variablestore) { 09707 ast_datastore_free(variablestore); 09708 } 09709 if (varlist) { 09710 ast_free(varlist); 09711 } 09712 } 09713 } else { 09714 /* No channel yet, so transfer the variables directly over to the pvt, 09715 * for later inheritance. */ 09716 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 09717 for (var = ies.vars; var && var->next; var = var->next); 09718 if (var) { 09719 var->next = iaxs[fr->callno]->iaxvars; 09720 iaxs[fr->callno]->iaxvars = ies.vars; 09721 ies.vars = NULL; 09722 } 09723 } 09724 } 09725 09726 if (ies.vars) { 09727 ast_debug(1, "I have IAX variables, but they were not processed\n"); 09728 } 09729 } 09730 09731 /* once we receive our first IAX Full Frame that is not CallToken related, send all 09732 * queued signaling frames that were being held. */ 09733 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 09734 send_signaling(iaxs[fr->callno]); 09735 } 09736 09737 if (f.frametype == AST_FRAME_VOICE) { 09738 if (f.subclass != iaxs[fr->callno]->voiceformat) { 09739 iaxs[fr->callno]->voiceformat = f.subclass; 09740 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass); 09741 if (iaxs[fr->callno]->owner) { 09742 int orignative; 09743 retryowner: 09744 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 09745 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 09746 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 09747 } 09748 if (iaxs[fr->callno]) { 09749 if (iaxs[fr->callno]->owner) { 09750 orignative = iaxs[fr->callno]->owner->nativeformats; 09751 iaxs[fr->callno]->owner->nativeformats = f.subclass; 09752 if (iaxs[fr->callno]->owner->readformat) 09753 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09754 iaxs[fr->callno]->owner->nativeformats = orignative; 09755 ast_channel_unlock(iaxs[fr->callno]->owner); 09756 } 09757 } else { 09758 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 09759 /* Free remote variables (if any) */ 09760 if (ies.vars) { 09761 ast_variables_destroy(ies.vars); 09762 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 09763 ies.vars = NULL; 09764 } 09765 ast_mutex_unlock(&iaxsl[fr->callno]); 09766 return 1; 09767 } 09768 } 09769 } 09770 } 09771 if (f.frametype == AST_FRAME_VIDEO) { 09772 if (f.subclass != iaxs[fr->callno]->videoformat) { 09773 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 09774 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 09775 } 09776 } 09777 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 09778 if (f.subclass == AST_CONTROL_BUSY) { 09779 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 09780 } else if (f.subclass == AST_CONTROL_CONGESTION) { 09781 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 09782 } 09783 } 09784 if (f.frametype == AST_FRAME_IAX) { 09785 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 09786 /* Handle the IAX pseudo frame itself */ 09787 if (iaxdebug) 09788 ast_debug(1, "IAX subclass %d received\n", f.subclass); 09789 09790 /* Update last ts unless the frame's timestamp originated with us. */ 09791 if (iaxs[fr->callno]->last < fr->ts && 09792 f.subclass != IAX_COMMAND_ACK && 09793 f.subclass != IAX_COMMAND_PONG && 09794 f.subclass != IAX_COMMAND_LAGRP) { 09795 iaxs[fr->callno]->last = fr->ts; 09796 if (iaxdebug) 09797 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 09798 } 09799 iaxs[fr->callno]->last_iax_message = f.subclass; 09800 if (!iaxs[fr->callno]->first_iax_message) { 09801 iaxs[fr->callno]->first_iax_message = f.subclass; 09802 } 09803 switch(f.subclass) { 09804 case IAX_COMMAND_ACK: 09805 /* Do nothing */ 09806 break; 09807 case IAX_COMMAND_QUELCH: 09808 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09809 /* Generate Manager Hold event, if necessary*/ 09810 if (iaxs[fr->callno]->owner) { 09811 manager_event(EVENT_FLAG_CALL, "Hold", 09812 "Status: On\r\n" 09813 "Channel: %s\r\n" 09814 "Uniqueid: %s\r\n", 09815 iaxs[fr->callno]->owner->name, 09816 iaxs[fr->callno]->owner->uniqueid); 09817 } 09818 09819 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 09820 if (ies.musiconhold) { 09821 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 09822 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 09823 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 09824 S_OR(moh_suggest, NULL), 09825 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 09826 if (!iaxs[fr->callno]) { 09827 ast_mutex_unlock(&iaxsl[fr->callno]); 09828 return 1; 09829 } 09830 } 09831 } 09832 } 09833 break; 09834 case IAX_COMMAND_UNQUELCH: 09835 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09836 /* Generate Manager Unhold event, if necessary*/ 09837 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 09838 manager_event(EVENT_FLAG_CALL, "Hold", 09839 "Status: Off\r\n" 09840 "Channel: %s\r\n" 09841 "Uniqueid: %s\r\n", 09842 iaxs[fr->callno]->owner->name, 09843 iaxs[fr->callno]->owner->uniqueid); 09844 } 09845 09846 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 09847 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 09848 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 09849 if (!iaxs[fr->callno]) { 09850 ast_mutex_unlock(&iaxsl[fr->callno]); 09851 return 1; 09852 } 09853 } 09854 } 09855 break; 09856 case IAX_COMMAND_TXACC: 09857 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 09858 /* Ack the packet with the given timestamp */ 09859 AST_LIST_LOCK(&frame_queue); 09860 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 09861 /* Cancel any outstanding txcnt's */ 09862 if ((fr->callno == cur->callno) && (cur->transfer)) 09863 cur->retries = -1; 09864 } 09865 AST_LIST_UNLOCK(&frame_queue); 09866 memset(&ied1, 0, sizeof(ied1)); 09867 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 09868 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 09869 iaxs[fr->callno]->transferring = TRANSFER_READY; 09870 } 09871 break; 09872 case IAX_COMMAND_NEW: 09873 /* Ignore if it's already up */ 09874 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 09875 break; 09876 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09877 ast_mutex_unlock(&iaxsl[fr->callno]); 09878 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09879 ast_mutex_lock(&iaxsl[fr->callno]); 09880 if (!iaxs[fr->callno]) { 09881 ast_mutex_unlock(&iaxsl[fr->callno]); 09882 return 1; 09883 } 09884 } 09885 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 09886 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 09887 int new_callno; 09888 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 09889 fr->callno = new_callno; 09890 } 09891 /* For security, always ack immediately */ 09892 if (delayreject) 09893 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09894 if (check_access(fr->callno, &sin, &ies)) { 09895 /* They're not allowed on */ 09896 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09897 if (authdebug) 09898 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); 09899 break; 09900 } 09901 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09902 const char *context, *exten, *cid_num; 09903 09904 context = ast_strdupa(iaxs[fr->callno]->context); 09905 exten = ast_strdupa(iaxs[fr->callno]->exten); 09906 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 09907 09908 /* This might re-enter the IAX code and need the lock */ 09909 ast_mutex_unlock(&iaxsl[fr->callno]); 09910 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 09911 ast_mutex_lock(&iaxsl[fr->callno]); 09912 09913 if (!iaxs[fr->callno]) { 09914 ast_mutex_unlock(&iaxsl[fr->callno]); 09915 return 1; 09916 } 09917 } else 09918 exists = 0; 09919 /* Get OSP token if it does exist */ 09920 save_osptoken(fr, &ies); 09921 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 09922 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09923 memset(&ied0, 0, sizeof(ied0)); 09924 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09925 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09926 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09927 if (!iaxs[fr->callno]) { 09928 ast_mutex_unlock(&iaxsl[fr->callno]); 09929 return 1; 09930 } 09931 if (authdebug) 09932 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); 09933 } else { 09934 /* Select an appropriate format */ 09935 09936 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09937 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09938 using_prefs = "reqonly"; 09939 } else { 09940 using_prefs = "disabled"; 09941 } 09942 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09943 memset(&pref, 0, sizeof(pref)); 09944 strcpy(caller_pref_buf, "disabled"); 09945 strcpy(host_pref_buf, "disabled"); 09946 } else { 09947 using_prefs = "mine"; 09948 /* If the information elements are in here... use them */ 09949 if (ies.codec_prefs) 09950 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09951 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09952 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 09953 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09954 pref = iaxs[fr->callno]->rprefs; 09955 using_prefs = "caller"; 09956 } else { 09957 pref = iaxs[fr->callno]->prefs; 09958 } 09959 } else 09960 pref = iaxs[fr->callno]->prefs; 09961 09962 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09963 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09964 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09965 } 09966 if (!format) { 09967 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09968 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09969 if (!format) { 09970 memset(&ied0, 0, sizeof(ied0)); 09971 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09972 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09973 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09974 if (!iaxs[fr->callno]) { 09975 ast_mutex_unlock(&iaxsl[fr->callno]); 09976 return 1; 09977 } 09978 if (authdebug) { 09979 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09980 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); 09981 else 09982 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); 09983 } 09984 } else { 09985 /* Pick one... */ 09986 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09987 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09988 format = 0; 09989 } else { 09990 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09991 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09992 memset(&pref, 0, sizeof(pref)); 09993 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09994 strcpy(caller_pref_buf,"disabled"); 09995 strcpy(host_pref_buf,"disabled"); 09996 } else { 09997 using_prefs = "mine"; 09998 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09999 /* Do the opposite of what we tried above. */ 10000 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10001 pref = iaxs[fr->callno]->prefs; 10002 } else { 10003 pref = iaxs[fr->callno]->rprefs; 10004 using_prefs = "caller"; 10005 } 10006 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10007 10008 } else /* if no codec_prefs IE do it the old way */ 10009 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10010 } 10011 } 10012 10013 if (!format) { 10014 memset(&ied0, 0, sizeof(ied0)); 10015 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10016 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10017 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10018 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10019 if (!iaxs[fr->callno]) { 10020 ast_mutex_unlock(&iaxsl[fr->callno]); 10021 return 1; 10022 } 10023 if (authdebug) 10024 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); 10025 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10026 break; 10027 } 10028 } 10029 } 10030 if (format) { 10031 /* No authentication required, let them in */ 10032 memset(&ied1, 0, sizeof(ied1)); 10033 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10034 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10035 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10036 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10037 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10038 "%srequested format = %s,\n" 10039 "%srequested prefs = %s,\n" 10040 "%sactual format = %s,\n" 10041 "%shost prefs = %s,\n" 10042 "%spriority = %s\n", 10043 ast_inet_ntoa(sin.sin_addr), 10044 VERBOSE_PREFIX_4, 10045 ast_getformatname(iaxs[fr->callno]->peerformat), 10046 VERBOSE_PREFIX_4, 10047 caller_pref_buf, 10048 VERBOSE_PREFIX_4, 10049 ast_getformatname(format), 10050 VERBOSE_PREFIX_4, 10051 host_pref_buf, 10052 VERBOSE_PREFIX_4, 10053 using_prefs); 10054 10055 iaxs[fr->callno]->chosenformat = format; 10056 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 10057 } else { 10058 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10059 /* If this is a TBD call, we're ready but now what... */ 10060 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10061 } 10062 } 10063 } 10064 break; 10065 } 10066 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10067 merge_encryption(iaxs[fr->callno],ies.encmethods); 10068 else 10069 iaxs[fr->callno]->encmethods = 0; 10070 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10071 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10072 if (!iaxs[fr->callno]) { 10073 ast_mutex_unlock(&iaxsl[fr->callno]); 10074 return 1; 10075 } 10076 break; 10077 case IAX_COMMAND_DPREQ: 10078 /* Request status in the dialplan */ 10079 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10080 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10081 if (iaxcompat) { 10082 /* Spawn a thread for the lookup */ 10083 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10084 } else { 10085 /* Just look it up */ 10086 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10087 } 10088 } 10089 break; 10090 case IAX_COMMAND_HANGUP: 10091 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10092 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10093 /* Set hangup cause according to remote */ 10094 if (ies.causecode && iaxs[fr->callno]->owner) 10095 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10096 /* Send ack immediately, before we destroy */ 10097 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10098 iax2_destroy(fr->callno); 10099 break; 10100 case IAX_COMMAND_REJECT: 10101 /* Set hangup cause according to remote */ 10102 if (ies.causecode && iaxs[fr->callno]->owner) 10103 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10104 10105 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10106 if (iaxs[fr->callno]->owner && authdebug) 10107 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10108 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10109 ies.cause ? ies.cause : "<Unknown>"); 10110 ast_debug(1, "Immediately destroying %d, having received reject\n", 10111 fr->callno); 10112 } 10113 /* Send ack immediately, before we destroy */ 10114 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10115 fr->ts, NULL, 0, fr->iseqno); 10116 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 10117 iaxs[fr->callno]->error = EPERM; 10118 iax2_destroy(fr->callno); 10119 break; 10120 case IAX_COMMAND_TRANSFER: 10121 { 10122 struct ast_channel *bridged_chan; 10123 10124 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 10125 /* Set BLINDTRANSFER channel variables */ 10126 10127 ast_mutex_unlock(&iaxsl[fr->callno]); 10128 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 10129 ast_mutex_lock(&iaxsl[fr->callno]); 10130 if (!iaxs[fr->callno]) { 10131 ast_mutex_unlock(&iaxsl[fr->callno]); 10132 return 1; 10133 } 10134 10135 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 10136 if (!strcmp(ies.called_number, ast_parking_ext())) { 10137 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 10138 ast_mutex_unlock(&iaxsl[fr->callno]); 10139 if (iax_park(bridged_chan, saved_channel)) { 10140 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 10141 } else { 10142 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 10143 } 10144 ast_mutex_lock(&iaxsl[fr->callno]); 10145 } else { 10146 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 10147 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 10148 ies.called_number, iaxs[fr->callno]->context); 10149 else { 10150 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 10151 ies.called_number, iaxs[fr->callno]->context); 10152 } 10153 } 10154 } else { 10155 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10156 } 10157 10158 break; 10159 } 10160 case IAX_COMMAND_ACCEPT: 10161 /* Ignore if call is already up or needs authentication or is a TBD */ 10162 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10163 break; 10164 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10165 /* Send ack immediately, before we destroy */ 10166 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10167 iax2_destroy(fr->callno); 10168 break; 10169 } 10170 if (ies.format) { 10171 iaxs[fr->callno]->peerformat = ies.format; 10172 } else { 10173 if (iaxs[fr->callno]->owner) 10174 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10175 else 10176 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10177 } 10178 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)); 10179 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10180 memset(&ied0, 0, sizeof(ied0)); 10181 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10182 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10183 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10184 if (!iaxs[fr->callno]) { 10185 ast_mutex_unlock(&iaxsl[fr->callno]); 10186 return 1; 10187 } 10188 if (authdebug) 10189 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); 10190 } else { 10191 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10192 if (iaxs[fr->callno]->owner) { 10193 /* Switch us to use a compatible format */ 10194 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10195 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10196 retryowner2: 10197 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 10198 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 10199 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 10200 } 10201 10202 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10203 /* Setup read/write formats properly. */ 10204 if (iaxs[fr->callno]->owner->writeformat) 10205 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10206 if (iaxs[fr->callno]->owner->readformat) 10207 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10208 ast_channel_unlock(iaxs[fr->callno]->owner); 10209 } 10210 } 10211 } 10212 if (iaxs[fr->callno]) { 10213 AST_LIST_LOCK(&dpcache); 10214 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10215 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10216 iax2_dprequest(dp, fr->callno); 10217 AST_LIST_UNLOCK(&dpcache); 10218 } 10219 break; 10220 case IAX_COMMAND_POKE: 10221 /* Send back a pong packet with the original timestamp */ 10222 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10223 if (!iaxs[fr->callno]) { 10224 ast_mutex_unlock(&iaxsl[fr->callno]); 10225 return 1; 10226 } 10227 break; 10228 case IAX_COMMAND_PING: 10229 { 10230 struct iax_ie_data pingied; 10231 construct_rr(iaxs[fr->callno], &pingied); 10232 /* Send back a pong packet with the original timestamp */ 10233 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10234 } 10235 break; 10236 case IAX_COMMAND_PONG: 10237 /* Calculate ping time */ 10238 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10239 /* save RR info */ 10240 save_rr(fr, &ies); 10241 10242 /* Good time to write jb stats for this call */ 10243 log_jitterstats(fr->callno); 10244 10245 if (iaxs[fr->callno]->peerpoke) { 10246 peer = iaxs[fr->callno]->peerpoke; 10247 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10248 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10249 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10250 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); 10251 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10252 } 10253 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10254 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10255 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10256 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); 10257 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10258 } 10259 } 10260 peer->lastms = iaxs[fr->callno]->pingtime; 10261 if (peer->smoothing && (peer->lastms > -1)) 10262 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10263 else if (peer->smoothing && peer->lastms < 0) 10264 peer->historicms = (0 + peer->historicms) / 2; 10265 else 10266 peer->historicms = iaxs[fr->callno]->pingtime; 10267 10268 /* Remove scheduled iax2_poke_noanswer */ 10269 if (peer->pokeexpire > -1) { 10270 if (!ast_sched_del(sched, peer->pokeexpire)) { 10271 peer_unref(peer); 10272 peer->pokeexpire = -1; 10273 } 10274 } 10275 /* Schedule the next cycle */ 10276 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10277 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10278 else 10279 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10280 if (peer->pokeexpire == -1) 10281 peer_unref(peer); 10282 /* and finally send the ack */ 10283 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10284 /* And wrap up the qualify call */ 10285 iax2_destroy(fr->callno); 10286 peer->callno = 0; 10287 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10288 } 10289 break; 10290 case IAX_COMMAND_LAGRQ: 10291 case IAX_COMMAND_LAGRP: 10292 f.src = "LAGRQ"; 10293 f.mallocd = 0; 10294 f.offset = 0; 10295 f.samples = 0; 10296 iax_frame_wrap(fr, &f); 10297 if(f.subclass == IAX_COMMAND_LAGRQ) { 10298 /* Received a LAGRQ - echo back a LAGRP */ 10299 fr->af.subclass = IAX_COMMAND_LAGRP; 10300 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10301 } else { 10302 /* Received LAGRP in response to our LAGRQ */ 10303 unsigned int ts; 10304 /* This is a reply we've been given, actually measure the difference */ 10305 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10306 iaxs[fr->callno]->lag = ts - fr->ts; 10307 if (iaxdebug) 10308 ast_debug(1, "Peer %s lag measured as %dms\n", 10309 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10310 } 10311 break; 10312 case IAX_COMMAND_AUTHREQ: 10313 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10314 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>"); 10315 break; 10316 } 10317 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10318 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10319 .subclass = AST_CONTROL_HANGUP, 10320 }; 10321 ast_log(LOG_WARNING, 10322 "I don't know how to authenticate %s to %s\n", 10323 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10324 iax2_queue_frame(fr->callno, &hangup_fr); 10325 } 10326 if (!iaxs[fr->callno]) { 10327 ast_mutex_unlock(&iaxsl[fr->callno]); 10328 return 1; 10329 } 10330 break; 10331 case IAX_COMMAND_AUTHREP: 10332 /* For security, always ack immediately */ 10333 if (delayreject) 10334 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10335 /* Ignore once we've started */ 10336 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10337 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>"); 10338 break; 10339 } 10340 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10341 if (authdebug) 10342 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); 10343 memset(&ied0, 0, sizeof(ied0)); 10344 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10345 break; 10346 } 10347 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10348 /* This might re-enter the IAX code and need the lock */ 10349 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10350 } else 10351 exists = 0; 10352 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10353 if (authdebug) 10354 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); 10355 memset(&ied0, 0, sizeof(ied0)); 10356 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10357 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10358 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10359 if (!iaxs[fr->callno]) { 10360 ast_mutex_unlock(&iaxsl[fr->callno]); 10361 return 1; 10362 } 10363 } else { 10364 /* Select an appropriate format */ 10365 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10366 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10367 using_prefs = "reqonly"; 10368 } else { 10369 using_prefs = "disabled"; 10370 } 10371 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10372 memset(&pref, 0, sizeof(pref)); 10373 strcpy(caller_pref_buf, "disabled"); 10374 strcpy(host_pref_buf, "disabled"); 10375 } else { 10376 using_prefs = "mine"; 10377 if (ies.codec_prefs) 10378 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10379 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10380 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10381 pref = iaxs[fr->callno]->rprefs; 10382 using_prefs = "caller"; 10383 } else { 10384 pref = iaxs[fr->callno]->prefs; 10385 } 10386 } else /* if no codec_prefs IE do it the old way */ 10387 pref = iaxs[fr->callno]->prefs; 10388 10389 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10390 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10391 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10392 } 10393 if (!format) { 10394 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10395 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); 10396 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10397 } 10398 if (!format) { 10399 if (authdebug) { 10400 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10401 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); 10402 else 10403 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); 10404 } 10405 memset(&ied0, 0, sizeof(ied0)); 10406 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10407 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10408 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10409 if (!iaxs[fr->callno]) { 10410 ast_mutex_unlock(&iaxsl[fr->callno]); 10411 return 1; 10412 } 10413 } else { 10414 /* Pick one... */ 10415 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10416 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10417 format = 0; 10418 } else { 10419 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10420 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10421 memset(&pref, 0, sizeof(pref)); 10422 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 10423 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10424 strcpy(caller_pref_buf,"disabled"); 10425 strcpy(host_pref_buf,"disabled"); 10426 } else { 10427 using_prefs = "mine"; 10428 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10429 /* Do the opposite of what we tried above. */ 10430 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10431 pref = iaxs[fr->callno]->prefs; 10432 } else { 10433 pref = iaxs[fr->callno]->rprefs; 10434 using_prefs = "caller"; 10435 } 10436 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10437 } else /* if no codec_prefs IE do it the old way */ 10438 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10439 } 10440 } 10441 if (!format) { 10442 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10443 if (authdebug) { 10444 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10445 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); 10446 else 10447 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); 10448 } 10449 memset(&ied0, 0, sizeof(ied0)); 10450 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10451 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10452 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10453 if (!iaxs[fr->callno]) { 10454 ast_mutex_unlock(&iaxsl[fr->callno]); 10455 return 1; 10456 } 10457 } 10458 } 10459 } 10460 if (format) { 10461 /* Authentication received */ 10462 memset(&ied1, 0, sizeof(ied1)); 10463 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10465 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10466 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10467 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 10468 "%srequested format = %s,\n" 10469 "%srequested prefs = %s,\n" 10470 "%sactual format = %s,\n" 10471 "%shost prefs = %s,\n" 10472 "%spriority = %s\n", 10473 ast_inet_ntoa(sin.sin_addr), 10474 VERBOSE_PREFIX_4, 10475 ast_getformatname(iaxs[fr->callno]->peerformat), 10476 VERBOSE_PREFIX_4, 10477 caller_pref_buf, 10478 VERBOSE_PREFIX_4, 10479 ast_getformatname(format), 10480 VERBOSE_PREFIX_4, 10481 host_pref_buf, 10482 VERBOSE_PREFIX_4, 10483 using_prefs); 10484 10485 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10486 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 10487 iax2_destroy(fr->callno); 10488 else if (ies.vars) { 10489 struct ast_datastore *variablestore; 10490 struct ast_variable *var, *prev = NULL; 10491 AST_LIST_HEAD(, ast_var_t) *varlist; 10492 varlist = ast_calloc(1, sizeof(*varlist)); 10493 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10494 if (variablestore && varlist) { 10495 variablestore->data = varlist; 10496 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10497 AST_LIST_HEAD_INIT(varlist); 10498 ast_debug(1, "I can haz IAX vars? w00t\n"); 10499 for (var = ies.vars; var; var = var->next) { 10500 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10501 if (prev) 10502 ast_free(prev); 10503 prev = var; 10504 if (!newvar) { 10505 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10506 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10507 } else { 10508 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10509 } 10510 } 10511 if (prev) 10512 ast_free(prev); 10513 ies.vars = NULL; 10514 ast_channel_datastore_add(c, variablestore); 10515 } else { 10516 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10517 if (variablestore) 10518 ast_datastore_free(variablestore); 10519 if (varlist) 10520 ast_free(varlist); 10521 } 10522 } 10523 } else { 10524 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10525 /* If this is a TBD call, we're ready but now what... */ 10526 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10527 } 10528 } 10529 } 10530 break; 10531 case IAX_COMMAND_DIAL: 10532 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 10533 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10534 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 10535 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 10536 if (authdebug) 10537 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); 10538 memset(&ied0, 0, sizeof(ied0)); 10539 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10540 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10541 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10542 if (!iaxs[fr->callno]) { 10543 ast_mutex_unlock(&iaxsl[fr->callno]); 10544 return 1; 10545 } 10546 } else { 10547 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10548 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 10549 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10550 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 10551 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 10552 iax2_destroy(fr->callno); 10553 else if (ies.vars) { 10554 struct ast_datastore *variablestore; 10555 struct ast_variable *var, *prev = NULL; 10556 AST_LIST_HEAD(, ast_var_t) *varlist; 10557 varlist = ast_calloc(1, sizeof(*varlist)); 10558 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10559 ast_debug(1, "I can haz IAX vars? w00t\n"); 10560 if (variablestore && varlist) { 10561 variablestore->data = varlist; 10562 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10563 AST_LIST_HEAD_INIT(varlist); 10564 for (var = ies.vars; var; var = var->next) { 10565 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10566 if (prev) 10567 ast_free(prev); 10568 prev = var; 10569 if (!newvar) { 10570 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10571 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10572 } else { 10573 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10574 } 10575 } 10576 if (prev) 10577 ast_free(prev); 10578 ies.vars = NULL; 10579 ast_channel_datastore_add(c, variablestore); 10580 } else { 10581 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10582 if (variablestore) 10583 ast_datastore_free(variablestore); 10584 if (varlist) 10585 ast_free(varlist); 10586 } 10587 } 10588 } 10589 } 10590 break; 10591 case IAX_COMMAND_INVAL: 10592 iaxs[fr->callno]->error = ENOTCONN; 10593 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 10594 iax2_destroy(fr->callno); 10595 ast_debug(1, "Destroying call %d\n", fr->callno); 10596 break; 10597 case IAX_COMMAND_VNAK: 10598 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 10599 /* Force retransmission */ 10600 vnak_retransmit(fr->callno, fr->iseqno); 10601 break; 10602 case IAX_COMMAND_REGREQ: 10603 case IAX_COMMAND_REGREL: 10604 /* For security, always ack immediately */ 10605 if (delayreject) 10606 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10607 if (register_verify(fr->callno, &sin, &ies)) { 10608 if (!iaxs[fr->callno]) { 10609 ast_mutex_unlock(&iaxsl[fr->callno]); 10610 return 1; 10611 } 10612 /* Send delayed failure */ 10613 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 10614 break; 10615 } 10616 if (!iaxs[fr->callno]) { 10617 ast_mutex_unlock(&iaxsl[fr->callno]); 10618 return 1; 10619 } 10620 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 10621 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 10622 10623 if (f.subclass == IAX_COMMAND_REGREL) 10624 memset(&sin, 0, sizeof(sin)); 10625 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 10626 ast_log(LOG_WARNING, "Registry error\n"); 10627 if (!iaxs[fr->callno]) { 10628 ast_mutex_unlock(&iaxsl[fr->callno]); 10629 return 1; 10630 } 10631 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10632 ast_mutex_unlock(&iaxsl[fr->callno]); 10633 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10634 ast_mutex_lock(&iaxsl[fr->callno]); 10635 if (!iaxs[fr->callno]) { 10636 ast_mutex_unlock(&iaxsl[fr->callno]); 10637 return 1; 10638 } 10639 } 10640 break; 10641 } 10642 registry_authrequest(fr->callno); 10643 if (!iaxs[fr->callno]) { 10644 ast_mutex_unlock(&iaxsl[fr->callno]); 10645 return 1; 10646 } 10647 break; 10648 case IAX_COMMAND_REGACK: 10649 if (iax2_ack_registry(&ies, &sin, fr->callno)) 10650 ast_log(LOG_WARNING, "Registration failure\n"); 10651 /* Send ack immediately, before we destroy */ 10652 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10653 iax2_destroy(fr->callno); 10654 break; 10655 case IAX_COMMAND_REGREJ: 10656 if (iaxs[fr->callno]->reg) { 10657 if (authdebug) { 10658 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)); 10659 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>"); 10660 } 10661 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 10662 } 10663 /* Send ack immediately, before we destroy */ 10664 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10665 iax2_destroy(fr->callno); 10666 break; 10667 case IAX_COMMAND_REGAUTH: 10668 /* Authentication request */ 10669 if (registry_rerequest(&ies, fr->callno, &sin)) { 10670 memset(&ied0, 0, sizeof(ied0)); 10671 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 10672 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 10673 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10674 if (!iaxs[fr->callno]) { 10675 ast_mutex_unlock(&iaxsl[fr->callno]); 10676 return 1; 10677 } 10678 } 10679 break; 10680 case IAX_COMMAND_TXREJ: 10681 iaxs[fr->callno]->transferring = 0; 10682 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10683 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 10684 if (iaxs[fr->callno]->bridgecallno) { 10685 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 10686 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 10687 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 10688 } 10689 } 10690 break; 10691 case IAX_COMMAND_TXREADY: 10692 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 10693 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 10694 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 10695 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 10696 else 10697 iaxs[fr->callno]->transferring = TRANSFER_READY; 10698 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10699 if (iaxs[fr->callno]->bridgecallno) { 10700 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 10701 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 10702 /* They're both ready, now release them. */ 10703 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 10704 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10705 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10706 10707 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 10708 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 10709 10710 memset(&ied0, 0, sizeof(ied0)); 10711 memset(&ied1, 0, sizeof(ied1)); 10712 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10713 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10714 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 10715 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 10716 } else { 10717 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10718 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10719 10720 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 10721 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 10722 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 10723 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10724 10725 /* Stop doing lag & ping requests */ 10726 stop_stuff(fr->callno); 10727 stop_stuff(iaxs[fr->callno]->bridgecallno); 10728 10729 memset(&ied0, 0, sizeof(ied0)); 10730 memset(&ied1, 0, sizeof(ied1)); 10731 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10732 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10733 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 10734 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 10735 } 10736 10737 } 10738 } 10739 } 10740 break; 10741 case IAX_COMMAND_TXREQ: 10742 try_transfer(iaxs[fr->callno], &ies); 10743 break; 10744 case IAX_COMMAND_TXCNT: 10745 if (iaxs[fr->callno]->transferring) 10746 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 10747 break; 10748 case IAX_COMMAND_TXREL: 10749 /* Send ack immediately, rather than waiting until we've changed addresses */ 10750 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10751 complete_transfer(fr->callno, &ies); 10752 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 10753 break; 10754 case IAX_COMMAND_TXMEDIA: 10755 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 10756 AST_LIST_LOCK(&frame_queue); 10757 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10758 /* Cancel any outstanding frames and start anew */ 10759 if ((fr->callno == cur->callno) && (cur->transfer)) 10760 cur->retries = -1; 10761 } 10762 AST_LIST_UNLOCK(&frame_queue); 10763 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 10764 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 10765 } 10766 break; 10767 case IAX_COMMAND_RTKEY: 10768 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 10769 ast_log(LOG_WARNING, 10770 "we've been told to rotate our encryption key, " 10771 "but this isn't an encrypted call. bad things will happen.\n" 10772 ); 10773 break; 10774 } 10775 10776 IAX_DEBUGDIGEST("Receiving", ies.challenge); 10777 10778 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 10779 break; 10780 case IAX_COMMAND_DPREP: 10781 complete_dpreply(iaxs[fr->callno], &ies); 10782 break; 10783 case IAX_COMMAND_UNSUPPORT: 10784 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 10785 break; 10786 case IAX_COMMAND_FWDOWNL: 10787 /* Firmware download */ 10788 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 10789 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 10790 break; 10791 } 10792 memset(&ied0, 0, sizeof(ied0)); 10793 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 10794 if (res < 0) 10795 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10796 else if (res > 0) 10797 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10798 else 10799 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10800 if (!iaxs[fr->callno]) { 10801 ast_mutex_unlock(&iaxsl[fr->callno]); 10802 return 1; 10803 } 10804 break; 10805 case IAX_COMMAND_CALLTOKEN: 10806 { 10807 struct iax_frame *cur; 10808 int found = 0; 10809 AST_LIST_LOCK(&frame_queue); 10810 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10811 /* find the last sent frame in our frame queue for this callno. 10812 * There are many things to take into account before resending this frame. 10813 * All of these are taken care of in resend_with_token() */ 10814 if (cur->callno == fr->callno) { 10815 found = 1; 10816 break; 10817 } 10818 } 10819 AST_LIST_UNLOCK(&frame_queue); 10820 10821 /* find last sent frame */ 10822 if (cur && found && ies.calltoken && ies.calltokendata) { 10823 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 10824 } 10825 break; 10826 } 10827 default: 10828 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 10829 memset(&ied0, 0, sizeof(ied0)); 10830 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 10831 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 10832 } 10833 /* Free remote variables (if any) */ 10834 if (ies.vars) { 10835 ast_variables_destroy(ies.vars); 10836 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 10837 ies.vars = NULL; 10838 } 10839 10840 /* Don't actually pass these frames along */ 10841 if ((f.subclass != IAX_COMMAND_ACK) && 10842 (f.subclass != IAX_COMMAND_TXCNT) && 10843 (f.subclass != IAX_COMMAND_TXACC) && 10844 (f.subclass != IAX_COMMAND_INVAL) && 10845 (f.subclass != IAX_COMMAND_VNAK)) { 10846 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 10847 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10848 } 10849 ast_mutex_unlock(&iaxsl[fr->callno]); 10850 return 1; 10851 } 10852 /* Unless this is an ACK or INVAL frame, ack it */ 10853 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 10854 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10855 } else if (minivid) { 10856 f.frametype = AST_FRAME_VIDEO; 10857 if (iaxs[fr->callno]->videoformat > 0) 10858 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 10859 else { 10860 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 10861 iax2_vnak(fr->callno); 10862 ast_mutex_unlock(&iaxsl[fr->callno]); 10863 return 1; 10864 } 10865 f.datalen = res - sizeof(*vh); 10866 if (f.datalen) 10867 f.data.ptr = thread->buf + sizeof(*vh); 10868 else 10869 f.data.ptr = NULL; 10870 #ifdef IAXTESTS 10871 if (test_resync) { 10872 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 10873 } else 10874 #endif /* IAXTESTS */ 10875 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 10876 } else { 10877 /* A mini frame */ 10878 f.frametype = AST_FRAME_VOICE; 10879 if (iaxs[fr->callno]->voiceformat > 0) 10880 f.subclass = iaxs[fr->callno]->voiceformat; 10881 else { 10882 ast_debug(1, "Received mini frame before first full voice frame\n"); 10883 iax2_vnak(fr->callno); 10884 ast_mutex_unlock(&iaxsl[fr->callno]); 10885 return 1; 10886 } 10887 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 10888 if (f.datalen < 0) { 10889 ast_log(LOG_WARNING, "Datalen < 0?\n"); 10890 ast_mutex_unlock(&iaxsl[fr->callno]); 10891 return 1; 10892 } 10893 if (f.datalen) 10894 f.data.ptr = thread->buf + sizeof(*mh); 10895 else 10896 f.data.ptr = NULL; 10897 #ifdef IAXTESTS 10898 if (test_resync) { 10899 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 10900 } else 10901 #endif /* IAXTESTS */ 10902 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 10903 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 10904 } 10905 /* Don't pass any packets until we're started */ 10906 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10907 ast_mutex_unlock(&iaxsl[fr->callno]); 10908 return 1; 10909 } 10910 /* Common things */ 10911 f.src = "IAX2"; 10912 f.mallocd = 0; 10913 f.offset = 0; 10914 f.len = 0; 10915 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 10916 f.samples = ast_codec_get_samples(&f); 10917 /* We need to byteswap incoming slinear samples from network byte order */ 10918 if (f.subclass == AST_FORMAT_SLINEAR) 10919 ast_frame_byteswap_be(&f); 10920 } else 10921 f.samples = 0; 10922 iax_frame_wrap(fr, &f); 10923 10924 /* If this is our most recent packet, use it as our basis for timestamping */ 10925 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10926 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 10927 fr->outoforder = 0; 10928 } else { 10929 if (iaxdebug && iaxs[fr->callno]) 10930 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); 10931 fr->outoforder = -1; 10932 } 10933 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 10934 duped_fr = iaxfrdup2(fr); 10935 if (duped_fr) { 10936 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 10937 } 10938 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10939 iaxs[fr->callno]->last = fr->ts; 10940 #if 1 10941 if (iaxdebug) 10942 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10943 #endif 10944 } 10945 10946 /* Always run again */ 10947 ast_mutex_unlock(&iaxsl[fr->callno]); 10948 return 1; 10949 }
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 9094 of file chan_iax2.c.
References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_mini_hdr::callno, f, find_callno_locked(), find_tpeer(), fix_peerts(), iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, chan_iax2_pvt::last, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, iax_frame::outoforder, iax2_trunk_peer::rxtrunktime, schedule_delivery(), iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09096 { 09097 unsigned char metatype; 09098 struct ast_iax2_meta_trunk_mini *mtm; 09099 struct ast_iax2_meta_trunk_hdr *mth; 09100 struct ast_iax2_meta_trunk_entry *mte; 09101 struct iax2_trunk_peer *tpeer; 09102 unsigned int ts; 09103 void *ptr; 09104 struct timeval rxtrunktime; 09105 struct ast_frame f = { 0, }; 09106 09107 if (packet_len < sizeof(*meta)) { 09108 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09109 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09110 return 1; 09111 } 09112 09113 if (meta->metacmd != IAX_META_TRUNK) 09114 return 1; 09115 09116 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09117 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09118 (int) (sizeof(*meta) + sizeof(*mth))); 09119 return 1; 09120 } 09121 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09122 ts = ntohl(mth->ts); 09123 metatype = meta->cmddata; 09124 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09125 ptr = mth->data; 09126 tpeer = find_tpeer(sin, sockfd); 09127 if (!tpeer) { 09128 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09129 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09130 return 1; 09131 } 09132 tpeer->trunkact = ast_tvnow(); 09133 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09134 tpeer->rxtrunktime = tpeer->trunkact; 09135 rxtrunktime = tpeer->rxtrunktime; 09136 ast_mutex_unlock(&tpeer->lock); 09137 while (packet_len >= sizeof(*mte)) { 09138 /* Process channels */ 09139 unsigned short callno, trunked_ts, len; 09140 09141 if (metatype == IAX_META_TRUNK_MINI) { 09142 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09143 ptr += sizeof(*mtm); 09144 packet_len -= sizeof(*mtm); 09145 len = ntohs(mtm->len); 09146 callno = ntohs(mtm->mini.callno); 09147 trunked_ts = ntohs(mtm->mini.ts); 09148 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09149 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09150 ptr += sizeof(*mte); 09151 packet_len -= sizeof(*mte); 09152 len = ntohs(mte->len); 09153 callno = ntohs(mte->callno); 09154 trunked_ts = 0; 09155 } else { 09156 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09157 break; 09158 } 09159 /* Stop if we don't have enough data */ 09160 if (len > packet_len) 09161 break; 09162 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09163 if (!fr->callno) 09164 continue; 09165 09166 /* If it's a valid call, deliver the contents. If not, we 09167 drop it, since we don't have a scallno to use for an INVAL */ 09168 /* Process as a mini frame */ 09169 memset(&f, 0, sizeof(f)); 09170 f.frametype = AST_FRAME_VOICE; 09171 if (!iaxs[fr->callno]) { 09172 /* drop it */ 09173 } else if (iaxs[fr->callno]->voiceformat == 0) { 09174 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09175 iax2_vnak(fr->callno); 09176 } else { 09177 f.subclass = iaxs[fr->callno]->voiceformat; 09178 f.datalen = len; 09179 if (f.datalen >= 0) { 09180 if (f.datalen) 09181 f.data.ptr = ptr; 09182 else 09183 f.data.ptr = NULL; 09184 if (trunked_ts) 09185 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09186 else 09187 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09188 /* Don't pass any packets until we're started */ 09189 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09190 struct iax_frame *duped_fr; 09191 09192 /* Common things */ 09193 f.src = "IAX2"; 09194 f.mallocd = 0; 09195 f.offset = 0; 09196 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09197 f.samples = ast_codec_get_samples(&f); 09198 else 09199 f.samples = 0; 09200 fr->outoforder = 0; 09201 iax_frame_wrap(fr, &f); 09202 duped_fr = iaxfrdup2(fr); 09203 if (duped_fr) 09204 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09205 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09206 iaxs[fr->callno]->last = fr->ts; 09207 } 09208 } else { 09209 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09210 } 09211 } 09212 ast_mutex_unlock(&iaxsl[fr->callno]); 09213 ptr += len; 09214 packet_len -= len; 09215 } 09216 09217 return 1; 09218 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9016 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::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
09017 { 09018 struct iax2_thread *thread; 09019 socklen_t len; 09020 time_t t; 09021 static time_t last_errtime = 0; 09022 struct ast_iax2_full_hdr *fh; 09023 09024 if (!(thread = find_idle_thread())) { 09025 time(&t); 09026 if (t != last_errtime) 09027 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09028 last_errtime = t; 09029 usleep(1); 09030 return 1; 09031 } 09032 09033 len = sizeof(thread->iosin); 09034 thread->iofd = fd; 09035 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09036 thread->buf_size = sizeof(thread->readbuf); 09037 thread->buf = thread->readbuf; 09038 if (thread->buf_len < 0) { 09039 if (errno != ECONNREFUSED && errno != EAGAIN) 09040 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09041 handle_error(); 09042 thread->iostate = IAX_IOSTATE_IDLE; 09043 signal_condition(&thread->lock, &thread->cond); 09044 return 1; 09045 } 09046 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09047 thread->iostate = IAX_IOSTATE_IDLE; 09048 signal_condition(&thread->lock, &thread->cond); 09049 return 1; 09050 } 09051 09052 /* Determine if this frame is a full frame; if so, and any thread is currently 09053 processing a full frame for the same callno from this peer, then drop this 09054 frame (and the peer will retransmit it) */ 09055 fh = (struct ast_iax2_full_hdr *) thread->buf; 09056 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09057 struct iax2_thread *cur = NULL; 09058 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09059 09060 AST_LIST_LOCK(&active_list); 09061 AST_LIST_TRAVERSE(&active_list, cur, list) { 09062 if ((cur->ffinfo.callno == callno) && 09063 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09064 break; 09065 } 09066 if (cur) { 09067 /* we found another thread processing a full frame for this call, 09068 so queue it up for processing later. */ 09069 defer_full_frame(thread, cur); 09070 AST_LIST_UNLOCK(&active_list); 09071 thread->iostate = IAX_IOSTATE_IDLE; 09072 signal_condition(&thread->lock, &thread->cond); 09073 return 1; 09074 } else { 09075 /* this thread is going to process this frame, so mark it */ 09076 thread->ffinfo.callno = callno; 09077 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09078 thread->ffinfo.type = fh->type; 09079 thread->ffinfo.csub = fh->csub; 09080 } 09081 AST_LIST_UNLOCK(&active_list); 09082 } 09083 09084 /* Mark as ready and send on its way */ 09085 thread->iostate = IAX_IOSTATE_READY; 09086 #ifdef DEBUG_SCHED_MULTITHREAD 09087 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09088 #endif 09089 signal_condition(&thread->lock, &thread->cond); 09090 09091 return 1; 09092 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 8732 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
08733 { 08734 pthread_t newthread; 08735 struct dpreq_data *dpr; 08736 08737 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 08738 return; 08739 08740 dpr->callno = callno; 08741 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 08742 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 08743 if (callerid) 08744 dpr->callerid = ast_strdup(callerid); 08745 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 08746 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 08747 } 08748 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 11565 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_detached, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.
Referenced by load_module().
11566 { 11567 struct iax2_thread *thread; 11568 int threadcount = 0; 11569 int x; 11570 for (x = 0; x < iaxthreadcount; x++) { 11571 thread = ast_calloc(1, sizeof(*thread)); 11572 if (thread) { 11573 thread->type = IAX_THREAD_TYPE_POOL; 11574 thread->threadnum = ++threadcount; 11575 ast_mutex_init(&thread->lock); 11576 ast_cond_init(&thread->cond, NULL); 11577 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) { 11578 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 11579 ast_free(thread); 11580 thread = NULL; 11581 } 11582 AST_LIST_LOCK(&idle_list); 11583 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 11584 AST_LIST_UNLOCK(&idle_list); 11585 } 11586 } 11587 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 11588 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 11589 ast_verb(2, "%d helper threads started\n", threadcount); 11590 return 0; 11591 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8435 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08436 { 08437 iax2_destroy_helper(iaxs[callno]); 08438 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1867 of file chan_iax2.c.
References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01868 { 01869 if (!pvt->peercallno) { 01870 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01871 return; 01872 } 01873 01874 ao2_link(iax_peercallno_pvts, pvt); 01875 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1848 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01849 { 01850 if (!pvt->transfercallno) { 01851 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01852 return; 01853 } 01854 01855 ao2_link(iax_transfercallno_pvts, pvt); 01856 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 8621 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), timer, totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
08622 { 08623 int res, processed = 0, totalcalls = 0; 08624 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 08625 struct timeval now = ast_tvnow(); 08626 08627 if (iaxtrunkdebug) 08628 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 08629 08630 if (timer) { 08631 ast_timer_ack(timer, 1); 08632 } 08633 08634 /* For each peer that supports trunking... */ 08635 AST_LIST_LOCK(&tpeers); 08636 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 08637 processed++; 08638 res = 0; 08639 ast_mutex_lock(&tpeer->lock); 08640 /* We can drop a single tpeer per pass. That makes all this logic 08641 substantially easier */ 08642 if (!drop && iax2_trunk_expired(tpeer, &now)) { 08643 /* Take it out of the list, but don't free it yet, because it 08644 could be in use */ 08645 AST_LIST_REMOVE_CURRENT(list); 08646 drop = tpeer; 08647 } else { 08648 res = send_trunk(tpeer, &now); 08649 trunk_timed++; 08650 if (iaxtrunkdebug) 08651 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); 08652 } 08653 totalcalls += res; 08654 res = 0; 08655 ast_mutex_unlock(&tpeer->lock); 08656 } 08657 AST_LIST_TRAVERSE_SAFE_END; 08658 AST_LIST_UNLOCK(&tpeers); 08659 08660 if (drop) { 08661 ast_mutex_lock(&drop->lock); 08662 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 08663 because by the time they could get tpeerlock, we've already grabbed it */ 08664 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 08665 if (drop->trunkdata) { 08666 ast_free(drop->trunkdata); 08667 drop->trunkdata = NULL; 08668 } 08669 ast_mutex_unlock(&drop->lock); 08670 ast_mutex_destroy(&drop->lock); 08671 ast_free(drop); 08672 08673 } 08674 08675 if (iaxtrunkdebug) 08676 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 08677 iaxtrunkdebug = 0; 08678 08679 return 1; 08680 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 13571 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
13572 { 13573 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13574 13575 /* The frames_received field is used to hold whether we're matching 13576 * against a full frame or not ... */ 13577 13578 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 13579 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13580 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 13564 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
13565 { 13566 const struct chan_iax2_pvt *pvt = obj; 13567 13568 return pvt->transfercallno; 13569 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3057 of file chan_iax2.c.
References ast_debug, errno, f, and handle_error().
Referenced by send_trunk().
03058 { 03059 int res; 03060 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03061 sizeof(*sin)); 03062 if (res < 0) { 03063 ast_debug(1, "Received error: %s\n", strerror(errno)); 03064 handle_error(); 03065 } else 03066 res = 0; 03067 return res; 03068 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2759 of file chan_iax2.c.
References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, iax2_trunk_peer::list, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
02760 { 02761 struct stat stbuf; 02762 struct iax_firmware *cur = NULL; 02763 int ifd, fd, res, len, chunk; 02764 struct ast_iax2_firmware_header *fwh, fwh2; 02765 struct MD5Context md5; 02766 unsigned char sum[16], buf[1024]; 02767 char *s2, *last; 02768 02769 if (!(s2 = alloca(strlen(s) + 100))) { 02770 ast_log(LOG_WARNING, "Alloca failed!\n"); 02771 return -1; 02772 } 02773 02774 last = strrchr(s, '/'); 02775 if (last) 02776 last++; 02777 else 02778 last = s; 02779 02780 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02781 02782 if ((res = stat(s, &stbuf) < 0)) { 02783 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02784 return -1; 02785 } 02786 02787 /* Make sure it's not a directory */ 02788 if (S_ISDIR(stbuf.st_mode)) 02789 return -1; 02790 ifd = open(s, O_RDONLY); 02791 if (ifd < 0) { 02792 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02793 return -1; 02794 } 02795 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 02796 if (fd < 0) { 02797 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02798 close(ifd); 02799 return -1; 02800 } 02801 /* Unlink our newly created file */ 02802 unlink(s2); 02803 02804 /* Now copy the firmware into it */ 02805 len = stbuf.st_size; 02806 while(len) { 02807 chunk = len; 02808 if (chunk > sizeof(buf)) 02809 chunk = sizeof(buf); 02810 res = read(ifd, buf, chunk); 02811 if (res != chunk) { 02812 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02813 close(ifd); 02814 close(fd); 02815 return -1; 02816 } 02817 res = write(fd, buf, chunk); 02818 if (res != chunk) { 02819 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02820 close(ifd); 02821 close(fd); 02822 return -1; 02823 } 02824 len -= chunk; 02825 } 02826 close(ifd); 02827 /* Return to the beginning */ 02828 lseek(fd, 0, SEEK_SET); 02829 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02830 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02831 close(fd); 02832 return -1; 02833 } 02834 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02835 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02836 close(fd); 02837 return -1; 02838 } 02839 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02840 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02841 close(fd); 02842 return -1; 02843 } 02844 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02845 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02846 close(fd); 02847 return -1; 02848 } 02849 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02850 if (fwh == MAP_FAILED) { 02851 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02852 close(fd); 02853 return -1; 02854 } 02855 MD5Init(&md5); 02856 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02857 MD5Final(sum, &md5); 02858 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02859 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02860 munmap((void*)fwh, stbuf.st_size); 02861 close(fd); 02862 return -1; 02863 } 02864 02865 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02866 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02867 /* Found a candidate */ 02868 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02869 /* The version we have on loaded is older, load this one instead */ 02870 break; 02871 /* This version is no newer than what we have. Don't worry about it. 02872 We'll consider it a proper load anyhow though */ 02873 munmap((void*)fwh, stbuf.st_size); 02874 close(fd); 02875 return 0; 02876 } 02877 } 02878 02879 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 02880 cur->fd = -1; 02881 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 02882 } 02883 02884 if (cur) { 02885 if (cur->fwh) 02886 munmap((void*)cur->fwh, cur->mmaplen); 02887 if (cur->fd > -1) 02888 close(cur->fd); 02889 cur->fwh = fwh; 02890 cur->fd = fd; 02891 cur->mmaplen = stbuf.st_size; 02892 cur->dead = 0; 02893 } 02894 02895 return 0; 02896 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7778 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
07779 { 07780 int newcall = 0; 07781 char newip[256]; 07782 struct iax_ie_data ied; 07783 struct sockaddr_in new; 07784 07785 07786 memset(&ied, 0, sizeof(ied)); 07787 if (ies->apparent_addr) 07788 memmove(&new, ies->apparent_addr, sizeof(new)); 07789 if (ies->callno) 07790 newcall = ies->callno; 07791 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07792 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07793 return -1; 07794 } 07795 pvt->transfercallno = newcall; 07796 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07797 inet_aton(newip, &pvt->transfer.sin_addr); 07798 pvt->transfer.sin_family = AF_INET; 07799 pvt->transferid = ies->transferid; 07800 /* only store by transfercallno if this is a new transfer, 07801 * just in case we get a duplicate TXREQ */ 07802 if (pvt->transferring == TRANSFER_NONE) { 07803 store_by_transfercallno(pvt); 07804 } 07805 pvt->transferring = TRANSFER_BEGIN; 07806 07807 if (ies->transferid) 07808 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07809 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07810 return 0; 07811 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1389 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01390 { 01391 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01392 if (csub & IAX_FLAG_SC_LOG) { 01393 /* special case for 'compressed' -1 */ 01394 if (csub == 0xff) 01395 return -1; 01396 else 01397 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01398 } 01399 else 01400 return csub; 01401 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8069 of file chan_iax2.c.
References ao2_unlink, ast_sched_del(), iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08070 { 08071 if (peer->expire > -1) { 08072 if (!ast_sched_del(sched, peer->expire)) { 08073 peer->expire = -1; 08074 peer_unref(peer); 08075 } 08076 } 08077 08078 if (peer->pokeexpire > -1) { 08079 if (!ast_sched_del(sched, peer->pokeexpire)) { 08080 peer->pokeexpire = -1; 08081 peer_unref(peer); 08082 } 08083 } 08084 08085 ao2_unlink(peers, peer); 08086 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13529 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
13530 { 13531 ast_custom_function_unregister(&iaxpeer_function); 13532 ast_custom_function_unregister(&iaxvar_function); 13533 return __unload_module(); 13534 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5057 of file chan_iax2.c.
References ast_mutex_unlock().
Referenced by iax2_bridge().
05058 { 05059 ast_mutex_unlock(&iaxsl[callno1]); 05060 ast_mutex_unlock(&iaxsl[callno0]); 05061 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3724 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
03725 { 03726 /* Video mini frames only encode the lower 15 bits of the session 03727 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03728 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03729 const int lower_mask = (1 << ts_shift) - 1; 03730 const int upper_mask = ~lower_mask; 03731 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03732 03733 if ( (fr->ts & upper_mask) == last_upper ) { 03734 const int x = fr->ts - iaxs[fr->callno]->last; 03735 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03736 03737 if (x < -threshold) { 03738 /* Sudden big jump backwards in timestamp: 03739 What likely happened here is that miniframe timestamp has circled but we haven't 03740 gotten the update from the main packet. We'll just pretend that we did, and 03741 update the timestamp appropriately. */ 03742 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03743 if (iaxdebug) 03744 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 03745 } else if (x > threshold) { 03746 /* Sudden apparent big jump forwards in timestamp: 03747 What's likely happened is this is an old miniframe belonging to the previous 03748 top 15 or 16-bit timestamp that has turned up out of order. 03749 Adjust the timestamp appropriately. */ 03750 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03751 if (iaxdebug) 03752 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 03753 } 03754 } 03755 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3759 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
03760 { 03761 int when; 03762 03763 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03764 03765 when = jb_next(pvt->jb) - when; 03766 03767 if (when <= 0) { 03768 /* XXX should really just empty until when > 0.. */ 03769 when = 1; 03770 } 03771 03772 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 03773 CALLNO_TO_PTR(pvt->callno)); 03774 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1776 of file chan_iax2.c.
References ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01777 { 01778 int max = 1; 01779 int x; 01780 /* XXX Prolly don't need locks here XXX */ 01781 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01782 if (iaxs[x]) 01783 max = x + 1; 01784 } 01785 maxnontrunkcall = max; 01786 if (iaxdebug) 01787 ast_debug(1, "New max nontrunk callno is %d\n", max); 01788 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1759 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01760 { 01761 int max = TRUNK_CALL_START; 01762 int x; 01763 01764 /* XXX Prolly don't need locks here XXX */ 01765 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01766 if (iaxs[x]) { 01767 max = x + 1; 01768 } 01769 } 01770 01771 maxtrunkcall = max; 01772 if (iaxdebug) 01773 ast_debug(1, "New max trunk callno is %d\n", max); 01774 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3186 of file chan_iax2.c.
References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
03187 { 03188 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03189 struct ast_iax2_full_hdr *fh = f->data; 03190 struct ast_frame af; 03191 03192 /* if frame is encrypted. decrypt before updating it. */ 03193 if (f->encmethods) { 03194 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03195 } 03196 /* Mark this as a retransmission */ 03197 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03198 /* Update iseqno */ 03199 f->iseqno = iaxs[f->callno]->iseqno; 03200 fh->iseqno = f->iseqno; 03201 03202 /* Now re-encrypt the frame */ 03203 if (f->encmethods) { 03204 /* since this is a retransmit frame, create a new random padding 03205 * before re-encrypting. */ 03206 build_rand_pad(f->semirand, sizeof(f->semirand)); 03207 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03208 } 03209 return 0; 03210 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8180 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verb, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.
Referenced by socket_process().
08181 { 08182 /* Called from IAX thread only, with proper iaxsl lock */ 08183 struct iax_ie_data ied; 08184 struct iax2_peer *p; 08185 int msgcount; 08186 char data[80]; 08187 int version; 08188 const char *peer_name; 08189 int res = -1; 08190 08191 memset(&ied, 0, sizeof(ied)); 08192 08193 peer_name = ast_strdupa(iaxs[callno]->peer); 08194 08195 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08196 ast_mutex_unlock(&iaxsl[callno]); 08197 if (!(p = find_peer(peer_name, 1))) { 08198 ast_mutex_lock(&iaxsl[callno]); 08199 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08200 return -1; 08201 } 08202 ast_mutex_lock(&iaxsl[callno]); 08203 if (!iaxs[callno]) 08204 goto return_unref; 08205 08206 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08207 if (sin->sin_addr.s_addr) { 08208 time_t nowtime; 08209 time(&nowtime); 08210 realtime_update_peer(peer_name, sin, nowtime); 08211 } else { 08212 realtime_update_peer(peer_name, sin, 0); 08213 } 08214 } 08215 if (inaddrcmp(&p->addr, sin)) { 08216 if (iax2_regfunk) 08217 iax2_regfunk(p->name, 1); 08218 08219 /* modify entry in peercnts table as _not_ registered */ 08220 peercnt_modify(0, 0, &p->addr); 08221 08222 /* Stash the IP address from which they registered */ 08223 memcpy(&p->addr, sin, sizeof(p->addr)); 08224 08225 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08226 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08227 ast_db_put("IAX/Registry", p->name, data); 08228 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08229 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08230 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08231 register_peer_exten(p, 1); 08232 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08233 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 08234 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08235 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08236 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08237 register_peer_exten(p, 0); 08238 ast_db_del("IAX/Registry", p->name); 08239 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08240 } 08241 /* Update the host */ 08242 /* Verify that the host is really there */ 08243 iax2_poke_peer(p, callno); 08244 } 08245 08246 /* modify entry in peercnts table as registered */ 08247 if (p->maxcallno) { 08248 peercnt_modify(1, p->maxcallno, &p->addr); 08249 } 08250 08251 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08252 if (!iaxs[callno]) { 08253 res = -1; 08254 goto return_unref; 08255 } 08256 08257 /* Store socket fd */ 08258 p->sockfd = fd; 08259 /* Setup the expiry */ 08260 if (p->expire > -1) { 08261 if (!ast_sched_del(sched, p->expire)) { 08262 p->expire = -1; 08263 peer_unref(p); 08264 } 08265 } 08266 /* treat an unspecified refresh interval as the minimum */ 08267 if (!refresh) 08268 refresh = min_reg_expire; 08269 if (refresh > max_reg_expire) { 08270 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08271 p->name, max_reg_expire, refresh); 08272 p->expiry = max_reg_expire; 08273 } else if (refresh < min_reg_expire) { 08274 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08275 p->name, min_reg_expire, refresh); 08276 p->expiry = min_reg_expire; 08277 } else { 08278 p->expiry = refresh; 08279 } 08280 if (p->expiry && sin->sin_addr.s_addr) { 08281 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08282 if (p->expire == -1) 08283 peer_unref(p); 08284 } 08285 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08286 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08287 if (sin->sin_addr.s_addr) { 08288 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08289 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 08290 if (!ast_strlen_zero(p->mailbox)) { 08291 struct ast_event *event; 08292 int new, old; 08293 char *mailbox, *context; 08294 08295 context = mailbox = ast_strdupa(p->mailbox); 08296 strsep(&context, "@"); 08297 if (ast_strlen_zero(context)) 08298 context = "default"; 08299 08300 event = ast_event_get_cached(AST_EVENT_MWI, 08301 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08302 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08303 AST_EVENT_IE_END); 08304 if (event) { 08305 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08306 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08307 ast_event_destroy(event); 08308 } else { /* Fall back on checking the mailbox directly */ 08309 ast_app_inboxcount(p->mailbox, &new, &old); 08310 } 08311 08312 if (new > 255) { 08313 new = 255; 08314 } 08315 if (old > 255) { 08316 old = 255; 08317 } 08318 msgcount = (old << 8) | new; 08319 08320 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08321 } 08322 if (ast_test_flag(p, IAX_HASCALLERID)) { 08323 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08324 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08325 } 08326 } 08327 version = iax_check_version(devtype); 08328 if (version) 08329 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08330 08331 res = 0; 08332 08333 return_unref: 08334 peer_unref(p); 08335 08336 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08337 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1436 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and user.
Referenced by load_objects().
01437 { 01438 struct iax2_user *user = obj, *user2 = arg; 01439 01440 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01441 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12240 of file chan_iax2.c.
References ast_set_flag, IAX_DELME, and user.
Referenced by delete_users().
12241 { 12242 struct iax2_user *user = obj; 12243 12244 ast_set_flag(user, IAX_DELME); 12245 12246 return 0; 12247 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 11991 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.
Referenced by build_user().
11992 { 11993 struct iax2_user *user = obj; 11994 11995 ast_free_ha(user->ha); 11996 free_context(user->contexts); 11997 if(user->vars) { 11998 ast_variables_destroy(user->vars); 11999 user->vars = NULL; 12000 } 12001 ast_string_field_free_memory(user); 12002 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1426 of file chan_iax2.c.
References ast_str_hash(), and user.
Referenced by load_objects().
01427 { 01428 const struct iax2_user *user = obj; 01429 01430 return ast_str_hash(user->name); 01431 }
Definition at line 1489 of file chan_iax2.c.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), and set_config().
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 8536 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxs, iax_frame::list, and send_packet().
Referenced by socket_process().
08537 { 08538 struct iax_frame *f; 08539 08540 AST_LIST_LOCK(&frame_queue); 08541 AST_LIST_TRAVERSE(&frame_queue, f, list) { 08542 /* Send a copy immediately */ 08543 if ((f->callno == callno) && iaxs[f->callno] && 08544 ((unsigned char ) (f->oseqno - last) < 128) && 08545 (f->retries >= 0)) { 08546 send_packet(f); 08547 } 08548 } 08549 AST_LIST_UNLOCK(&frame_queue); 08550 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4914 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
04915 { 04916 unsigned short callno = pvt->callno; 04917 04918 if (!pvt->peercallno) { 04919 /* We don't know the remote side's call number, yet. :( */ 04920 int count = 10; 04921 while (count-- && pvt && !pvt->peercallno) { 04922 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 04923 pvt = iaxs[callno]; 04924 } 04925 if (!pvt->peercallno) { 04926 return -1; 04927 } 04928 } 04929 04930 return 0; 04931 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 13752 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 244 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial_channel(), build_gateway(), check_peer_ok(), dahdi_new(), dial_exec_full(), do_forward(), findmeexec(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), and tds_log().
int adsi = 0 [static] |
int amaflags = 0 [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13752 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 160 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 161 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 754 of file chan_iax2.c.
Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 713 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 718 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 716 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 757 of file chan_iax2.c.
Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().
struct ast_cli_entry cli_iax2[] [static] |
unsigned int cos |
Definition at line 171 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 960 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 759 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 761 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 141 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 183 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 249 of file chan_iax2.c.
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 136 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 763 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 766 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 303 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 252 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), apply_general_options(), build_peer(), build_user(), check_access(), find_or_create(), find_user(), find_user_realtime(), forward_message(), handle_minivm_show_settings(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 230 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 250 of file chan_iax2.c.
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 185 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 1074 of file chan_iax2.c.
Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
struct ast_datastore_info iax2_variable_datastore_info [static] |
Initial value:
{ .type = "IAX2_VARIABLE", .duplicate = iax2_dup_variable_datastore, .destroy = iax2_free_variable_datastore, }
Definition at line 1118 of file chan_iax2.c.
Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 937 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
*
Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 953 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 502 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 232 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 167 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 500 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
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 926 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), socket_process(), socket_process_meta(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
chan_iax2_pvt structure locks
These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.
Definition at line 946 of file chan_iax2.c.
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 498 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 234 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
struct io_context* io [static] |
Definition at line 227 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 153 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 149 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 143 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 163 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 731 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 175 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 147 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 146 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 150 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 152 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1027 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1026 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 174 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 245 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 246 of file chan_iax2.c.
Referenced by check_peer_ok(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 181 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 254 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 182 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 11197 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 751 of file chan_iax2.c.
Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().
struct ao2_container* peers [static] |
Definition at line 745 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), _sip_show_peers(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), delete_users(), expire_register(), find_peer(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), poke_all_peers(), prune_peers(), register_verify(), set_config(), sip_do_reload(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), unlink_peer(), and unload_module().
int ping_time = 21 [static] |
Definition at line 148 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 127 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char* psyn = "Provision a calling IAXy with a given template" [static] |
struct { ... } qos [static] |
Referenced by acf_channel_read(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().
int randomcalltokendata [static] |
Definition at line 729 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 144 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 228 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 257 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 256 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 255 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 129 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 236 of file chan_iax2.c.
Definition at line 179 of file chan_iax2.c.
Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), load_module(), network_thread(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), read_pipe(), run_timer(), timing_read(), timing_test(), and write_byte().
unsigned int tos |
Definition at line 170 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 768 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 137 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 137 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 137 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 137 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 157 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 158 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 748 of file chan_iax2.c.
Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_exec(), prune_users(), set_config(), and unload_module().