#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.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 <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include <sys/ioctl.h>
#include "asterisk/dahdi_compat.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.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/astobj2.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 | ast_firmware_list |
struct | ast_iax2_queue |
struct | callno_entry |
struct | chan_iax2_pvt |
struct | chan_iax2_pvt::signaling_queue |
struct | create_addr_info |
struct | dpreq_data |
struct | dynamic_list |
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 |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#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_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 %-15d %-15d\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 %-15.15s\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_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { 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 | { 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 | 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 | 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 (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 *tv) |
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_show_peer (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 (aes_decrypt_ctx *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 (aes_encrypt_ctx *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 *tv, 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, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (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 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 int | iax2_answer (struct ast_channel *c) |
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_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
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 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_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_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
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_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
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 (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
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_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_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_callnumber_usage (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
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 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 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_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
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_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 | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
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 | AST_MODFLAG_BUILDSUM, .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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static const 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 ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT = 2048 |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
static ast_mutex_t | dpcache_lock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
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 |
enum { ... } | iax2_flags |
int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
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 ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
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 char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
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 | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static char | show_cache_usage [] |
static char | show_callnumber_usage [] |
static char | show_channels_usage [] |
static char | show_firmware_usage [] |
static char | show_netstats_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_prov_usage [] |
static char | show_reg_usage [] |
static char | show_stats_usage [] |
static char | show_threads_usage [] |
static char | show_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static unsigned int | tos = 0 |
static uint16_t | total_nonval_callno_used = 0 |
static ast_mutex_t | tpeerlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 768 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache().
#define CACHE_FLAG_EXISTS (1 << 0) |
Extension exists
Definition at line 764 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache().
#define CACHE_FLAG_MATCHMORE (1 << 7) |
Matchmore
Definition at line 778 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache().
#define CACHE_FLAG_NONEXISTENT (1 << 1) |
Extension is nonexistent
Definition at line 766 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CACHE_FLAG_PENDING (1 << 3) |
Waiting to hear back response
Definition at line 770 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TIMEOUT (1 << 4) |
Timed out
Definition at line 772 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 774 of file chan_iax2.c.
Referenced by iax2_dprequest(), iax2_show_cache(), and socket_process().
#define CACHE_FLAG_UNKNOWN (1 << 6) |
Timeout
Definition at line 776 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 123 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 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 131 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 197 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 196 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 195 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 457 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 %-15d %-15d\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 %-15.15s\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 136 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_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
Definition at line 178 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 186 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 191 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 180 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 802 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 806 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 114 of file chan_iax2.c.
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 466 of file chan_iax2.c.
Referenced by ast_cli_netstats(), iax2_send(), and iax2_show_channels().
#define MAX_JITTER_BUFFER 50 |
Definition at line 454 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 1 |
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 698 of file chan_iax2.c.
Referenced by load_objects(), and set_config().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 460 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 458 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 455 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 122 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), 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 107 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1101 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
Definition at line 939 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 463 of file chan_iax2.c.
anonymous enum |
Definition at line 231 of file chan_iax2.c.
00231 { 00232 IAX_STATE_STARTED = (1 << 0), 00233 IAX_STATE_AUTHENTICATED = (1 << 1), 00234 IAX_STATE_TBD = (1 << 2), 00235 } iax2_state;
anonymous enum |
Definition at line 242 of file chan_iax2.c.
00242 { 00243 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00244 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00245 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00246 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00247 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00248 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00249 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00250 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00251 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00252 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00253 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00254 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00255 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00256 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00257 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00258 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00259 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00260 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00261 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00262 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00263 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00264 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00265 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00266 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00267 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00268 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00269 response, so that we've achieved a three-way handshake with 00270 them before sending voice or anything else*/ 00271 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00272 IAX_SHRINKCALLERID = (1 << 27), /*!< Turn on and off caller id shrinking */ 00273 } iax2_flags;
anonymous enum |
Definition at line 1673 of file chan_iax2.c.
01673 { 01674 /* do not allow a new call number, only search ones in use for match */ 01675 NEW_PREVENT = 0, 01676 /* search for match first, then allow a new one to be allocated */ 01677 NEW_ALLOW = 1, 01678 /* do not search for match, force a new call number */ 01679 NEW_FORCE = 2, 01680 /* do not search for match, force a new call number. Signifies call number 01681 * has been calltoken validated */ 01682 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01683 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 283 of file chan_iax2.c.
00283 { 00284 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00285 CALLTOKEN_DEFAULT = 0, 00286 /*! \brief Require call token validation. */ 00287 CALLTOKEN_YES = 1, 00288 /*! \brief Require call token validation after a successful registration 00289 * using call token validation occurs. */ 00290 CALLTOKEN_AUTO = 2, 00291 /*! \brief Do not require call token validation. */ 00292 CALLTOKEN_NO = 3, 00293 };
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 409 of file chan_iax2.c.
00409 { 00410 REG_STATE_UNREGISTERED = 0, 00411 REG_STATE_REGSENT, 00412 REG_STATE_AUTHSENT, 00413 REG_STATE_REGISTERED, 00414 REG_STATE_REJECTED, 00415 REG_STATE_TIMEOUT, 00416 REG_STATE_NOAUTH 00417 };
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 419 of file chan_iax2.c.
00419 { 00420 TRANSFER_NONE = 0, 00421 TRANSFER_BEGIN, 00422 TRANSFER_READY, 00423 TRANSFER_RELEASED, 00424 TRANSFER_PASSTHROUGH, 00425 TRANSFER_MBEGIN, 00426 TRANSFER_MREADY, 00427 TRANSFER_MRELEASED, 00428 TRANSFER_MPASSTHROUGH, 00429 TRANSFER_MEDIA, 00430 TRANSFER_MEDIAPASS 00431 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3057 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(), iax2_registry::callno, ast_iax2_queue::count, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, ast_iax2_queue::queue, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03058 { 03059 /* Attempt to transmit the frame to the remote peer... 03060 Called without iaxsl held. */ 03061 struct iax_frame *f = (struct iax_frame *)data; 03062 int freeme=0; 03063 int callno = f->callno; 03064 /* Make sure this call is still active */ 03065 if (callno) 03066 ast_mutex_lock(&iaxsl[callno]); 03067 if (callno && iaxs[callno]) { 03068 if ((f->retries < 0) /* Already ACK'd */ || 03069 (f->retries >= max_retries) /* Too many attempts */) { 03070 /* Record an error if we've transmitted too many times */ 03071 if (f->retries >= max_retries) { 03072 if (f->transfer) { 03073 /* Transfer timeout */ 03074 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03075 } else if (f->final) { 03076 if (f->final) 03077 iax2_destroy(callno); 03078 } else { 03079 if (iaxs[callno]->owner) 03080 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); 03081 iaxs[callno]->error = ETIMEDOUT; 03082 if (iaxs[callno]->owner) { 03083 struct ast_frame fr = { 0, }; 03084 /* Hangup the fd */ 03085 fr.frametype = AST_FRAME_CONTROL; 03086 fr.subclass = AST_CONTROL_HANGUP; 03087 iax2_queue_frame(callno, &fr); // XXX 03088 /* Remember, owner could disappear */ 03089 if (iaxs[callno] && iaxs[callno]->owner) 03090 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03091 } else { 03092 if (iaxs[callno]->reg) { 03093 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03094 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03095 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03096 } 03097 iax2_destroy(callno); 03098 } 03099 } 03100 03101 } 03102 freeme++; 03103 } else { 03104 /* Update it if it needs it */ 03105 update_packet(f); 03106 /* Attempt transmission */ 03107 send_packet(f); 03108 f->retries++; 03109 /* Try again later after 10 times as long */ 03110 f->retrytime *= 10; 03111 if (f->retrytime > MAX_RETRY_TIME) 03112 f->retrytime = MAX_RETRY_TIME; 03113 /* Transfer messages max out at one second */ 03114 if (f->transfer && (f->retrytime > 1000)) 03115 f->retrytime = 1000; 03116 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03117 } 03118 } else { 03119 /* Make sure it gets freed */ 03120 f->retries = -1; 03121 freeme++; 03122 } 03123 if (callno) 03124 ast_mutex_unlock(&iaxsl[callno]); 03125 /* Do not try again */ 03126 if (freeme) { 03127 /* Don't attempt delivery, just remove it from the queue */ 03128 AST_LIST_LOCK(&iaxq.queue); 03129 AST_LIST_REMOVE(&iaxq.queue, f, list); 03130 iaxq.count--; 03131 AST_LIST_UNLOCK(&iaxq.queue); 03132 f->retrans = -1; /* this is safe because this is the scheduled function */ 03133 /* Free the IAX frame */ 03134 iax2_frame_free(f); 03135 } 03136 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 7711 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
07712 { 07713 /* Called from IAX thread only, without iaxs lock */ 07714 int callno = (int)(long)(nothing); 07715 struct iax_ie_data ied; 07716 ast_mutex_lock(&iaxsl[callno]); 07717 if (iaxs[callno]) { 07718 memset(&ied, 0, sizeof(ied)); 07719 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 07720 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 07721 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 07722 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 07723 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 07724 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07725 } 07726 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 07727 } 07728 ast_mutex_unlock(&iaxsl[callno]); 07729 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4042 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04043 { 04044 int callno = PTR_TO_CALLNO(nothing); 04045 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04046 ast_mutex_lock(&iaxsl[callno]); 04047 if (iaxs[callno]) { 04048 iaxs[callno]->initid = -1; 04049 iax2_queue_frame(callno, &f); 04050 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04051 } 04052 ast_mutex_unlock(&iaxsl[callno]); 04053 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 7760 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
07761 { 07762 /* Called from IAX thread only, without iaxs lock */ 07763 int callno = (int)(long)(nothing); 07764 struct iax_ie_data ied; 07765 ast_mutex_lock(&iaxsl[callno]); 07766 if (iaxs[callno]) { 07767 memset(&ied, 0, sizeof(ied)); 07768 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 07769 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 07770 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 07771 } 07772 ast_mutex_unlock(&iaxsl[callno]); 07773 }
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 2910 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().
02911 { 02912 /* Just deliver the packet by using queueing. This is called by 02913 the IAX thread with the iaxsl lock held. */ 02914 struct iax_frame *fr = data; 02915 fr->retrans = -1; 02916 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02917 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02918 iax2_queue_frame(fr->callno, &fr->af); 02919 /* Free our iax frame */ 02920 iax2_frame_free(fr); 02921 /* And don't run again */ 02922 return 0; 02923 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7377 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), 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, option_debug, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
07378 { 07379 struct iax2_peer *peer = (struct iax2_peer *) data; 07380 07381 if (!peer) 07382 return; 07383 07384 peer->expire = -1; 07385 07386 if (option_debug) 07387 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 07388 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 07389 realtime_update_peer(peer->name, &peer->addr, 0); 07390 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07391 /* modify entry in peercnts table as _not_ registered */ 07392 peercnt_modify(0, 0, &peer->addr); 07393 /* Reset the address */ 07394 memset(&peer->addr, 0, sizeof(peer->addr)); 07395 /* Reset expiry value */ 07396 peer->expiry = min_reg_expire; 07397 if (!ast_test_flag(peer, IAX_TEMPONLY)) 07398 ast_db_del("IAX/Registry", peer->name); 07399 register_peer_exten(peer, 0); 07400 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07401 if (iax2_regfunk) 07402 iax2_regfunk(peer->name, 0); 07403 07404 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 07405 unlink_peer(peer); 07406 07407 peer_unref(peer); 07408 }
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 2369 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find(), ao2_ref(), ast_copy_flags, 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, iaxsl, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), NEW_ALLOW, new_iax(), option_debug, 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().
02370 { 02371 int res = 0; 02372 int x; 02373 /* this call is calltoken validated as long as it is either NEW_FORCE 02374 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02375 int validated = (new > NEW_ALLOW) ? 1 : 0; 02376 char host[80]; 02377 02378 if (new <= NEW_ALLOW) { 02379 if (callno) { 02380 struct chan_iax2_pvt *pvt; 02381 struct chan_iax2_pvt tmp_pvt = { 02382 .callno = dcallno, 02383 .peercallno = callno, 02384 .transfercallno = callno, 02385 /* hack!! */ 02386 .frames_received = check_dcallno, 02387 }; 02388 02389 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02390 /* this works for finding normal call numbers not involving transfering */ 02391 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02392 if (return_locked) { 02393 ast_mutex_lock(&iaxsl[pvt->callno]); 02394 } 02395 res = pvt->callno; 02396 ao2_ref(pvt, -1); 02397 pvt = NULL; 02398 return res; 02399 } 02400 /* this searches for transfer call numbers that might not get caught otherwise */ 02401 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02402 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02403 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02404 if (return_locked) { 02405 ast_mutex_lock(&iaxsl[pvt->callno]); 02406 } 02407 res = pvt->callno; 02408 ao2_ref(pvt, -1); 02409 pvt = NULL; 02410 return res; 02411 } 02412 } 02413 /* This will occur on the first response to a message that we initiated, 02414 * such as a PING. */ 02415 if (dcallno) { 02416 ast_mutex_lock(&iaxsl[dcallno]); 02417 } 02418 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02419 iaxs[dcallno]->peercallno = callno; 02420 res = dcallno; 02421 store_by_peercallno(iaxs[dcallno]); 02422 if (!res || !return_locked) { 02423 ast_mutex_unlock(&iaxsl[dcallno]); 02424 } 02425 return res; 02426 } 02427 if (dcallno) { 02428 ast_mutex_unlock(&iaxsl[dcallno]); 02429 } 02430 #ifdef IAX_OLD_FIND 02431 /* If we get here, we SHOULD NOT find a call structure for this 02432 callno; if we do, it means that there is a call structure that 02433 has a peer callno but did NOT get entered into the hash table, 02434 which is bad. 02435 02436 If we find a call structure using this old, slow method, output a log 02437 message so we'll know about it. After a few months of leaving this in 02438 place, if we don't hear about people seeing these messages, we can 02439 remove this code for good. 02440 */ 02441 02442 for (x = 1; !res && x < maxnontrunkcall; x++) { 02443 ast_mutex_lock(&iaxsl[x]); 02444 if (iaxs[x]) { 02445 /* Look for an exact match */ 02446 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02447 res = x; 02448 } 02449 } 02450 if (!res || !return_locked) 02451 ast_mutex_unlock(&iaxsl[x]); 02452 } 02453 02454 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02455 ast_mutex_lock(&iaxsl[x]); 02456 if (iaxs[x]) { 02457 /* Look for an exact match */ 02458 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02459 res = x; 02460 } 02461 } 02462 if (!res || !return_locked) 02463 ast_mutex_unlock(&iaxsl[x]); 02464 } 02465 02466 if (res) { 02467 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 02468 } 02469 #endif 02470 } 02471 if (!res && (new >= NEW_ALLOW)) { 02472 struct callno_entry *callno_entry; 02473 /* It may seem odd that we look through the peer list for a name for 02474 * this *incoming* call. Well, it is weird. However, users don't 02475 * have an IP address/port number that we can match against. So, 02476 * this is just checking for a peer that has that IP/port and 02477 * assuming that we have a user of the same name. This isn't always 02478 * correct, but it will be changed if needed after authentication. */ 02479 if (!iax2_getpeername(*sin, host, sizeof(host))) 02480 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02481 02482 if (peercnt_add(sin)) { 02483 /* This address has hit its callnumber limit. When the limit 02484 * is reached, the connection is not added to the peercnts table.*/ 02485 return 0; 02486 } 02487 02488 if (!(callno_entry = get_unused_callno(0, validated))) { 02489 /* since we ran out of space, remove the peercnt 02490 * entry we added earlier */ 02491 peercnt_remove_by_addr(sin); 02492 ast_log(LOG_WARNING, "No more space\n"); 02493 return 0; 02494 } 02495 x = callno_entry->callno; 02496 ast_mutex_lock(&iaxsl[x]); 02497 02498 iaxs[x] = new_iax(sin, host); 02499 update_max_nontrunk(); 02500 if (iaxs[x]) { 02501 if (option_debug && iaxdebug) 02502 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 02503 iaxs[x]->callno_entry = callno_entry; 02504 iaxs[x]->sockfd = sockfd; 02505 iaxs[x]->addr.sin_port = sin->sin_port; 02506 iaxs[x]->addr.sin_family = sin->sin_family; 02507 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02508 iaxs[x]->peercallno = callno; 02509 iaxs[x]->callno = x; 02510 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02511 iaxs[x]->expiry = min_reg_expire; 02512 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02513 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02514 iaxs[x]->amaflags = amaflags; 02515 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02516 02517 ast_string_field_set(iaxs[x], accountcode, accountcode); 02518 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02519 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02520 02521 if (iaxs[x]->peercallno) { 02522 store_by_peercallno(iaxs[x]); 02523 } 02524 } else { 02525 ast_log(LOG_WARNING, "Out of resources\n"); 02526 ast_mutex_unlock(&iaxsl[x]); 02527 replace_callno(callno_entry); 02528 return 0; 02529 } 02530 if (!return_locked) 02531 ast_mutex_unlock(&iaxsl[x]); 02532 res = x; 02533 } 02534 return res; 02535 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3484 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(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, iax2_registry::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().
03485 { 03486 int callno = PTR_TO_CALLNO(p); 03487 struct chan_iax2_pvt *pvt = NULL; 03488 struct iax_frame *fr; 03489 jb_frame frame; 03490 int ret; 03491 long now; 03492 long next; 03493 struct timeval tv; 03494 03495 /* Make sure we have a valid private structure before going on */ 03496 ast_mutex_lock(&iaxsl[callno]); 03497 pvt = iaxs[callno]; 03498 if (!pvt) { 03499 /* No go! */ 03500 ast_mutex_unlock(&iaxsl[callno]); 03501 return; 03502 } 03503 03504 pvt->jbid = -1; 03505 03506 gettimeofday(&tv,NULL); 03507 /* round up a millisecond since ast_sched_runq does; */ 03508 /* prevents us from spinning while waiting for our now */ 03509 /* to catch up with runq's now */ 03510 tv.tv_usec += 1000; 03511 03512 now = ast_tvdiff_ms(tv, pvt->rxcore); 03513 03514 if(now >= (next = jb_next(pvt->jb))) { 03515 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 03516 switch(ret) { 03517 case JB_OK: 03518 fr = frame.data; 03519 __do_deliver(fr); 03520 /* __do_deliver() can cause the call to disappear */ 03521 pvt = iaxs[callno]; 03522 break; 03523 case JB_INTERP: 03524 { 03525 struct ast_frame af = { 0, }; 03526 03527 /* create an interpolation frame */ 03528 af.frametype = AST_FRAME_VOICE; 03529 af.subclass = pvt->voiceformat; 03530 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03531 af.src = "IAX2 JB interpolation"; 03532 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03533 af.offset = AST_FRIENDLY_OFFSET; 03534 03535 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03536 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03537 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03538 iax2_queue_frame(callno, &af); 03539 /* iax2_queue_frame() could cause the call to disappear */ 03540 pvt = iaxs[callno]; 03541 } 03542 } 03543 break; 03544 case JB_DROP: 03545 iax2_frame_free(frame.data); 03546 break; 03547 case JB_NOFRAME: 03548 case JB_EMPTY: 03549 /* do nothing */ 03550 break; 03551 default: 03552 /* shouldn't happen */ 03553 break; 03554 } 03555 } 03556 if (pvt) 03557 update_jbsched(pvt); 03558 ast_mutex_unlock(&iaxsl[callno]); 03559 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7058 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
07059 { 07060 struct iax2_registry *reg = (struct iax2_registry *)data; 07061 reg->expire = -1; 07062 iax2_do_register(reg); 07063 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10269 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
10270 { 10271 struct iax2_peer *peer = (struct iax2_peer *)data; 10272 int callno; 10273 10274 if (peer->lastms > -1) { 10275 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 10276 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 10277 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 10278 } 10279 if ((callno = peer->callno) > 0) { 10280 ast_mutex_lock(&iaxsl[callno]); 10281 iax2_destroy(callno); 10282 ast_mutex_unlock(&iaxsl[callno]); 10283 } 10284 peer->callno = 0; 10285 peer->lastms = -1; 10286 /* Try again quickly */ 10287 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10288 if (peer->pokeexpire == -1) 10289 peer_unref(peer); 10290 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7823 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
07824 { 07825 struct iax2_peer *peer = (struct iax2_peer *)data; 07826 iax2_poke_peer(peer, 0); 07827 peer_unref(peer); 07828 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5780 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, and iax2_peer::username.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
05781 { 05782 regex_t regexbuf; 05783 int havepattern = 0; 05784 int total_peers = 0; 05785 int online_peers = 0; 05786 int offline_peers = 0; 05787 int unmonitored_peers = 0; 05788 struct ao2_iterator i; 05789 05790 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 05791 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 05792 05793 struct iax2_peer *peer = NULL; 05794 char name[256]; 05795 int registeredonly=0; 05796 char *term = manager ? "\r\n" : "\n"; 05797 05798 switch (argc) { 05799 case 6: 05800 if (!strcasecmp(argv[3], "registered")) 05801 registeredonly = 1; 05802 else 05803 return RESULT_SHOWUSAGE; 05804 if (!strcasecmp(argv[4], "like")) { 05805 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 05806 return RESULT_SHOWUSAGE; 05807 havepattern = 1; 05808 } else 05809 return RESULT_SHOWUSAGE; 05810 break; 05811 case 5: 05812 if (!strcasecmp(argv[3], "like")) { 05813 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05814 return RESULT_SHOWUSAGE; 05815 havepattern = 1; 05816 } else 05817 return RESULT_SHOWUSAGE; 05818 break; 05819 case 4: 05820 if (!strcasecmp(argv[3], "registered")) 05821 registeredonly = 1; 05822 else 05823 return RESULT_SHOWUSAGE; 05824 break; 05825 case 3: 05826 break; 05827 default: 05828 return RESULT_SHOWUSAGE; 05829 } 05830 05831 05832 if (s) 05833 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05834 else 05835 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05836 05837 i = ao2_iterator_init(peers, 0); 05838 for (peer = ao2_iterator_next(&i); peer; 05839 peer_unref(peer), peer = ao2_iterator_next(&i)) { 05840 char nm[20]; 05841 char status[20]; 05842 char srch[2000]; 05843 int retstatus; 05844 05845 if (registeredonly && !peer->addr.sin_addr.s_addr) 05846 continue; 05847 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 05848 continue; 05849 05850 if (!ast_strlen_zero(peer->username)) 05851 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 05852 else 05853 ast_copy_string(name, peer->name, sizeof(name)); 05854 05855 retstatus = peer_status(peer, status, sizeof(status)); 05856 if (retstatus > 0) 05857 online_peers++; 05858 else if (!retstatus) 05859 offline_peers++; 05860 else 05861 unmonitored_peers++; 05862 05863 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 05864 05865 snprintf(srch, sizeof(srch), FORMAT, name, 05866 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05867 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05868 nm, 05869 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05870 peer->encmethods ? "(E)" : " ", status, term); 05871 05872 if (s) 05873 astman_append(s, FORMAT, name, 05874 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 05875 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05876 nm, 05877 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05878 peer->encmethods ? "(E)" : " ", status, term); 05879 else 05880 ast_cli(fd, FORMAT, name, 05881 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05882 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05883 nm, 05884 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05885 peer->encmethods ? "(E)" : " ", status, term); 05886 total_peers++; 05887 } 05888 ao2_iterator_destroy(&i); 05889 05890 if (s) 05891 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05892 else 05893 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05894 05895 if (havepattern) 05896 regfree(®exbuf); 05897 05898 return RESULT_SUCCESS; 05899 #undef FORMAT 05900 #undef FORMAT2 05901 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 12802 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1076 of file chan_iax2.c.
References ast_copy_string(), ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
01077 { 01078 struct iax2_thread *thread = NULL; 01079 static time_t lasterror; 01080 static time_t t; 01081 01082 thread = find_idle_thread(); 01083 01084 if (thread != NULL) { 01085 thread->schedfunc = func; 01086 thread->scheddata = data; 01087 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01088 #ifdef DEBUG_SCHED_MULTITHREAD 01089 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01090 #endif 01091 signal_condition(&thread->lock, &thread->cond); 01092 return 0; 01093 } 01094 time(&t); 01095 if (t != lasterror && option_debug) 01096 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 01097 lasterror = t; 01098 01099 return -1; 01100 }
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 6306 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().
06308 { 06309 struct ast_frame f = { 0, }; 06310 int res = 0; 06311 f.frametype = type; 06312 f.subclass = command; 06313 f.datalen = datalen; 06314 f.src = __FUNCTION__; 06315 f.data = (void *) data; 06316 06317 if ((res = queue_signalling(i, &f)) <= 0) { 06318 return res; 06319 } 06320 return iax2_send(i, &f, ts, seqno, now, transfer, final); 06321 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1163 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01164 { 01165 int callno = (long) data; 01166 01167 ast_mutex_lock(&iaxsl[callno]); 01168 01169 if (iaxs[callno]) { 01170 if (iaxs[callno]->peercallno) { 01171 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01172 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01173 } else { 01174 /* I am the schedule, so I'm allowed to do this */ 01175 iaxs[callno]->lagid = -1; 01176 } 01177 } else { 01178 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno); 01179 } 01180 01181 ast_mutex_unlock(&iaxsl[callno]); 01182 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1118 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, LOG_DEBUG, option_debug, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
01119 { 01120 int callno = (long) data; 01121 01122 ast_mutex_lock(&iaxsl[callno]); 01123 01124 if (iaxs[callno]) { 01125 if (iaxs[callno]->peercallno) { 01126 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01127 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01128 } else { 01129 /* I am the schedule, so I'm allowed to do this */ 01130 iaxs[callno]->pingid = -1; 01131 } 01132 } else if (option_debug > 0) { 01133 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno); 01134 } 01135 01136 ast_mutex_unlock(&iaxsl[callno]); 01137 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 12490 of file chan_iax2.c.
References ao2_ref(), ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_netsock_release(), AST_PTHREADT_NULL, 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, iaxq, iaxs, iaxsl, iax2_thread::list, ast_firmware_list::lock, netsock, outsock, peercnts, peers, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, users, and waresl.
12491 { 12492 struct iax2_thread *thread = NULL; 12493 int x; 12494 12495 /* Make sure threads do not hold shared resources when they are canceled */ 12496 12497 /* Grab the sched lock resource to keep it away from threads about to die */ 12498 /* Cancel the network thread, close the net socket */ 12499 if (netthreadid != AST_PTHREADT_NULL) { 12500 AST_LIST_LOCK(&iaxq.queue); 12501 ast_mutex_lock(&sched_lock); 12502 pthread_cancel(netthreadid); 12503 ast_cond_signal(&sched_cond); 12504 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 12505 AST_LIST_UNLOCK(&iaxq.queue); 12506 pthread_join(netthreadid, NULL); 12507 } 12508 if (schedthreadid != AST_PTHREADT_NULL) { 12509 ast_mutex_lock(&sched_lock); 12510 pthread_cancel(schedthreadid); 12511 ast_cond_signal(&sched_cond); 12512 ast_mutex_unlock(&sched_lock); 12513 pthread_join(schedthreadid, NULL); 12514 } 12515 12516 /* Call for all threads to halt */ 12517 AST_LIST_LOCK(&idle_list); 12518 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 12519 AST_LIST_REMOVE_CURRENT(&idle_list, list); 12520 pthread_cancel(thread->threadid); 12521 } 12522 AST_LIST_TRAVERSE_SAFE_END 12523 AST_LIST_UNLOCK(&idle_list); 12524 12525 AST_LIST_LOCK(&active_list); 12526 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 12527 AST_LIST_REMOVE_CURRENT(&active_list, list); 12528 pthread_cancel(thread->threadid); 12529 } 12530 AST_LIST_TRAVERSE_SAFE_END 12531 AST_LIST_UNLOCK(&active_list); 12532 12533 AST_LIST_LOCK(&dynamic_list); 12534 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 12535 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 12536 pthread_cancel(thread->threadid); 12537 } 12538 AST_LIST_TRAVERSE_SAFE_END 12539 AST_LIST_UNLOCK(&dynamic_list); 12540 12541 AST_LIST_HEAD_DESTROY(&iaxq.queue); 12542 12543 /* Wait for threads to exit */ 12544 while(0 < iaxactivethreadcount) 12545 usleep(10000); 12546 12547 ast_netsock_release(netsock); 12548 ast_netsock_release(outsock); 12549 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 12550 if (iaxs[x]) { 12551 iax2_destroy(x); 12552 } 12553 } 12554 ast_manager_unregister( "IAXpeers" ); 12555 ast_manager_unregister( "IAXnetstats" ); 12556 ast_unregister_application(papp); 12557 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12558 ast_unregister_switch(&iax2_switch); 12559 ast_channel_unregister(&iax2_tech); 12560 delete_users(); 12561 iax_provision_unload(); 12562 sched_context_destroy(sched); 12563 reload_firmware(1); 12564 12565 ast_mutex_destroy(&waresl.lock); 12566 12567 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12568 ast_mutex_destroy(&iaxsl[x]); 12569 } 12570 12571 ao2_ref(peers, -1); 12572 ao2_ref(users, -1); 12573 ao2_ref(iax_peercallno_pvts, -1); 12574 ao2_ref(iax_transfercallno_pvts, -1); 12575 ao2_ref(peercnts, -1); 12576 ao2_ref(callno_limits, -1); 12577 ao2_ref(calltoken_ignores, -1); 12578 ao2_ref(callno_pool, -1); 12579 ao2_ref(callno_pool_trunk, -1); 12580 12581 return 0; 12582 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 12802 of file chan_iax2.c.
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2136 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ao2_ref(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), calltoken_ignores, addr_range::ha, and LOG_WARNING.
Referenced by set_config().
02137 { 02138 struct addr_range tmp; 02139 struct addr_range *addr_range = NULL; 02140 struct ast_ha *ha = NULL; 02141 02142 if (ast_strlen_zero(addr)) { 02143 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02144 return -1; 02145 } 02146 02147 ha = ast_append_ha("permit", addr, NULL); 02148 02149 /* check for valid config information */ 02150 if (!ha) { 02151 ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr); 02152 return -1; 02153 } 02154 02155 ast_copy_ha(ha, &tmp.ha); 02156 /* find or create the addr_range */ 02157 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02158 ao2_lock(addr_range); 02159 addr_range->delme = 0; 02160 ao2_unlock(addr_range); 02161 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02162 /* copy over config data into addr_range object */ 02163 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02164 ao2_link(calltoken_ignores, addr_range); 02165 } else { 02166 ast_free_ha(ha); 02167 return -1; 02168 } 02169 02170 ast_free_ha(ha); 02171 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02172 02173 return 0; 02174 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4120 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().
04121 { 04122 /* first make sure their are two empty bytes left in ied->buf */ 04123 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04124 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04125 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04126 pvt->calltoken_ie_len = 2; 04127 } 04128 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1790 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
01791 { 01792 struct addr_range *lim1 = obj, *lim2 = arg; 01793 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) && 01794 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ? 01795 CMP_MATCH | CMP_STOP : 0; 01796 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1777 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01778 { 01779 struct addr_range *lim = obj; 01780 lim->delme = 1; 01781 return 0; 01782 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1784 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01785 { 01786 const struct addr_range *lim = obj; 01787 return abs((int) lim->ha.netaddr.s_addr); 01788 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1810 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
01811 { 01812 struct addr_range *addr_range = obj; 01813 struct sockaddr_in *sin = arg; 01814 01815 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 01816 return CMP_MATCH | CMP_STOP; 01817 } 01818 return 0; 01819 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 6362 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
06363 { 06364 while(con) { 06365 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 06366 return -1; 06367 con = con->next; 06368 } 06369 return 0; 06370 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 6122 of file chan_iax2.c.
References 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, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
06123 { 06124 int x; 06125 int numchans = 0; 06126 char first_message[10] = { 0, }; 06127 char last_message[10] = { 0, }; 06128 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06129 ast_mutex_lock(&iaxsl[x]); 06130 if (iaxs[x]) { 06131 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06132 char *fmt; 06133 jb_info jbinfo; 06134 06135 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06136 jb_getinfo(iaxs[x]->jb, &jbinfo); 06137 localjitter = jbinfo.jitter; 06138 localdelay = jbinfo.current - jbinfo.min; 06139 locallost = jbinfo.frames_lost; 06140 locallosspct = jbinfo.losspct/1000; 06141 localdropped = jbinfo.frames_dropped; 06142 localooo = jbinfo.frames_ooo; 06143 } else { 06144 localjitter = -1; 06145 localdelay = 0; 06146 locallost = -1; 06147 locallosspct = -1; 06148 localdropped = 0; 06149 localooo = -1; 06150 } 06151 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06152 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06153 if (limit_fmt) 06154 fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"; 06155 else 06156 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"; 06157 if (s) 06158 06159 astman_append(s, fmt, 06160 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06161 iaxs[x]->pingtime, 06162 localjitter, 06163 localdelay, 06164 locallost, 06165 locallosspct, 06166 localdropped, 06167 localooo, 06168 iaxs[x]->frames_received/1000, 06169 iaxs[x]->remote_rr.jitter, 06170 iaxs[x]->remote_rr.delay, 06171 iaxs[x]->remote_rr.losscnt, 06172 iaxs[x]->remote_rr.losspct, 06173 iaxs[x]->remote_rr.dropped, 06174 iaxs[x]->remote_rr.ooo, 06175 iaxs[x]->remote_rr.packets/1000, 06176 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06177 first_message, 06178 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06179 last_message); 06180 else 06181 ast_cli(fd, fmt, 06182 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06183 iaxs[x]->pingtime, 06184 localjitter, 06185 localdelay, 06186 locallost, 06187 locallosspct, 06188 localdropped, 06189 localooo, 06190 iaxs[x]->frames_received/1000, 06191 iaxs[x]->remote_rr.jitter, 06192 iaxs[x]->remote_rr.delay, 06193 iaxs[x]->remote_rr.losscnt, 06194 iaxs[x]->remote_rr.losspct, 06195 iaxs[x]->remote_rr.dropped, 06196 iaxs[x]->remote_rr.ooo, 06197 iaxs[x]->remote_rr.packets/1000, 06198 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06199 first_message, 06200 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06201 last_message); 06202 numchans++; 06203 } 06204 ast_mutex_unlock(&iaxsl[x]); 06205 } 06206 return numchans; 06207 }
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 4945 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_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_hangup(), 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(), 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, chan_iax2_pvt::dnid, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_tech, iaxs, iaxsl, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, 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, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
04946 { 04947 struct ast_channel *tmp; 04948 struct chan_iax2_pvt *i; 04949 struct ast_variable *v = NULL; 04950 04951 if (!(i = iaxs[callno])) { 04952 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 04953 return NULL; 04954 } 04955 04956 /* Don't hold call lock */ 04957 ast_mutex_unlock(&iaxsl[callno]); 04958 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); 04959 ast_mutex_lock(&iaxsl[callno]); 04960 if (i != iaxs[callno]) { 04961 if (tmp) { 04962 /* unlock and relock iaxsl[callno] to preserve locking order */ 04963 ast_mutex_unlock(&iaxsl[callno]); 04964 ast_channel_free(tmp); 04965 ast_mutex_lock(&iaxsl[callno]); 04966 } 04967 return NULL; 04968 } 04969 04970 if (!tmp) 04971 return NULL; 04972 tmp->tech = &iax2_tech; 04973 /* We can support any format by default, until we get restricted */ 04974 tmp->nativeformats = capability; 04975 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 04976 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 04977 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 04978 04979 /* Don't use ast_set_callerid() here because it will 04980 * generate a NewCallerID event before the NewChannel event */ 04981 if (!ast_strlen_zero(i->ani)) 04982 tmp->cid.cid_ani = ast_strdup(i->ani); 04983 else 04984 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04985 tmp->cid.cid_dnid = ast_strdup(i->dnid); 04986 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04987 tmp->cid.cid_pres = i->calling_pres; 04988 tmp->cid.cid_ton = i->calling_ton; 04989 tmp->cid.cid_tns = i->calling_tns; 04990 if (!ast_strlen_zero(i->language)) 04991 ast_string_field_set(tmp, language, i->language); 04992 if (!ast_strlen_zero(i->accountcode)) 04993 ast_string_field_set(tmp, accountcode, i->accountcode); 04994 if (i->amaflags) 04995 tmp->amaflags = i->amaflags; 04996 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04997 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04998 if (i->adsi) 04999 tmp->adsicpe = i->peeradsicpe; 05000 else 05001 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05002 i->owner = tmp; 05003 i->capability = capability; 05004 05005 for (v = i->vars ; v ; v = v->next) 05006 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05007 05008 if (state != AST_STATE_DOWN) { 05009 if (ast_pbx_start(tmp)) { 05010 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05011 ast_hangup(tmp); 05012 i->owner = NULL; 05013 return NULL; 05014 } 05015 } 05016 05017 ast_module_ref(ast_module_info->self); 05018 05019 return tmp; 05020 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3138 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03139 { 03140 #ifdef SCHED_MULTITHREADED 03141 if (schedule_action(__attempt_transmit, data)) 03142 #endif 03143 __attempt_transmit(data); 03144 return 0; 03145 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 7745 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), iaxs, and sched.
Referenced by socket_process().
07746 { 07747 /* Schedule sending the authentication failure in one second, to prevent 07748 guessing */ 07749 if (iaxs[callno]) { 07750 iaxs[callno]->authfail = failcode; 07751 if (delayreject) { 07752 AST_SCHED_DEL(sched, iaxs[callno]->authid); 07753 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 07754 } else 07755 auth_reject((void *)(long)callno); 07756 } 07757 return 0; 07758 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 7731 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
07732 { 07733 int callno = (int)(long)(data); 07734 ast_mutex_lock(&iaxsl[callno]); 07735 if (iaxs[callno]) 07736 iaxs[callno]->authid = -1; 07737 ast_mutex_unlock(&iaxsl[callno]); 07738 #ifdef SCHED_MULTITHREADED 07739 if (schedule_action(__auth_reject, data)) 07740 #endif 07741 __auth_reject(data); 07742 return 0; 07743 }
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 6925 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().
06926 { 06927 int res = -1; 06928 int x; 06929 if (!ast_strlen_zero(keyn)) { 06930 if (!(authmethods & IAX_AUTH_RSA)) { 06931 if (ast_strlen_zero(secret)) 06932 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)); 06933 } else if (ast_strlen_zero(challenge)) { 06934 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 06935 } else { 06936 char sig[256]; 06937 struct ast_key *key; 06938 key = ast_key_get(keyn, AST_KEY_PRIVATE); 06939 if (!key) { 06940 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 06941 } else { 06942 if (ast_sign(key, (char*)challenge, sig)) { 06943 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 06944 res = -1; 06945 } else { 06946 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 06947 res = 0; 06948 } 06949 } 06950 } 06951 } 06952 /* Fall back */ 06953 if (res && !ast_strlen_zero(secret)) { 06954 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 06955 struct MD5Context md5; 06956 unsigned char digest[16]; 06957 char digres[128]; 06958 MD5Init(&md5); 06959 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 06960 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 06961 MD5Final(digest, &md5); 06962 /* If they support md5, authenticate with it. */ 06963 for (x=0;x<16;x++) 06964 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 06965 if (pvt) { 06966 build_encryption_keys(digest, pvt); 06967 } 06968 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 06969 res = 0; 06970 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 06971 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 06972 res = 0; 06973 } else 06974 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 06975 } 06976 return res; 06977 }
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 6983 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax2_peer::authmethods, chan_iax2_pvt::callno, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, ies, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.
Referenced by socket_process().
06984 { 06985 struct iax2_peer *peer = NULL; 06986 /* Start pessimistic */ 06987 int res = -1; 06988 int authmethods = 0; 06989 struct iax_ie_data ied; 06990 uint16_t callno = p->callno; 06991 06992 memset(&ied, 0, sizeof(ied)); 06993 06994 if (ies->username) 06995 ast_string_field_set(p, username, ies->username); 06996 if (ies->challenge) 06997 ast_string_field_set(p, challenge, ies->challenge); 06998 if (ies->authmethods) 06999 authmethods = ies->authmethods; 07000 if (authmethods & IAX_AUTH_MD5) 07001 merge_encryption(p, ies->encmethods); 07002 else 07003 p->encmethods = 0; 07004 07005 /* Check for override RSA authentication first */ 07006 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07007 /* Normal password authentication */ 07008 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07009 } else { 07010 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07011 while ((peer = ao2_iterator_next(&i))) { 07012 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07013 /* No peer specified at our end, or this is the peer */ 07014 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07015 /* No username specified in peer rule, or this is the right username */ 07016 && (!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))) 07017 /* No specified host, or this is our host */ 07018 ) { 07019 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07020 if (!res) { 07021 peer_unref(peer); 07022 break; 07023 } 07024 } 07025 peer_unref(peer); 07026 } 07027 ao2_iterator_destroy(&i); 07028 if (!peer) { 07029 /* We checked our list and didn't find one. It's unlikely, but possible, 07030 that we're trying to authenticate *to* a realtime peer */ 07031 const char *peer_name = ast_strdupa(p->peer); 07032 ast_mutex_unlock(&iaxsl[callno]); 07033 if ((peer = realtime_peer(peer_name, NULL))) { 07034 ast_mutex_lock(&iaxsl[callno]); 07035 if (!(p = iaxs[callno])) { 07036 peer_unref(peer); 07037 return -1; 07038 } 07039 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07040 peer_unref(peer); 07041 } 07042 if (!peer) { 07043 ast_mutex_lock(&iaxsl[callno]); 07044 if (!(p = iaxs[callno])) 07045 return -1; 07046 } 07047 } 07048 } 07049 if (ies->encmethods) 07050 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07051 if (!res) 07052 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 07053 return res; 07054 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 6634 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, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, iax2_user::maxauthreq, send_command(), send_command_final(), user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
06635 { 06636 struct iax_ie_data ied; 06637 int res = -1, authreq_restrict = 0; 06638 char challenge[10]; 06639 struct chan_iax2_pvt *p = iaxs[call_num]; 06640 06641 memset(&ied, 0, sizeof(ied)); 06642 06643 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 06644 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06645 struct iax2_user *user, tmp_user = { 06646 .name = p->username, 06647 }; 06648 06649 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06650 if (user) { 06651 if (user->curauthreq == user->maxauthreq) 06652 authreq_restrict = 1; 06653 else 06654 user->curauthreq++; 06655 user = user_unref(user); 06656 } 06657 } 06658 06659 /* If the AUTHREQ limit test failed, send back an error */ 06660 if (authreq_restrict) { 06661 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 06662 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 06663 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 06664 return 0; 06665 } 06666 06667 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06668 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 06669 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06670 ast_string_field_set(p, challenge, challenge); 06671 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 06672 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 06673 } 06674 if (p->encmethods) 06675 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 06676 06677 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 06678 06679 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 06680 06681 if (p->encmethods) 06682 ast_set_flag(p, IAX_ENCRYPTED); 06683 06684 return res; 06685 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6687 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_user::name, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
06688 { 06689 char requeststr[256]; 06690 char md5secret[256] = ""; 06691 char secret[256] = ""; 06692 char rsasecret[256] = ""; 06693 int res = -1; 06694 int x; 06695 struct iax2_user *user, tmp_user = { 06696 .name = p->username, 06697 }; 06698 06699 if (p->authrej) { 06700 return res; 06701 } 06702 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06703 if (user) { 06704 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06705 ast_atomic_fetchadd_int(&user->curauthreq, -1); 06706 ast_clear_flag(p, IAX_MAXAUTHREQ); 06707 } 06708 ast_string_field_set(p, host, user->name); 06709 user = user_unref(user); 06710 } 06711 06712 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 06713 return res; 06714 if (ies->password) 06715 ast_copy_string(secret, ies->password, sizeof(secret)); 06716 if (ies->md5_result) 06717 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06718 if (ies->rsa_result) 06719 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06720 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 06721 struct ast_key *key; 06722 char *keyn; 06723 char tmpkey[256]; 06724 char *stringp=NULL; 06725 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 06726 stringp=tmpkey; 06727 keyn = strsep(&stringp, ":"); 06728 while(keyn) { 06729 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06730 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 06731 res = 0; 06732 break; 06733 } else if (!key) 06734 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 06735 keyn = strsep(&stringp, ":"); 06736 } 06737 } else if (p->authmethods & IAX_AUTH_MD5) { 06738 struct MD5Context md5; 06739 unsigned char digest[16]; 06740 char *tmppw, *stringp; 06741 06742 tmppw = ast_strdupa(p->secret); 06743 stringp = tmppw; 06744 while((tmppw = strsep(&stringp, ";"))) { 06745 MD5Init(&md5); 06746 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 06747 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06748 MD5Final(digest, &md5); 06749 /* If they support md5, authenticate with it. */ 06750 for (x=0;x<16;x++) 06751 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06752 if (!strcasecmp(requeststr, md5secret)) { 06753 res = 0; 06754 break; 06755 } 06756 } 06757 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 06758 if (!strcmp(secret, p->secret)) 06759 res = 0; 06760 } 06761 return res; 06762 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4055 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
04056 { 04057 #ifdef SCHED_MULTITHREADED 04058 if (schedule_action(__auto_congest, data)) 04059 #endif 04060 __auto_congest(data); 04061 return 0; 04062 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 7775 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
07776 { 07777 int callno = (int)(long)(data); 07778 ast_mutex_lock(&iaxsl[callno]); 07779 if (iaxs[callno]) { 07780 iaxs[callno]->autoid = -1; 07781 } 07782 ast_mutex_unlock(&iaxsl[callno]); 07783 #ifdef SCHED_MULTITHREADED 07784 if (schedule_action(__auto_hangup, data)) 07785 #endif 07786 __auto_hangup(data); 07787 return 0; 07788 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2083 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ao2_ref(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by set_config().
02084 { 02085 struct addr_range *addr_range = NULL; 02086 struct addr_range tmp; 02087 struct ast_ha *ha; 02088 int limit; 02089 int found; 02090 02091 for (; v; v = v->next) { 02092 limit = -1; 02093 found = 0; 02094 ha = ast_append_ha("permit", v->name, NULL); 02095 02096 /* check for valid config information */ 02097 if (!ha) { 02098 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02099 continue; 02100 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02101 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02102 ast_free_ha(ha); 02103 continue; 02104 } 02105 02106 ast_copy_ha(ha, &tmp.ha); 02107 /* find or create the addr_range */ 02108 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02109 ao2_lock(addr_range); 02110 found = 1; 02111 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02112 ast_free_ha(ha); 02113 return; /* out of memory */ 02114 } 02115 02116 /* copy over config data into addr_range object */ 02117 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02118 ast_free_ha(ha); /* cleanup the tmp ha */ 02119 addr_range->limit = limit; 02120 addr_range->delme = 0; 02121 02122 /* cleanup */ 02123 if (found) { 02124 ao2_unlock(addr_range); 02125 } else { 02126 ao2_link(callno_limits, addr_range); 02127 } 02128 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02129 } 02130 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 10602 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
10603 { 10604 struct iax2_context *con; 10605 10606 if ((con = ast_calloc(1, sizeof(*con)))) 10607 ast_copy_string(con->context, context, sizeof(con->context)); 10608 10609 return con; 10610 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5349 of file chan_iax2.c.
References aes_decrypt_key128(), aes_encrypt_key128(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys().
05350 { 05351 /* it is required to hold the corresponding decrypt key to our encrypt key 05352 * in the pvt struct because queued frames occasionally need to be decrypted and 05353 * re-encrypted when updated for a retransmission */ 05354 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05355 aes_encrypt_key128(digest, &pvt->ecx); 05356 aes_decrypt_key128(digest, &pvt->mydcx); 05357 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5343 of file chan_iax2.c.
References aes_decrypt_key128(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05344 { 05345 build_ecx_key(digest, pvt); 05346 aes_decrypt_key128(digest, &pvt->dcx); 05347 }
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 10749 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_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_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, 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, iax2_peer::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, peers, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.
10750 { 10751 struct iax2_peer *peer = NULL; 10752 struct ast_ha *oldha = NULL; 10753 int maskfound=0; 10754 int found=0; 10755 int firstpass=1; 10756 struct iax2_peer tmp_peer = { 10757 .name = name, 10758 }; 10759 10760 if (!temponly) { 10761 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 10762 if (peer && !ast_test_flag(peer, IAX_DELME)) 10763 firstpass = 0; 10764 } 10765 10766 if (peer) { 10767 found++; 10768 if (firstpass) { 10769 oldha = peer->ha; 10770 peer->ha = NULL; 10771 } 10772 unlink_peer(peer); 10773 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 10774 peer->expire = -1; 10775 peer->pokeexpire = -1; 10776 peer->sockfd = defaultsockfd; 10777 if (ast_string_field_init(peer, 32)) 10778 peer = peer_unref(peer); 10779 } 10780 10781 if (peer) { 10782 if (firstpass) { 10783 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10784 peer->encmethods = iax2_encryption; 10785 peer->adsi = adsi; 10786 ast_string_field_set(peer,secret,""); 10787 if (!found) { 10788 ast_string_field_set(peer, name, name); 10789 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10790 peer->expiry = min_reg_expire; 10791 } 10792 peer->prefs = prefs; 10793 peer->capability = iax2_capability; 10794 peer->smoothing = 0; 10795 peer->pokefreqok = DEFAULT_FREQ_OK; 10796 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 10797 peer->maxcallno = 0; 10798 peercnt_modify(0, 0, &peer->addr); 10799 peer->calltoken_required = CALLTOKEN_DEFAULT; 10800 ast_string_field_set(peer,context,""); 10801 ast_string_field_set(peer,peercontext,""); 10802 ast_clear_flag(peer, IAX_HASCALLERID); 10803 ast_string_field_set(peer, cid_name, ""); 10804 ast_string_field_set(peer, cid_num, ""); 10805 ast_string_field_set(peer, mohinterpret, mohinterpret); 10806 ast_string_field_set(peer, mohsuggest, mohsuggest); 10807 } 10808 10809 if (!v) { 10810 v = alt; 10811 alt = NULL; 10812 } 10813 while(v) { 10814 if (!strcasecmp(v->name, "secret")) { 10815 ast_string_field_set(peer, secret, v->value); 10816 } else if (!strcasecmp(v->name, "mailbox")) { 10817 ast_string_field_set(peer, mailbox, v->value); 10818 } else if (!strcasecmp(v->name, "hasvoicemail")) { 10819 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 10820 ast_string_field_set(peer, mailbox, name); 10821 } 10822 } else if (!strcasecmp(v->name, "mohinterpret")) { 10823 ast_string_field_set(peer, mohinterpret, v->value); 10824 } else if (!strcasecmp(v->name, "mohsuggest")) { 10825 ast_string_field_set(peer, mohsuggest, v->value); 10826 } else if (!strcasecmp(v->name, "dbsecret")) { 10827 ast_string_field_set(peer, dbsecret, v->value); 10828 } else if (!strcasecmp(v->name, "trunk")) { 10829 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 10830 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 10831 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 10832 ast_clear_flag(peer, IAX_TRUNK); 10833 } 10834 } else if (!strcasecmp(v->name, "auth")) { 10835 peer->authmethods = get_auth_methods(v->value); 10836 } else if (!strcasecmp(v->name, "encryption")) { 10837 peer->encmethods = get_encrypt_methods(v->value); 10838 } else if (!strcasecmp(v->name, "notransfer")) { 10839 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10840 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 10841 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 10842 } else if (!strcasecmp(v->name, "transfer")) { 10843 if (!strcasecmp(v->value, "mediaonly")) { 10844 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10845 } else if (ast_true(v->value)) { 10846 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10847 } else 10848 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10849 } else if (!strcasecmp(v->name, "jitterbuffer")) { 10850 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 10851 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 10852 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 10853 } else if (!strcasecmp(v->name, "host")) { 10854 if (!strcasecmp(v->value, "dynamic")) { 10855 /* They'll register with us */ 10856 ast_set_flag(peer, IAX_DYNAMIC); 10857 if (!found) { 10858 /* Initialize stuff iff we're not found, otherwise 10859 we keep going with what we had */ 10860 memset(&peer->addr.sin_addr, 0, 4); 10861 if (peer->addr.sin_port) { 10862 /* If we've already got a port, make it the default rather than absolute */ 10863 peer->defaddr.sin_port = peer->addr.sin_port; 10864 peer->addr.sin_port = 0; 10865 } 10866 } 10867 } else { 10868 /* Non-dynamic. Make sure we become that way if we're not */ 10869 AST_SCHED_DEL(sched, peer->expire); 10870 ast_clear_flag(peer, IAX_DYNAMIC); 10871 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 10872 return peer_unref(peer); 10873 if (!peer->addr.sin_port) 10874 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10875 } 10876 if (!maskfound) 10877 inet_aton("255.255.255.255", &peer->mask); 10878 } else if (!strcasecmp(v->name, "defaultip")) { 10879 if (ast_get_ip(&peer->defaddr, v->value)) 10880 return peer_unref(peer); 10881 } else if (!strcasecmp(v->name, "sourceaddress")) { 10882 peer_set_srcaddr(peer, v->value); 10883 } else if (!strcasecmp(v->name, "permit") || 10884 !strcasecmp(v->name, "deny")) { 10885 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 10886 } else if (!strcasecmp(v->name, "mask")) { 10887 maskfound++; 10888 inet_aton(v->value, &peer->mask); 10889 } else if (!strcasecmp(v->name, "context")) { 10890 ast_string_field_set(peer, context, v->value); 10891 } else if (!strcasecmp(v->name, "regexten")) { 10892 ast_string_field_set(peer, regexten, v->value); 10893 } else if (!strcasecmp(v->name, "peercontext")) { 10894 ast_string_field_set(peer, peercontext, v->value); 10895 } else if (!strcasecmp(v->name, "port")) { 10896 if (ast_test_flag(peer, IAX_DYNAMIC)) 10897 peer->defaddr.sin_port = htons(atoi(v->value)); 10898 else 10899 peer->addr.sin_port = htons(atoi(v->value)); 10900 } else if (!strcasecmp(v->name, "username")) { 10901 ast_string_field_set(peer, username, v->value); 10902 } else if (!strcasecmp(v->name, "allow")) { 10903 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 10904 } else if (!strcasecmp(v->name, "disallow")) { 10905 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 10906 } else if (!strcasecmp(v->name, "callerid")) { 10907 if (!ast_strlen_zero(v->value)) { 10908 char name2[80]; 10909 char num2[80]; 10910 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 10911 ast_string_field_set(peer, cid_name, name2); 10912 ast_string_field_set(peer, cid_num, num2); 10913 } else { 10914 ast_string_field_set(peer, cid_name, ""); 10915 ast_string_field_set(peer, cid_num, ""); 10916 } 10917 ast_set_flag(peer, IAX_HASCALLERID); 10918 } else if (!strcasecmp(v->name, "fullname")) { 10919 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 10920 ast_set_flag(peer, IAX_HASCALLERID); 10921 } else if (!strcasecmp(v->name, "cid_number")) { 10922 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 10923 ast_set_flag(peer, IAX_HASCALLERID); 10924 } else if (!strcasecmp(v->name, "sendani")) { 10925 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 10926 } else if (!strcasecmp(v->name, "inkeys")) { 10927 ast_string_field_set(peer, inkeys, v->value); 10928 } else if (!strcasecmp(v->name, "outkey")) { 10929 ast_string_field_set(peer, outkey, v->value); 10930 } else if (!strcasecmp(v->name, "qualify")) { 10931 if (!strcasecmp(v->value, "no")) { 10932 peer->maxms = 0; 10933 } else if (!strcasecmp(v->value, "yes")) { 10934 peer->maxms = DEFAULT_MAXMS; 10935 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 10936 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); 10937 peer->maxms = 0; 10938 } 10939 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 10940 peer->smoothing = ast_true(v->value); 10941 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 10942 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 10943 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); 10944 } 10945 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 10946 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 10947 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); 10948 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 10949 } else if (!strcasecmp(v->name, "timezone")) { 10950 ast_string_field_set(peer, zonetag, v->value); 10951 } else if (!strcasecmp(v->name, "adsi")) { 10952 peer->adsi = ast_true(v->value); 10953 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 10954 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 10955 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 10956 } else { 10957 peercnt_modify(1, peer->maxcallno, &peer->addr); 10958 } 10959 } else if (!strcasecmp(v->name, "requirecalltoken")) { 10960 /* default is required unless in optional ip list */ 10961 if (ast_false(v->value)) { 10962 peer->calltoken_required = CALLTOKEN_NO; 10963 } else if (!strcasecmp(v->value, "auto")) { 10964 peer->calltoken_required = CALLTOKEN_AUTO; 10965 } else if (ast_true(v->value)) { 10966 peer->calltoken_required = CALLTOKEN_YES; 10967 } else { 10968 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 10969 } 10970 } /* else if (strcasecmp(v->name,"type")) */ 10971 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10972 v = v->next; 10973 if (!v) { 10974 v = alt; 10975 alt = NULL; 10976 } 10977 } 10978 if (!peer->authmethods) 10979 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 10980 ast_clear_flag(peer, IAX_DELME); 10981 /* Make sure these are IPv4 addresses */ 10982 peer->addr.sin_family = AF_INET; 10983 } 10984 if (oldha) 10985 ast_free_ha(oldha); 10986 return peer; 10987 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 5333 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05334 { 05335 long tmp; 05336 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05337 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05338 buf += sizeof(tmp); 05339 len -= sizeof(tmp); 05340 } 05341 }
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 11003 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::prefs, prefs, secret, iax2_user::secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
11004 { 11005 struct iax2_user *user = NULL; 11006 struct iax2_context *con, *conl = NULL; 11007 struct ast_ha *oldha = NULL; 11008 struct iax2_context *oldcon = NULL; 11009 int format; 11010 int firstpass=1; 11011 int oldcurauthreq = 0; 11012 char *varname = NULL, *varval = NULL; 11013 struct ast_variable *tmpvar = NULL; 11014 struct iax2_user tmp_user = { 11015 .name = name, 11016 }; 11017 11018 if (!temponly) { 11019 user = ao2_find(users, &tmp_user, OBJ_POINTER); 11020 if (user && !ast_test_flag(user, IAX_DELME)) 11021 firstpass = 0; 11022 } 11023 11024 if (user) { 11025 if (firstpass) { 11026 oldcurauthreq = user->curauthreq; 11027 oldha = user->ha; 11028 oldcon = user->contexts; 11029 user->ha = NULL; 11030 user->contexts = NULL; 11031 } 11032 /* Already in the list, remove it and it will be added back (or FREE'd) */ 11033 ao2_unlink(users, user); 11034 } else { 11035 user = ao2_alloc(sizeof(*user), user_destructor); 11036 } 11037 11038 if (user) { 11039 if (firstpass) { 11040 ast_string_field_free_memory(user); 11041 memset(user, 0, sizeof(struct iax2_user)); 11042 if (ast_string_field_init(user, 32)) { 11043 user = user_unref(user); 11044 goto cleanup; 11045 } 11046 user->maxauthreq = maxauthreq; 11047 user->curauthreq = oldcurauthreq; 11048 user->prefs = prefs; 11049 user->capability = iax2_capability; 11050 user->encmethods = iax2_encryption; 11051 user->adsi = adsi; 11052 user->calltoken_required = CALLTOKEN_DEFAULT; 11053 ast_string_field_set(user, name, name); 11054 ast_string_field_set(user, language, language); 11055 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 11056 ast_clear_flag(user, IAX_HASCALLERID); 11057 ast_string_field_set(user, cid_name, ""); 11058 ast_string_field_set(user, cid_num, ""); 11059 ast_string_field_set(user, accountcode, accountcode); 11060 ast_string_field_set(user, mohinterpret, mohinterpret); 11061 ast_string_field_set(user, mohsuggest, mohsuggest); 11062 } 11063 if (!v) { 11064 v = alt; 11065 alt = NULL; 11066 } 11067 while(v) { 11068 if (!strcasecmp(v->name, "context")) { 11069 con = build_context(v->value); 11070 if (con) { 11071 if (conl) 11072 conl->next = con; 11073 else 11074 user->contexts = con; 11075 conl = con; 11076 } 11077 } else if (!strcasecmp(v->name, "permit") || 11078 !strcasecmp(v->name, "deny")) { 11079 user->ha = ast_append_ha(v->name, v->value, user->ha); 11080 } else if (!strcasecmp(v->name, "setvar")) { 11081 varname = ast_strdupa(v->value); 11082 if (varname && (varval = strchr(varname,'='))) { 11083 *varval = '\0'; 11084 varval++; 11085 if((tmpvar = ast_variable_new(varname, varval))) { 11086 tmpvar->next = user->vars; 11087 user->vars = tmpvar; 11088 } 11089 } 11090 } else if (!strcasecmp(v->name, "allow")) { 11091 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 11092 } else if (!strcasecmp(v->name, "disallow")) { 11093 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 11094 } else if (!strcasecmp(v->name, "trunk")) { 11095 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 11096 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 11097 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 11098 ast_clear_flag(user, IAX_TRUNK); 11099 } 11100 } else if (!strcasecmp(v->name, "auth")) { 11101 user->authmethods = get_auth_methods(v->value); 11102 } else if (!strcasecmp(v->name, "encryption")) { 11103 user->encmethods = get_encrypt_methods(v->value); 11104 } else if (!strcasecmp(v->name, "notransfer")) { 11105 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11106 ast_clear_flag(user, IAX_TRANSFERMEDIA); 11107 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 11108 } else if (!strcasecmp(v->name, "transfer")) { 11109 if (!strcasecmp(v->value, "mediaonly")) { 11110 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11111 } else if (ast_true(v->value)) { 11112 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11113 } else 11114 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11115 } else if (!strcasecmp(v->name, "codecpriority")) { 11116 if(!strcasecmp(v->value, "caller")) 11117 ast_set_flag(user, IAX_CODEC_USER_FIRST); 11118 else if(!strcasecmp(v->value, "disabled")) 11119 ast_set_flag(user, IAX_CODEC_NOPREFS); 11120 else if(!strcasecmp(v->value, "reqonly")) { 11121 ast_set_flag(user, IAX_CODEC_NOCAP); 11122 ast_set_flag(user, IAX_CODEC_NOPREFS); 11123 } 11124 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11125 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 11126 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11127 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 11128 } else if (!strcasecmp(v->name, "dbsecret")) { 11129 ast_string_field_set(user, dbsecret, v->value); 11130 } else if (!strcasecmp(v->name, "secret")) { 11131 if (!ast_strlen_zero(user->secret)) { 11132 char *old = ast_strdupa(user->secret); 11133 11134 ast_string_field_build(user, secret, "%s;%s", old, v->value); 11135 } else 11136 ast_string_field_set(user, secret, v->value); 11137 } else if (!strcasecmp(v->name, "callerid")) { 11138 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 11139 char name2[80]; 11140 char num2[80]; 11141 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 11142 ast_string_field_set(user, cid_name, name2); 11143 ast_string_field_set(user, cid_num, num2); 11144 ast_set_flag(user, IAX_HASCALLERID); 11145 } else { 11146 ast_clear_flag(user, IAX_HASCALLERID); 11147 ast_string_field_set(user, cid_name, ""); 11148 ast_string_field_set(user, cid_num, ""); 11149 } 11150 } else if (!strcasecmp(v->name, "fullname")) { 11151 if (!ast_strlen_zero(v->value)) { 11152 ast_string_field_set(user, cid_name, v->value); 11153 ast_set_flag(user, IAX_HASCALLERID); 11154 } else { 11155 ast_string_field_set(user, cid_name, ""); 11156 if (ast_strlen_zero(user->cid_num)) 11157 ast_clear_flag(user, IAX_HASCALLERID); 11158 } 11159 } else if (!strcasecmp(v->name, "cid_number")) { 11160 if (!ast_strlen_zero(v->value)) { 11161 ast_string_field_set(user, cid_num, v->value); 11162 ast_set_flag(user, IAX_HASCALLERID); 11163 } else { 11164 ast_string_field_set(user, cid_num, ""); 11165 if (ast_strlen_zero(user->cid_name)) 11166 ast_clear_flag(user, IAX_HASCALLERID); 11167 } 11168 } else if (!strcasecmp(v->name, "accountcode")) { 11169 ast_string_field_set(user, accountcode, v->value); 11170 } else if (!strcasecmp(v->name, "mohinterpret")) { 11171 ast_string_field_set(user, mohinterpret, v->value); 11172 } else if (!strcasecmp(v->name, "mohsuggest")) { 11173 ast_string_field_set(user, mohsuggest, v->value); 11174 } else if (!strcasecmp(v->name, "language")) { 11175 ast_string_field_set(user, language, v->value); 11176 } else if (!strcasecmp(v->name, "amaflags")) { 11177 format = ast_cdr_amaflags2int(v->value); 11178 if (format < 0) { 11179 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11180 } else { 11181 user->amaflags = format; 11182 } 11183 } else if (!strcasecmp(v->name, "inkeys")) { 11184 ast_string_field_set(user, inkeys, v->value); 11185 } else if (!strcasecmp(v->name, "maxauthreq")) { 11186 user->maxauthreq = atoi(v->value); 11187 if (user->maxauthreq < 0) 11188 user->maxauthreq = 0; 11189 } else if (!strcasecmp(v->name, "adsi")) { 11190 user->adsi = ast_true(v->value); 11191 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11192 /* default is required unless in optional ip list */ 11193 if (ast_false(v->value)) { 11194 user->calltoken_required = CALLTOKEN_NO; 11195 } else if (!strcasecmp(v->value, "auto")) { 11196 user->calltoken_required = CALLTOKEN_AUTO; 11197 } else if (ast_true(v->value)) { 11198 user->calltoken_required = CALLTOKEN_YES; 11199 } else { 11200 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11201 } 11202 } /* else if (strcasecmp(v->name,"type")) */ 11203 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11204 v = v->next; 11205 if (!v) { 11206 v = alt; 11207 alt = NULL; 11208 } 11209 } 11210 if (!user->authmethods) { 11211 if (!ast_strlen_zero(user->secret)) { 11212 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11213 if (!ast_strlen_zero(user->inkeys)) 11214 user->authmethods |= IAX_AUTH_RSA; 11215 } else if (!ast_strlen_zero(user->inkeys)) { 11216 user->authmethods = IAX_AUTH_RSA; 11217 } else { 11218 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11219 } 11220 } 11221 ast_clear_flag(user, IAX_DELME); 11222 } 11223 cleanup: 11224 if (oldha) 11225 ast_free_ha(oldha); 11226 if (oldcon) 11227 free_context(oldcon); 11228 return user; 11229 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 11770 of file chan_iax2.c.
References add_empty_calltoken_ie(), ARRAY_LEN, AST_FRAME_IAX, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
11771 { 11772 struct sockaddr_in sin; 11773 int x; 11774 int callno; 11775 struct iax_ie_data ied; 11776 struct create_addr_info cai; 11777 struct parsed_dial_string pds; 11778 char *tmpstr; 11779 11780 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11781 /* Look for an *exact match* call. Once a call is negotiated, it can only 11782 look up entries for a single context */ 11783 if (!ast_mutex_trylock(&iaxsl[x])) { 11784 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 11785 return x; 11786 ast_mutex_unlock(&iaxsl[x]); 11787 } 11788 } 11789 11790 /* No match found, we need to create a new one */ 11791 11792 memset(&cai, 0, sizeof(cai)); 11793 memset(&ied, 0, sizeof(ied)); 11794 memset(&pds, 0, sizeof(pds)); 11795 11796 tmpstr = ast_strdupa(data); 11797 parse_dial_string(tmpstr, &pds); 11798 11799 if (ast_strlen_zero(pds.peer)) { 11800 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 11801 return -1; 11802 } 11803 11804 /* Populate our address from the given */ 11805 if (create_addr(pds.peer, NULL, &sin, &cai)) 11806 return -1; 11807 11808 if (option_debug) 11809 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 11810 pds.peer, pds.username, pds.password, pds.context); 11811 11812 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11813 if (callno < 1) { 11814 ast_log(LOG_WARNING, "Unable to create call\n"); 11815 return -1; 11816 } 11817 11818 ast_string_field_set(iaxs[callno], dproot, data); 11819 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 11820 11821 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 11822 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 11823 /* the string format is slightly different from a standard dial string, 11824 because the context appears in the 'exten' position 11825 */ 11826 if (pds.exten) 11827 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 11828 if (pds.username) 11829 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 11830 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 11831 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 11832 /* Keep password handy */ 11833 if (pds.password) 11834 ast_string_field_set(iaxs[callno], secret, pds.password); 11835 if (pds.key) 11836 ast_string_field_set(iaxs[callno], outkey, pds.key); 11837 /* Start the call going */ 11838 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11839 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 11840 11841 return callno; 11842 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5199 of file chan_iax2.c.
References ast_log(), ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
05200 { 05201 /* Returns where in "receive time" we are. That is, how many ms 05202 since we received (or would have received) the frame with timestamp 0 */ 05203 int ms; 05204 #ifdef IAXTESTS 05205 int jit; 05206 #endif /* IAXTESTS */ 05207 /* Setup rxcore if necessary */ 05208 if (ast_tvzero(p->rxcore)) { 05209 p->rxcore = ast_tvnow(); 05210 if (option_debug && iaxdebug) 05211 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05212 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05213 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05214 #if 1 05215 if (option_debug && iaxdebug) 05216 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05217 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05218 #endif 05219 } 05220 05221 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05222 #ifdef IAXTESTS 05223 if (test_jit) { 05224 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05225 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05226 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05227 jit = -jit; 05228 ms += jit; 05229 } 05230 } 05231 if (test_late) { 05232 ms += test_late; 05233 test_late = 0; 05234 } 05235 #endif /* IAXTESTS */ 05236 return ms; 05237 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5066 of file chan_iax2.c.
References ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), 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, chan_iax2_pvt::offset, and option_debug.
Referenced by iax2_send(), and socket_process().
05067 { 05068 int ms; 05069 int voice = 0; 05070 int genuine = 0; 05071 int adjust; 05072 int rate = ast_format_rate(f->subclass) / 1000; 05073 struct timeval *delivery = NULL; 05074 05075 05076 /* What sort of frame do we have?: voice is self-explanatory 05077 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05078 non-genuine frames are CONTROL frames [ringing etc], DTMF 05079 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05080 the others need a timestamp slaved to the voice frames so that they go in sequence 05081 */ 05082 if (f) { 05083 if (f->frametype == AST_FRAME_VOICE) { 05084 voice = 1; 05085 delivery = &f->delivery; 05086 } else if (f->frametype == AST_FRAME_IAX) { 05087 genuine = 1; 05088 } else if (f->frametype == AST_FRAME_CNG) { 05089 p->notsilenttx = 0; 05090 } 05091 } 05092 if (ast_tvzero(p->offset)) { 05093 gettimeofday(&p->offset, NULL); 05094 /* Round to nearest 20ms for nice looking traces */ 05095 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05096 } 05097 /* If the timestamp is specified, just send it as is */ 05098 if (ts) 05099 return ts; 05100 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05101 if (delivery && !ast_tvzero(*delivery)) { 05102 ms = ast_tvdiff_ms(*delivery, p->offset); 05103 if (ms < 0) { 05104 ms = 0; 05105 } 05106 if (option_debug > 2 && iaxdebug) 05107 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05108 } else { 05109 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05110 if (ms < 0) 05111 ms = 0; 05112 if (voice) { 05113 /* On a voice frame, use predicted values if appropriate */ 05114 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05115 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05116 /* AN EXPLANATION: 05117 When we send voice, we usually send "calculated" timestamps worked out 05118 on the basis of the number of samples sent. When we send other frames, 05119 we usually send timestamps worked out from the real clock. 05120 The problem is that they can tend to drift out of step because the 05121 source channel's clock and our clock may not be exactly at the same rate. 05122 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05123 for this call. Moving it adjusts timestamps for non-voice frames. 05124 We make the adjustment in the style of a moving average. Each time we 05125 adjust p->offset by 10% of the difference between our clock-derived 05126 timestamp and the predicted timestamp. That's why you see "10000" 05127 below even though IAX2 timestamps are in milliseconds. 05128 The use of a moving average avoids offset moving too radically. 05129 Generally, "adjust" roams back and forth around 0, with offset hardly 05130 changing at all. But if a consistent different starts to develop it 05131 will be eliminated over the course of 10 frames (200-300msecs) 05132 */ 05133 adjust = (ms - p->nextpred); 05134 if (adjust < 0) 05135 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05136 else if (adjust > 0) 05137 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05138 05139 if (!p->nextpred) { 05140 p->nextpred = ms; /*f->samples / rate;*/ 05141 if (p->nextpred <= p->lastsent) 05142 p->nextpred = p->lastsent + 3; 05143 } 05144 ms = p->nextpred; 05145 } else { 05146 /* in this case, just use the actual 05147 * time, since we're either way off 05148 * (shouldn't happen), or we're ending a 05149 * silent period -- and seed the next 05150 * predicted time. Also, round ms to the 05151 * next multiple of frame size (so our 05152 * silent periods are multiples of 05153 * frame size too) */ 05154 05155 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05156 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05157 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05158 05159 if (f->samples >= rate) /* check to make sure we dont core dump */ 05160 { 05161 int diff = ms % (f->samples / rate); 05162 if (diff) 05163 ms += f->samples/rate - diff; 05164 } 05165 05166 p->nextpred = ms; 05167 p->notsilenttx = 1; 05168 } 05169 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05170 /* 05171 * IAX2 draft 03 says that timestamps MUST be in order. 05172 * It does not say anything about several frames having the same timestamp 05173 * When transporting video, we can have a frame that spans multiple iax packets 05174 * (so called slices), so it would make sense to use the same timestamp for all of 05175 * them 05176 * We do want to make sure that frames don't go backwards though 05177 */ 05178 if ( (unsigned int)ms < p->lastsent ) 05179 ms = p->lastsent; 05180 } else { 05181 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05182 it's a genuine frame */ 05183 if (genuine) { 05184 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05185 if (ms <= p->lastsent) 05186 ms = p->lastsent + 3; 05187 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05188 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05189 ms = p->lastsent + 3; 05190 } 05191 } 05192 } 05193 p->lastsent = ms; 05194 if (voice) 05195 p->nextpred = p->nextpred + f->samples / rate; 05196 return ms; 05197 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 5022 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().
05023 { 05024 unsigned long int mssincetx; /* unsigned to handle overflows */ 05025 long int ms, pred; 05026 05027 tpeer->trunkact = *tv; 05028 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 05029 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05030 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05031 tpeer->txtrunktime = *tv; 05032 tpeer->lastsent = 999999; 05033 } 05034 /* Update last transmit time now */ 05035 tpeer->lasttxtime = *tv; 05036 05037 /* Calculate ms offset */ 05038 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 05039 /* Predict from last value */ 05040 pred = tpeer->lastsent + sampms; 05041 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05042 ms = pred; 05043 05044 /* We never send the same timestamp twice, so fudge a little if we must */ 05045 if (ms == tpeer->lastsent) 05046 ms = tpeer->lastsent + 1; 05047 tpeer->lastsent = ms; 05048 return ms; 05049 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2270 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02271 { 02272 return abs(ast_random()); 02273 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 1826 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, calltoken_ignores, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, LOG_DEBUG, option_debug, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().
Referenced by handle_call_token().
01827 { 01828 struct addr_range *addr_range; 01829 struct iax2_peer *peer = NULL; 01830 struct iax2_user *user = NULL; 01831 /* if no username is given, check for guest accounts */ 01832 const char *find = S_OR(name, "guest"); 01833 int res = 1; /* required by default */ 01834 int optional = 0; 01835 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 01836 /* There are only two cases in which calltoken validation is not required. 01837 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 01838 * the peer definition has not set the requirecalltoken option. 01839 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 01840 */ 01841 01842 /* ----- Case 1 ----- */ 01843 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 01844 ao2_ref(addr_range, -1); 01845 optional = 1; 01846 } 01847 01848 /* ----- Case 2 ----- */ 01849 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 01850 calltoken_required = user->calltoken_required; 01851 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 01852 calltoken_required = user->calltoken_required; 01853 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 01854 calltoken_required = peer->calltoken_required; 01855 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 01856 calltoken_required = peer->calltoken_required; 01857 } 01858 01859 if (peer) { 01860 peer_unref(peer); 01861 } 01862 if (user) { 01863 user_unref(user); 01864 } 01865 if (option_debug) { 01866 ast_log(LOG_DEBUG, "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); 01867 } 01868 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 01869 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 01870 res = 0; 01871 } 01872 01873 return res; 01874 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6373 of file chan_iax2.c.
References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax2_context::context, chan_iax2_pvt::context, iax2_user::contexts, iax2_user::dbsecret, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, globalflags, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, ies, iax2_user::inkeys, iax2_user::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), secret, iax2_user::secret, user_unref(), users, ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
06374 { 06375 /* Start pessimistic */ 06376 int res = -1; 06377 int version = 2; 06378 struct iax2_user *user = NULL, *best = NULL; 06379 int bestscore = 0; 06380 int gotcapability = 0; 06381 struct ast_variable *v = NULL, *tmpvar = NULL; 06382 struct ao2_iterator i; 06383 06384 if (!iaxs[callno]) 06385 return res; 06386 if (ies->called_number) 06387 ast_string_field_set(iaxs[callno], exten, ies->called_number); 06388 if (ies->calling_number) { 06389 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 06390 ast_shrink_phone_number(ies->calling_number); 06391 } 06392 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 06393 } 06394 if (ies->calling_name) 06395 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 06396 if (ies->calling_ani) 06397 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 06398 if (ies->dnid) 06399 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 06400 if (ies->rdnis) 06401 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 06402 if (ies->called_context) 06403 ast_string_field_set(iaxs[callno], context, ies->called_context); 06404 if (ies->language) 06405 ast_string_field_set(iaxs[callno], language, ies->language); 06406 if (ies->username) 06407 ast_string_field_set(iaxs[callno], username, ies->username); 06408 if (ies->calling_ton > -1) 06409 iaxs[callno]->calling_ton = ies->calling_ton; 06410 if (ies->calling_tns > -1) 06411 iaxs[callno]->calling_tns = ies->calling_tns; 06412 if (ies->calling_pres > -1) 06413 iaxs[callno]->calling_pres = ies->calling_pres; 06414 if (ies->format) 06415 iaxs[callno]->peerformat = ies->format; 06416 if (ies->adsicpe) 06417 iaxs[callno]->peeradsicpe = ies->adsicpe; 06418 if (ies->capability) { 06419 gotcapability = 1; 06420 iaxs[callno]->peercapability = ies->capability; 06421 } 06422 if (ies->version) 06423 version = ies->version; 06424 06425 /* Use provided preferences until told otherwise for actual preferences */ 06426 if(ies->codec_prefs) { 06427 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 06428 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 06429 } 06430 06431 if (!gotcapability) 06432 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 06433 if (version > IAX_PROTO_VERSION) { 06434 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 06435 ast_inet_ntoa(sin->sin_addr), version); 06436 return res; 06437 } 06438 /* Search the userlist for a compatible entry, and fill in the rest */ 06439 i = ao2_iterator_init(users, 0); 06440 while ((user = ao2_iterator_next(&i))) { 06441 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 06442 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 06443 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 06444 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 06445 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 06446 if (!ast_strlen_zero(iaxs[callno]->username)) { 06447 /* Exact match, stop right now. */ 06448 if (best) 06449 user_unref(best); 06450 best = user; 06451 break; 06452 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 06453 /* No required authentication */ 06454 if (user->ha) { 06455 /* There was host authentication and we passed, bonus! */ 06456 if (bestscore < 4) { 06457 bestscore = 4; 06458 if (best) 06459 user_unref(best); 06460 best = user; 06461 continue; 06462 } 06463 } else { 06464 /* No host access, but no secret, either, not bad */ 06465 if (bestscore < 3) { 06466 bestscore = 3; 06467 if (best) 06468 user_unref(best); 06469 best = user; 06470 continue; 06471 } 06472 } 06473 } else { 06474 if (user->ha) { 06475 /* Authentication, but host access too, eh, it's something.. */ 06476 if (bestscore < 2) { 06477 bestscore = 2; 06478 if (best) 06479 user_unref(best); 06480 best = user; 06481 continue; 06482 } 06483 } else { 06484 /* Authentication and no host access... This is our baseline */ 06485 if (bestscore < 1) { 06486 bestscore = 1; 06487 if (best) 06488 user_unref(best); 06489 best = user; 06490 continue; 06491 } 06492 } 06493 } 06494 } 06495 user_unref(user); 06496 } 06497 ao2_iterator_destroy(&i); 06498 user = best; 06499 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 06500 user = realtime_user(iaxs[callno]->username, sin); 06501 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 06502 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 06503 user = user_unref(user); 06504 } 06505 } 06506 if (user) { 06507 /* We found our match (use the first) */ 06508 /* copy vars */ 06509 for (v = user->vars ; v ; v = v->next) { 06510 if((tmpvar = ast_variable_new(v->name, v->value))) { 06511 tmpvar->next = iaxs[callno]->vars; 06512 iaxs[callno]->vars = tmpvar; 06513 } 06514 } 06515 /* If a max AUTHREQ restriction is in place, activate it */ 06516 if (user->maxauthreq > 0) 06517 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 06518 iaxs[callno]->prefs = user->prefs; 06519 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 06520 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 06521 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 06522 iaxs[callno]->encmethods = user->encmethods; 06523 /* Store the requested username if not specified */ 06524 if (ast_strlen_zero(iaxs[callno]->username)) 06525 ast_string_field_set(iaxs[callno], username, user->name); 06526 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 06527 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 06528 iaxs[callno]->capability = user->capability; 06529 /* And use the default context */ 06530 if (ast_strlen_zero(iaxs[callno]->context)) { 06531 if (user->contexts) 06532 ast_string_field_set(iaxs[callno], context, user->contexts->context); 06533 else 06534 ast_string_field_set(iaxs[callno], context, context); 06535 } 06536 /* And any input keys */ 06537 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 06538 /* And the permitted authentication methods */ 06539 iaxs[callno]->authmethods = user->authmethods; 06540 iaxs[callno]->adsi = user->adsi; 06541 /* If the user has callerid, override the remote caller id. */ 06542 if (ast_test_flag(user, IAX_HASCALLERID)) { 06543 iaxs[callno]->calling_tns = 0; 06544 iaxs[callno]->calling_ton = 0; 06545 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 06546 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 06547 ast_string_field_set(iaxs[callno], ani, user->cid_num); 06548 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 06549 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 06550 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 06551 } /* else user is allowed to set their own CID settings */ 06552 if (!ast_strlen_zero(user->accountcode)) 06553 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 06554 if (!ast_strlen_zero(user->mohinterpret)) 06555 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 06556 if (!ast_strlen_zero(user->mohsuggest)) 06557 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 06558 if (user->amaflags) 06559 iaxs[callno]->amaflags = user->amaflags; 06560 if (!ast_strlen_zero(user->language)) 06561 ast_string_field_set(iaxs[callno], language, user->language); 06562 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 06563 /* Keep this check last */ 06564 if (!ast_strlen_zero(user->dbsecret)) { 06565 char *family, *key=NULL; 06566 char buf[80]; 06567 family = ast_strdupa(user->dbsecret); 06568 key = strchr(family, '/'); 06569 if (key) { 06570 *key = '\0'; 06571 key++; 06572 } 06573 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 06574 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 06575 else 06576 ast_string_field_set(iaxs[callno], secret, buf); 06577 } else 06578 ast_string_field_set(iaxs[callno], secret, user->secret); 06579 res = 0; 06580 user = user_unref(user); 06581 } else { 06582 /* user was not found, but we should still fake an AUTHREQ. 06583 * Set authmethods to the last known authmethod used by the system 06584 * Set a fake secret, it's not looked at, just required to attempt authentication. 06585 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 06586 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06587 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06588 iaxs[callno]->authrej = 1; 06589 if (!ast_strlen_zero(iaxs[callno]->username)) { 06590 /* only send the AUTHREQ if a username was specified. */ 06591 res = 0; 06592 } 06593 } 06594 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 06595 return res; 06596 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 8133 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
08134 { 08135 unsigned int ourver; 08136 char rsi[80]; 08137 snprintf(rsi, sizeof(rsi), "si-%s", si); 08138 if (iax_provision_version(&ourver, rsi, 1)) 08139 return 0; 08140 if (option_debug) 08141 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 08142 if (ourver != ver) 08143 iax2_provision(sin, sockfd, NULL, rsi, 1); 08144 return 0; 08145 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 10628 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
10629 { 10630 int sd; 10631 int res; 10632 10633 sd = socket(AF_INET, SOCK_DGRAM, 0); 10634 if (sd < 0) { 10635 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 10636 return -1; 10637 } 10638 10639 res = bind(sd, sa, salen); 10640 if (res < 0) { 10641 if (option_debug) 10642 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 10643 close(sd); 10644 return 1; 10645 } 10646 10647 close(sd); 10648 return 0; 10649 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7104 of file chan_iax2.c.
References ARRAY_LEN, ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
07105 { 07106 char exten[256] = ""; 07107 int status = CACHE_FLAG_UNKNOWN; 07108 int expiry = iaxdefaultdpcache; 07109 int x; 07110 int matchmore = 0; 07111 struct iax2_dpcache *dp, *prev; 07112 07113 if (ies->called_number) 07114 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07115 07116 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07117 status = CACHE_FLAG_EXISTS; 07118 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07119 status = CACHE_FLAG_CANEXIST; 07120 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07121 status = CACHE_FLAG_NONEXISTENT; 07122 07123 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 07124 /* Don't really do anything with this */ 07125 } 07126 if (ies->refresh) 07127 expiry = ies->refresh; 07128 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07129 matchmore = CACHE_FLAG_MATCHMORE; 07130 ast_mutex_lock(&dpcache_lock); 07131 prev = NULL; 07132 dp = pvt->dpentries; 07133 while(dp) { 07134 if (!strcmp(dp->exten, exten)) { 07135 /* Let them go */ 07136 if (prev) 07137 prev->peer = dp->peer; 07138 else 07139 pvt->dpentries = dp->peer; 07140 dp->peer = NULL; 07141 dp->callno = 0; 07142 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 07143 if (dp->flags & CACHE_FLAG_PENDING) { 07144 dp->flags &= ~CACHE_FLAG_PENDING; 07145 dp->flags |= status; 07146 dp->flags |= matchmore; 07147 } 07148 /* Wake up waiters */ 07149 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 07150 if (dp->waiters[x] > -1) { 07151 if (write(dp->waiters[x], "asdf", 4) < 0) { 07152 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 07153 } 07154 } 07155 } 07156 } 07157 prev = dp; 07158 dp = dp->peer; 07159 } 07160 ast_mutex_unlock(&dpcache_lock); 07161 return 0; 07162 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3323 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, peer_unref(), and peers.
03324 { 03325 int which = 0; 03326 struct iax2_peer *peer; 03327 char *res = NULL; 03328 int wordlen = strlen(word); 03329 struct ao2_iterator i; 03330 03331 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 03332 if (pos != 3) 03333 return NULL; 03334 03335 i = ao2_iterator_init(peers, 0); 03336 while ((peer = ao2_iterator_next(&i))) { 03337 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 03338 res = ast_strdup(peer->name); 03339 peer_unref(peer); 03340 break; 03341 } 03342 peer_unref(peer); 03343 } 03344 ao2_iterator_destroy(&i); 03345 03346 return res; 03347 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7164 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, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, 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, ast_iax2_queue::queue, 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().
07165 { 07166 int peercallno = 0; 07167 struct chan_iax2_pvt *pvt = iaxs[callno]; 07168 struct iax_frame *cur; 07169 jb_frame frame; 07170 07171 if (ies->callno) 07172 peercallno = ies->callno; 07173 07174 if (peercallno < 1) { 07175 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07176 return -1; 07177 } 07178 remove_by_transfercallno(pvt); 07179 /* since a transfer has taken place, the address will change. 07180 * This must be accounted for in the peercnts table. Remove 07181 * the old address and add the new one */ 07182 peercnt_remove_by_addr(&pvt->addr); 07183 peercnt_add(&pvt->transfer); 07184 /* now copy over the new address */ 07185 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 07186 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 07187 /* Reset sequence numbers */ 07188 pvt->oseqno = 0; 07189 pvt->rseqno = 0; 07190 pvt->iseqno = 0; 07191 pvt->aseqno = 0; 07192 07193 if (pvt->peercallno) { 07194 remove_by_peercallno(pvt); 07195 } 07196 pvt->peercallno = peercallno; 07197 /*this is where the transfering call swiches hash tables */ 07198 store_by_peercallno(pvt); 07199 pvt->transferring = TRANSFER_NONE; 07200 pvt->svoiceformat = -1; 07201 pvt->voiceformat = 0; 07202 pvt->svideoformat = -1; 07203 pvt->videoformat = 0; 07204 pvt->transfercallno = -1; 07205 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 07206 memset(&pvt->offset, 0, sizeof(pvt->offset)); 07207 /* reset jitterbuffer */ 07208 while(jb_getall(pvt->jb,&frame) == JB_OK) 07209 iax2_frame_free(frame.data); 07210 jb_reset(pvt->jb); 07211 pvt->lag = 0; 07212 pvt->last = 0; 07213 pvt->lastsent = 0; 07214 pvt->nextpred = 0; 07215 pvt->pingtime = DEFAULT_RETRY_TIME; 07216 AST_LIST_LOCK(&iaxq.queue); 07217 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07218 /* We must cancel any packets that would have been transmitted 07219 because now we're talking to someone new. It's okay, they 07220 were transmitted to someone that didn't care anyway. */ 07221 if (callno == cur->callno) 07222 cur->retries = -1; 07223 } 07224 AST_LIST_UNLOCK(&iaxq.queue); 07225 return 0; 07226 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1194 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().
01195 { 01196 int x; 01197 int power=-1; 01198 /* If it's 128 or smaller, just return it */ 01199 if (subclass < IAX_FLAG_SC_LOG) 01200 return subclass; 01201 /* Otherwise find its power */ 01202 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01203 if (subclass & (1 << x)) { 01204 if (power > -1) { 01205 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01206 return 0; 01207 } else 01208 power = x; 01209 } 01210 } 01211 return power | IAX_FLAG_SC_LOG; 01212 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 8147 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().
08148 { 08149 jb_info stats; 08150 jb_getinfo(pvt->jb, &stats); 08151 08152 memset(iep, 0, sizeof(*iep)); 08153 08154 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 08155 if(stats.frames_in == 0) stats.frames_in = 1; 08156 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 08157 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 08158 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 08159 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 08160 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 08161 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3947 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_gethostbyname(), 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, hp, 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.
03948 { 03949 struct ast_hostent ahp; 03950 struct hostent *hp; 03951 struct iax2_peer *peer; 03952 int res = -1; 03953 struct ast_codec_pref ourprefs; 03954 03955 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03956 cai->sockfd = defaultsockfd; 03957 cai->maxtime = 0; 03958 sin->sin_family = AF_INET; 03959 03960 if (!(peer = find_peer(peername, 1))) { 03961 cai->found = 0; 03962 03963 hp = ast_gethostbyname(peername, &ahp); 03964 if (hp) { 03965 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03966 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03967 /* use global iax prefs for unknown peer/user */ 03968 /* But move the calling channel's native codec to the top of the preference list */ 03969 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03970 if (c) 03971 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03972 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03973 return 0; 03974 } else { 03975 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03976 return -1; 03977 } 03978 } 03979 03980 cai->found = 1; 03981 03982 /* if the peer has no address (current or default), return failure */ 03983 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03984 goto return_unref; 03985 03986 /* if the peer is being monitored and is currently unreachable, return failure */ 03987 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03988 goto return_unref; 03989 03990 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03991 cai->maxtime = peer->maxms; 03992 cai->capability = peer->capability; 03993 cai->encmethods = peer->encmethods; 03994 cai->sockfd = peer->sockfd; 03995 cai->adsi = peer->adsi; 03996 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03997 /* Move the calling channel's native codec to the top of the preference list */ 03998 if (c) { 03999 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 04000 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04001 } 04002 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04003 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04004 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04005 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04006 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04007 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04008 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04009 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04010 if (ast_strlen_zero(peer->dbsecret)) { 04011 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04012 } else { 04013 char *family; 04014 char *key = NULL; 04015 04016 family = ast_strdupa(peer->dbsecret); 04017 key = strchr(family, '/'); 04018 if (key) 04019 *key++ = '\0'; 04020 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04021 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04022 goto return_unref; 04023 } 04024 } 04025 04026 if (peer->addr.sin_addr.s_addr) { 04027 sin->sin_addr = peer->addr.sin_addr; 04028 sin->sin_port = peer->addr.sin_port; 04029 } else { 04030 sin->sin_addr = peer->defaddr.sin_addr; 04031 sin->sin_port = peer->defaddr.sin_port; 04032 } 04033 04034 res = 0; 04035 04036 return_unref: 04037 peer_unref(peer); 04038 04039 return res; 04040 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2275 of file chan_iax2.c.
References ao2_alloc(), ao2_container_alloc(), ao2_ref(), callno_hash(), IAX_MAX_CALLS, and TRUNK_CALL_START.
Referenced by load_objects().
02276 { 02277 uint16_t i; 02278 02279 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02280 return -1; 02281 } 02282 02283 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02284 return -1; 02285 } 02286 02287 /* start at 2, 0 and 1 are reserved */ 02288 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02289 struct callno_entry *callno_entry; 02290 02291 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02292 return -1; 02293 } 02294 02295 callno_entry->callno = i; 02296 02297 if (i < TRUNK_CALL_START) { 02298 ao2_link(callno_pool, callno_entry); 02299 } else { 02300 ao2_link(callno_pool_trunk, callno_entry); 02301 } 02302 02303 ao2_ref(callno_entry, -1); 02304 } 02305 02306 return 0; 02307 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5407 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
05408 { 05409 int padding; 05410 unsigned char *workspace; 05411 05412 workspace = alloca(*datalen); 05413 memset(f, 0, sizeof(*f)); 05414 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05415 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05416 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05417 return -1; 05418 /* Decrypt */ 05419 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05420 05421 padding = 16 + (workspace[15] & 0x0f); 05422 if (option_debug && iaxdebug) 05423 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05424 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05425 return -1; 05426 05427 *datalen -= padding; 05428 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05429 f->frametype = fh->type; 05430 if (f->frametype == AST_FRAME_VIDEO) { 05431 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05432 } else { 05433 f->subclass = uncompress_subclass(fh->csub); 05434 } 05435 } else { 05436 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05437 if (option_debug && iaxdebug) 05438 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 05439 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05440 return -1; 05441 /* Decrypt */ 05442 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05443 padding = 16 + (workspace[15] & 0x0f); 05444 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05445 return -1; 05446 *datalen -= padding; 05447 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05448 } 05449 return 0; 05450 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5493 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(), and secret.
Referenced by socket_process().
05494 { 05495 int res=-1; 05496 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 05497 /* Search for possible keys, given secrets */ 05498 struct MD5Context md5; 05499 unsigned char digest[16]; 05500 char *tmppw, *stringp; 05501 05502 tmppw = ast_strdupa(iaxs[callno]->secret); 05503 stringp = tmppw; 05504 while ((tmppw = strsep(&stringp, ";"))) { 05505 MD5Init(&md5); 05506 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05507 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05508 MD5Final(digest, &md5); 05509 build_encryption_keys(digest, iaxs[callno]); 05510 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05511 if (!res) { 05512 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 05513 break; 05514 } 05515 } 05516 } else 05517 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05518 return res; 05519 }
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 8209 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().
08210 { 08211 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 08212 struct ast_iax2_full_hdr *fh, *cur_fh; 08213 08214 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 08215 return; 08216 08217 pkt_buf->len = from_here->buf_len; 08218 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 08219 08220 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 08221 ast_mutex_lock(&to_here->lock); 08222 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 08223 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 08224 if (fh->oseqno < cur_fh->oseqno) { 08225 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 08226 break; 08227 } 08228 } 08229 AST_LIST_TRAVERSE_SAFE_END 08230 08231 if (!cur_pkt_buf) 08232 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 08233 08234 ast_mutex_unlock(&to_here->lock); 08235 }
static void delete_users | ( | void | ) | [static] |
Definition at line 11249 of file chan_iax2.c.
References ao2_callback(), ast_dnsmgr_release(), 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, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
11250 { 11251 struct iax2_registry *reg; 11252 11253 ao2_callback(users, 0, user_delme_cb, NULL); 11254 11255 AST_LIST_LOCK(®istrations); 11256 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 11257 ast_sched_del(sched, reg->expire); 11258 if (reg->callno) { 11259 int callno = reg->callno; 11260 ast_mutex_lock(&iaxsl[callno]); 11261 if (iaxs[callno]) { 11262 iaxs[callno]->reg = NULL; 11263 iax2_destroy(callno); 11264 } 11265 ast_mutex_unlock(&iaxsl[callno]); 11266 } 11267 if (reg->dnsmgr) 11268 ast_dnsmgr_release(reg->dnsmgr); 11269 free(reg); 11270 } 11271 AST_LIST_UNLOCK(®istrations); 11272 11273 ao2_callback(peers, 0, peer_delme_cb, NULL); 11274 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2637 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
02638 { 02639 /* Close firmware */ 02640 if (cur->fwh) { 02641 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02642 } 02643 close(cur->fd); 02644 free(cur); 02645 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 7981 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, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
07982 { 07983 unsigned short dpstatus = 0; 07984 struct iax_ie_data ied1; 07985 int mm; 07986 07987 memset(&ied1, 0, sizeof(ied1)); 07988 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 07989 /* Must be started */ 07990 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 07991 dpstatus = IAX_DPSTATUS_EXISTS; 07992 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 07993 dpstatus = IAX_DPSTATUS_CANEXIST; 07994 } else { 07995 dpstatus = IAX_DPSTATUS_NONEXISTENT; 07996 } 07997 if (ast_ignore_pattern(context, callednum)) 07998 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 07999 if (mm) 08000 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08001 if (!skiplock) 08002 ast_mutex_lock(&iaxsl[callno]); 08003 if (iaxs[callno]) { 08004 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08005 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08006 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08007 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08008 } 08009 if (!skiplock) 08010 ast_mutex_unlock(&iaxsl[callno]); 08011 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8013 of file chan_iax2.c.
References dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup(), and free.
Referenced by spawn_dp_lookup().
08014 { 08015 /* Look up for dpreq */ 08016 struct dpreq_data *dpr = data; 08017 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 08018 if (dpr->callerid) 08019 free(dpr->callerid); 08020 free(dpr); 08021 return NULL; 08022 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 5452 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send(), and update_packet().
05453 { 05454 int padding; 05455 unsigned char *workspace; 05456 workspace = alloca(*datalen + 32); 05457 if (!workspace) 05458 return -1; 05459 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05460 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05461 if (option_debug && iaxdebug) 05462 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05463 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05464 padding = 16 + (padding & 0xf); 05465 memcpy(workspace, poo, padding); 05466 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05467 workspace[15] &= 0xf0; 05468 workspace[15] |= (padding & 0xf); 05469 if (option_debug && iaxdebug) 05470 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 05471 *datalen += padding; 05472 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05473 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05474 memcpy(poo, workspace + *datalen - 32, 32); 05475 } else { 05476 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05477 if (option_debug && iaxdebug) 05478 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 05479 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 05480 padding = 16 + (padding & 0xf); 05481 memcpy(workspace, poo, padding); 05482 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05483 workspace[15] &= 0xf0; 05484 workspace[15] |= (padding & 0x0f); 05485 *datalen += padding; 05486 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 05487 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 05488 memcpy(poo, workspace + *datalen - 32, 32); 05489 } 05490 return 0; 05491 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7410 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
07411 { 07412 #ifdef SCHED_MULTITHREADED 07413 if (schedule_action(__expire_registry, data)) 07414 #endif 07415 __expire_registry(data); 07416 return 0; 07417 }
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 11844 of file chan_iax2.c.
References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_frfree, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), ast_test_flag, ast_tvcmp(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
11845 { 11846 struct iax2_dpcache *dp, *prev = NULL, *next; 11847 struct timeval tv; 11848 int x; 11849 int com[2]; 11850 int timeout; 11851 int old=0; 11852 int outfd; 11853 int abort; 11854 int callno; 11855 struct ast_channel *c; 11856 struct ast_frame *f; 11857 gettimeofday(&tv, NULL); 11858 dp = dpcache; 11859 while(dp) { 11860 next = dp->next; 11861 /* Expire old caches */ 11862 if (ast_tvcmp(tv, dp->expiry) > 0) { 11863 /* It's expired, let it disappear */ 11864 if (prev) 11865 prev->next = dp->next; 11866 else 11867 dpcache = dp->next; 11868 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 11869 /* Free memory and go again */ 11870 free(dp); 11871 } else { 11872 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno); 11873 } 11874 dp = next; 11875 continue; 11876 } 11877 /* We found an entry that matches us! */ 11878 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 11879 break; 11880 prev = dp; 11881 dp = next; 11882 } 11883 if (!dp) { 11884 /* No matching entry. Create a new one. */ 11885 /* First, can we make a callno? */ 11886 callno = cache_get_callno_locked(data); 11887 if (callno < 0) { 11888 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 11889 return NULL; 11890 } 11891 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 11892 ast_mutex_unlock(&iaxsl[callno]); 11893 return NULL; 11894 } 11895 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 11896 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 11897 gettimeofday(&dp->expiry, NULL); 11898 dp->orig = dp->expiry; 11899 /* Expires in 30 mins by default */ 11900 dp->expiry.tv_sec += iaxdefaultdpcache; 11901 dp->next = dpcache; 11902 dp->flags = CACHE_FLAG_PENDING; 11903 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 11904 dp->waiters[x] = -1; 11905 dpcache = dp; 11906 dp->peer = iaxs[callno]->dpentries; 11907 iaxs[callno]->dpentries = dp; 11908 /* Send the request if we're already up */ 11909 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 11910 iax2_dprequest(dp, callno); 11911 ast_mutex_unlock(&iaxsl[callno]); 11912 } 11913 /* By here we must have a dp */ 11914 if (dp->flags & CACHE_FLAG_PENDING) { 11915 /* Okay, here it starts to get nasty. We need a pipe now to wait 11916 for a reply to come back so long as it's pending */ 11917 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 11918 /* Find an empty slot */ 11919 if (dp->waiters[x] < 0) 11920 break; 11921 } 11922 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 11923 ast_log(LOG_WARNING, "No more waiter positions available\n"); 11924 return NULL; 11925 } 11926 if (pipe(com)) { 11927 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 11928 return NULL; 11929 } 11930 dp->waiters[x] = com[1]; 11931 /* Okay, now we wait */ 11932 timeout = iaxdefaulttimeout * 1000; 11933 /* Temporarily unlock */ 11934 ast_mutex_unlock(&dpcache_lock); 11935 /* Defer any dtmf */ 11936 if (chan) 11937 old = ast_channel_defer_dtmf(chan); 11938 abort = 0; 11939 while(timeout) { 11940 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 11941 if (outfd > -1) { 11942 break; 11943 } 11944 if (c) { 11945 f = ast_read(c); 11946 if (f) 11947 ast_frfree(f); 11948 else { 11949 /* Got hung up on, abort! */ 11950 break; 11951 abort = 1; 11952 } 11953 } 11954 } 11955 if (!timeout) { 11956 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 11957 } 11958 ast_mutex_lock(&dpcache_lock); 11959 dp->waiters[x] = -1; 11960 close(com[1]); 11961 close(com[0]); 11962 if (abort) { 11963 /* Don't interpret anything, just abort. Not sure what th epoint 11964 of undeferring dtmf on a hung up channel is but hey whatever */ 11965 if (!old && chan) 11966 ast_channel_undefer_dtmf(chan); 11967 return NULL; 11968 } 11969 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 11970 /* Now to do non-independent analysis the results of our wait */ 11971 if (dp->flags & CACHE_FLAG_PENDING) { 11972 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 11973 pending. Don't let it take as long to timeout. */ 11974 dp->flags &= ~CACHE_FLAG_PENDING; 11975 dp->flags |= CACHE_FLAG_TIMEOUT; 11976 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 11977 systems without leaving it unavailable once the server comes back online */ 11978 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 11979 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 11980 if (dp->waiters[x] > -1) { 11981 if (write(dp->waiters[x], "asdf", 4) < 0) { 11982 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 11983 } 11984 } 11985 } 11986 } 11987 } 11988 /* Our caller will obtain the rest */ 11989 if (!old && chan) 11990 ast_channel_undefer_dtmf(chan); 11991 } 11992 return dp; 11993 }
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 2537 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02537 { 02538 02539 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02540 }
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 2542 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
02542 { 02543 02544 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02545 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1027 of file chan_iax2.c.
References ast_calloc, ast_cond_init, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init, ast_pthread_create, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::list, and thread.
Referenced by __schedule_action(), and socket_read().
01028 { 01029 pthread_attr_t attr; 01030 struct iax2_thread *thread = NULL; 01031 01032 /* Pop the head of the list off */ 01033 AST_LIST_LOCK(&idle_list); 01034 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01035 AST_LIST_UNLOCK(&idle_list); 01036 01037 /* If no idle thread is available from the regular list, try dynamic */ 01038 if (thread == NULL) { 01039 AST_LIST_LOCK(&dynamic_list); 01040 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01041 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 01042 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 01043 /* We need to MAKE a thread! */ 01044 if ((thread = ast_calloc(1, sizeof(*thread)))) { 01045 thread->threadnum = iaxdynamicthreadnum++; 01046 thread->type = IAX_TYPE_DYNAMIC; 01047 ast_mutex_init(&thread->lock); 01048 ast_cond_init(&thread->cond, NULL); 01049 pthread_attr_init(&attr); 01050 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01051 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 01052 free(thread); 01053 thread = NULL; 01054 } else { 01055 /* All went well and the thread is up, so increment our count */ 01056 iaxdynamicthreadcount++; 01057 01058 /* Wait for the thread to be ready before returning it to the caller */ 01059 while (!thread->ready_for_signal) 01060 usleep(1); 01061 } 01062 } 01063 } 01064 AST_LIST_UNLOCK(&dynamic_list); 01065 } 01066 01067 /* this thread is not processing a full frame (since it is idle), 01068 so ensure that the field for the full frame call number is empty */ 01069 if (thread) 01070 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01071 01072 return thread; 01073 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1272 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, peers, and realtime_peer().
01273 { 01274 struct iax2_peer *peer = NULL; 01275 struct iax2_peer tmp_peer = { 01276 .name = name, 01277 }; 01278 01279 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01280 01281 /* Now go for realtime if applicable */ 01282 if(!peer && realtime) 01283 peer = realtime_peer(name, NULL); 01284 01285 return peer; 01286 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 5239 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock, inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, tpeerlock, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
05240 { 05241 struct iax2_trunk_peer *tpeer; 05242 05243 /* Finds and locks trunk peer */ 05244 ast_mutex_lock(&tpeerlock); 05245 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 05246 /* We don't lock here because tpeer->addr *never* changes */ 05247 if (!inaddrcmp(&tpeer->addr, sin)) { 05248 ast_mutex_lock(&tpeer->lock); 05249 break; 05250 } 05251 } 05252 if (!tpeer) { 05253 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05254 ast_mutex_init(&tpeer->lock); 05255 tpeer->lastsent = 9999; 05256 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05257 tpeer->trunkact = ast_tvnow(); 05258 ast_mutex_lock(&tpeer->lock); 05259 tpeer->next = tpeers; 05260 tpeer->sockfd = fd; 05261 tpeers = tpeer; 05262 #ifdef SO_NO_CHECK 05263 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05264 #endif 05265 if (option_debug) 05266 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05267 } 05268 } 05269 ast_mutex_unlock(&tpeerlock); 05270 return tpeer; 05271 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1300 of file chan_iax2.c.
References ao2_find(), iax2_user::name, and users.
01301 { 01302 struct iax2_user tmp_user = { 01303 .name = name, 01304 }; 01305 01306 return ao2_find(users, &tmp_user, OBJ_POINTER); 01307 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5051 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
05052 { 05053 long ms; /* NOT unsigned */ 05054 if (ast_tvzero(iaxs[callno]->rxcore)) { 05055 /* Initialize rxcore time if appropriate */ 05056 gettimeofday(&iaxs[callno]->rxcore, NULL); 05057 /* Round to nearest 20ms so traces look pretty */ 05058 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05059 } 05060 /* Calculate difference between trunk and channel */ 05061 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 05062 /* Return as the sum of trunk time and the difference between trunk and real time */ 05063 return ms + ts; 05064 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 10380 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
10381 { 10382 struct iax2_context *conl; 10383 while(con) { 10384 conl = con; 10385 con = con->next; 10386 free(conl); 10387 } 10388 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1522 of file chan_iax2.c.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 12117 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, 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.
12118 { 12119 struct iax2_peer *peer; 12120 char *peername, *colname; 12121 12122 peername = ast_strdupa(data); 12123 12124 /* if our channel, return the IP address of the endpoint of current channel */ 12125 if (!strcmp(peername,"CURRENTCHANNEL")) { 12126 unsigned short callno; 12127 if (chan->tech != &iax2_tech) 12128 return -1; 12129 callno = PTR_TO_CALLNO(chan->tech_pvt); 12130 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 12131 return 0; 12132 } 12133 12134 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 12135 *colname++ = '\0'; 12136 else if ((colname = strchr(peername, '|'))) 12137 *colname++ = '\0'; 12138 else 12139 colname = "ip"; 12140 12141 if (!(peer = find_peer(peername, 1))) 12142 return -1; 12143 12144 if (!strcasecmp(colname, "ip")) { 12145 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12146 } else if (!strcasecmp(colname, "status")) { 12147 peer_status(peer, buf, len); 12148 } else if (!strcasecmp(colname, "mailbox")) { 12149 ast_copy_string(buf, peer->mailbox, len); 12150 } else if (!strcasecmp(colname, "context")) { 12151 ast_copy_string(buf, peer->context, len); 12152 } else if (!strcasecmp(colname, "expire")) { 12153 snprintf(buf, len, "%d", peer->expire); 12154 } else if (!strcasecmp(colname, "dynamic")) { 12155 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 12156 } else if (!strcasecmp(colname, "callerid_name")) { 12157 ast_copy_string(buf, peer->cid_name, len); 12158 } else if (!strcasecmp(colname, "callerid_num")) { 12159 ast_copy_string(buf, peer->cid_num, len); 12160 } else if (!strcasecmp(colname, "codecs")) { 12161 ast_getformatname_multiple(buf, len -1, peer->capability); 12162 } else if (!strncasecmp(colname, "codec[", 6)) { 12163 char *codecnum, *ptr; 12164 int index = 0, codec = 0; 12165 12166 codecnum = strchr(colname, '['); 12167 *codecnum = '\0'; 12168 codecnum++; 12169 if ((ptr = strchr(codecnum, ']'))) { 12170 *ptr = '\0'; 12171 } 12172 index = atoi(codecnum); 12173 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12174 ast_copy_string(buf, ast_getformatname(codec), len); 12175 } else { 12176 buf[0] = '\0'; 12177 } 12178 } else { 12179 buf[0] = '\0'; 12180 } 12181 12182 peer_unref(peer); 12183 12184 return 0; 12185 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 10612 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
10613 { 10614 int methods = 0; 10615 if (strstr(value, "rsa")) 10616 methods |= IAX_AUTH_RSA; 10617 if (strstr(value, "md5")) 10618 methods |= IAX_AUTH_MD5; 10619 if (strstr(value, "plaintext")) 10620 methods |= IAX_AUTH_PLAINTEXT; 10621 return methods; 10622 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1149 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01150 { 01151 int e; 01152 if (!strcasecmp(s, "aes128")) 01153 e = IAX_ENCRYPT_AES128; 01154 else if (ast_true(s)) 01155 e = IAX_ENCRYPT_AES128; 01156 else 01157 e = 0; 01158 return e; 01159 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3561 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03562 { 03563 #ifdef SCHED_MULTITHREADED 03564 if (schedule_action(__get_from_jb, data)) 03565 #endif 03566 __get_from_jb(data); 03567 return 0; 03568 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2208 of file chan_iax2.c.
References ao2_container_count(), ao2_find(), ast_log(), LOG_WARNING, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02209 { 02210 struct callno_entry *callno_entry = NULL; 02211 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02212 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02213 /* Minor optimization for the extreme case. */ 02214 return NULL; 02215 } 02216 02217 /* the callno_pool container is locked here primarily to ensure thread 02218 * safety of the total_nonval_callno_used check and increment */ 02219 ao2_lock(callno_pool); 02220 02221 /* only a certain number of nonvalidated call numbers should be allocated. 02222 * If there ever is an attack, this separates the calltoken validating 02223 * users from the non calltoken validating users. */ 02224 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02225 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02226 ao2_unlock(callno_pool); 02227 return NULL; 02228 } 02229 02230 /* unlink the object from the container, taking over ownership 02231 * of the reference the container had to the object */ 02232 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02233 02234 if (callno_entry) { 02235 callno_entry->validated = validated; 02236 if (!validated) { 02237 total_nonval_callno_used++; 02238 } 02239 } 02240 02241 ao2_unlock(callno_pool); 02242 return callno_entry; 02243 }
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 4254 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), iax_ie_data::buf, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), 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, ies, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), t, ast_iax2_full_hdr::ts, and uncompress_subclass().
Referenced by socket_process().
04256 { 04257 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04258 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04259 char buf[256] = { 0 }; 04260 time_t t = time(NULL); 04261 char hash[41]; /* 40 char sha1 hash */ 04262 int subclass = uncompress_subclass(fh->csub); 04263 04264 /* ----- Case 1 ----- */ 04265 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04266 struct iax_ie_data ied = { 04267 .buf = { 0 }, 04268 .pos = 0, 04269 }; 04270 04271 /* create the hash with their address data and our timestamp */ 04272 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04273 ast_sha1_hash(hash, buf); 04274 04275 snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04276 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf); 04277 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04278 04279 return 1; 04280 04281 /* ----- Case 2 ----- */ 04282 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04283 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04284 char *rec_ts = NULL; /* received timestamp */ 04285 unsigned int rec_time; /* received time_t */ 04286 04287 /* split the timestamp from the hash data */ 04288 rec_hash = strchr((char *) ies->calltokendata, '?'); 04289 if (rec_hash) { 04290 *rec_hash++ = '\0'; 04291 rec_ts = (char *) ies->calltokendata; 04292 } 04293 04294 /* check that we have valid data before we do any comparisons */ 04295 if (!rec_hash || !rec_ts) { 04296 goto reject; 04297 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04298 goto reject; 04299 } 04300 04301 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04302 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04303 ast_sha1_hash(hash, buf); 04304 04305 /* compare hashes and then check timestamp delay */ 04306 if (strcmp(hash, rec_hash)) { 04307 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04308 goto reject; /* received hash does not match ours, reject */ 04309 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04310 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04311 goto reject; /* too much delay, reject */ 04312 } 04313 04314 /* at this point the call token is valid, returning 0 04315 * will allow socket_process to continue as usual */ 04316 requirecalltoken_mark_auto(ies->username, subclass); 04317 return 0; 04318 04319 /* ----- Case 3 ----- */ 04320 } else { /* calltokens are not supported for this client, how do we respond? */ 04321 if (calltoken_required(sin, ies->username, subclass)) { 04322 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenignore list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest")); 04323 goto reject; 04324 } 04325 return 0; /* calltoken is not required for this addr, so permit it. */ 04326 } 04327 04328 reject: 04329 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04330 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04331 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04332 } else { 04333 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04334 } 04335 04336 return 1; 04337 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 8179 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.
08180 { 08181 struct iax2_pkt_buf *pkt_buf; 08182 08183 ast_mutex_lock(&thread->lock); 08184 08185 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 08186 ast_mutex_unlock(&thread->lock); 08187 08188 thread->buf = pkt_buf->buf; 08189 thread->buf_len = pkt_buf->len; 08190 thread->buf_size = pkt_buf->len + 1; 08191 08192 socket_process(thread); 08193 08194 thread->buf = NULL; 08195 ast_free(pkt_buf); 08196 08197 ast_mutex_lock(&thread->lock); 08198 } 08199 08200 ast_mutex_unlock(&thread->lock); 08201 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2925 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().
02926 { 02927 /* XXX Ideally we should figure out why an error occured and then abort those 02928 rather than continuing to try. Unfortunately, the published interface does 02929 not seem to work XXX */ 02930 #if 0 02931 struct sockaddr_in *sin; 02932 int res; 02933 struct msghdr m; 02934 struct sock_extended_err e; 02935 m.msg_name = NULL; 02936 m.msg_namelen = 0; 02937 m.msg_iov = NULL; 02938 m.msg_control = &e; 02939 m.msg_controllen = sizeof(e); 02940 m.msg_flags = 0; 02941 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02942 if (res < 0) 02943 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02944 else { 02945 if (m.msg_controllen) { 02946 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02947 if (sin) 02948 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02949 else 02950 ast_log(LOG_WARNING, "No address detected??\n"); 02951 } else { 02952 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02953 } 02954 } 02955 #endif 02956 return 0; 02957 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 7229 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
07230 { 07231 struct iax2_registry *reg; 07232 /* Start pessimistic */ 07233 char peer[256] = ""; 07234 char msgstatus[60]; 07235 int refresh = 60; 07236 char ourip[256] = "<Unspecified>"; 07237 struct sockaddr_in oldus; 07238 struct sockaddr_in us; 07239 int oldmsgs; 07240 07241 memset(&us, 0, sizeof(us)); 07242 if (ies->apparent_addr) 07243 bcopy(ies->apparent_addr, &us, sizeof(us)); 07244 if (ies->username) 07245 ast_copy_string(peer, ies->username, sizeof(peer)); 07246 if (ies->refresh) 07247 refresh = ies->refresh; 07248 if (ies->calling_number) { 07249 /* We don't do anything with it really, but maybe we should */ 07250 } 07251 reg = iaxs[callno]->reg; 07252 if (!reg) { 07253 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 07254 return -1; 07255 } 07256 memcpy(&oldus, ®->us, sizeof(oldus)); 07257 oldmsgs = reg->messages; 07258 if (inaddrcmp(®->addr, sin)) { 07259 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07260 return -1; 07261 } 07262 memcpy(®->us, &us, sizeof(reg->us)); 07263 if (ies->msgcount >= 0) 07264 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 07265 /* always refresh the registration at the interval requested by the server 07266 we are registering to 07267 */ 07268 reg->refresh = refresh; 07269 AST_SCHED_DEL(sched, reg->expire); 07270 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07271 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 07272 if (option_verbose > 2) { 07273 if (reg->messages > 255) 07274 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 07275 else if (reg->messages > 1) 07276 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 07277 else if (reg->messages > 0) 07278 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 07279 else 07280 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 07281 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07282 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 07283 } 07284 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 07285 } 07286 reg->regstate = REG_STATE_REGISTERED; 07287 return 0; 07288 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2346 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().
02347 { 02348 if (frametype != AST_FRAME_IAX) { 02349 return 0; 02350 } 02351 switch (subclass) { 02352 case IAX_COMMAND_NEW: 02353 case IAX_COMMAND_REGREQ: 02354 case IAX_COMMAND_FWDOWNL: 02355 case IAX_COMMAND_REGREL: 02356 return 1; 02357 case IAX_COMMAND_POKE: 02358 if (!inbound) { 02359 return 1; 02360 } 02361 break; 02362 } 02363 return 0; 02364 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4856 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04857 { 04858 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04859 if (option_debug) 04860 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 04861 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 04862 }
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 4701 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_verbose(), chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, tv, unlock_both(), and VERBOSE_PREFIX_3.
04702 { 04703 struct ast_channel *cs[3]; 04704 struct ast_channel *who, *other; 04705 int to = -1; 04706 int res = -1; 04707 int transferstarted=0; 04708 struct ast_frame *f; 04709 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 04710 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 04711 struct timeval waittimer = {0, 0}, tv; 04712 04713 lock_both(callno0, callno1); 04714 if (!iaxs[callno0] || !iaxs[callno1]) { 04715 unlock_both(callno0, callno1); 04716 return AST_BRIDGE_FAILED; 04717 } 04718 /* Put them in native bridge mode */ 04719 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 04720 iaxs[callno0]->bridgecallno = callno1; 04721 iaxs[callno1]->bridgecallno = callno0; 04722 } 04723 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 04724 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 04725 transferstarted = 1; 04726 } 04727 unlock_both(callno0, callno1); 04728 04729 /* If not, try to bridge until we can execute a transfer, if we can */ 04730 cs[0] = c0; 04731 cs[1] = c1; 04732 for (/* ever */;;) { 04733 /* Check in case we got masqueraded into */ 04734 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 04735 if (option_verbose > 2) 04736 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 04737 /* Remove from native mode */ 04738 if (c0->tech == &iax2_tech) { 04739 ast_mutex_lock(&iaxsl[callno0]); 04740 iaxs[callno0]->bridgecallno = 0; 04741 ast_mutex_unlock(&iaxsl[callno0]); 04742 } 04743 if (c1->tech == &iax2_tech) { 04744 ast_mutex_lock(&iaxsl[callno1]); 04745 iaxs[callno1]->bridgecallno = 0; 04746 ast_mutex_unlock(&iaxsl[callno1]); 04747 } 04748 return AST_BRIDGE_FAILED_NOWARN; 04749 } 04750 if (c0->nativeformats != c1->nativeformats) { 04751 if (option_verbose > 2) { 04752 char buf0[255]; 04753 char buf1[255]; 04754 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 04755 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 04756 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 04757 } 04758 /* Remove from native mode */ 04759 lock_both(callno0, callno1); 04760 if (iaxs[callno0]) 04761 iaxs[callno0]->bridgecallno = 0; 04762 if (iaxs[callno1]) 04763 iaxs[callno1]->bridgecallno = 0; 04764 unlock_both(callno0, callno1); 04765 return AST_BRIDGE_FAILED_NOWARN; 04766 } 04767 /* check if transfered and if we really want native bridging */ 04768 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 04769 /* Try the transfer */ 04770 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 04771 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 04772 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 04773 transferstarted = 1; 04774 } 04775 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 04776 /* Call has been transferred. We're no longer involved */ 04777 gettimeofday(&tv, NULL); 04778 if (ast_tvzero(waittimer)) { 04779 waittimer = tv; 04780 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 04781 c0->_softhangup |= AST_SOFTHANGUP_DEV; 04782 c1->_softhangup |= AST_SOFTHANGUP_DEV; 04783 *fo = NULL; 04784 *rc = c0; 04785 res = AST_BRIDGE_COMPLETE; 04786 break; 04787 } 04788 } 04789 to = 1000; 04790 who = ast_waitfor_n(cs, 2, &to); 04791 if (timeoutms > -1) { 04792 timeoutms -= (1000 - to); 04793 if (timeoutms < 0) 04794 timeoutms = 0; 04795 } 04796 if (!who) { 04797 if (!timeoutms) { 04798 res = AST_BRIDGE_RETRY; 04799 break; 04800 } 04801 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 04802 res = AST_BRIDGE_FAILED; 04803 break; 04804 } 04805 continue; 04806 } 04807 f = ast_read(who); 04808 if (!f) { 04809 *fo = NULL; 04810 *rc = who; 04811 res = AST_BRIDGE_COMPLETE; 04812 break; 04813 } 04814 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 04815 *fo = f; 04816 *rc = who; 04817 res = AST_BRIDGE_COMPLETE; 04818 break; 04819 } 04820 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 04821 if ((f->frametype == AST_FRAME_VOICE) || 04822 (f->frametype == AST_FRAME_TEXT) || 04823 (f->frametype == AST_FRAME_VIDEO) || 04824 (f->frametype == AST_FRAME_IMAGE) || 04825 (f->frametype == AST_FRAME_DTMF) || 04826 (f->frametype == AST_FRAME_CONTROL)) { 04827 /* monitored dtmf take out of the bridge. 04828 * check if we monitor the specific source. 04829 */ 04830 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 04831 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 04832 *rc = who; 04833 *fo = f; 04834 res = AST_BRIDGE_COMPLETE; 04835 /* Remove from native mode */ 04836 break; 04837 } 04838 /* everything else goes to the other side */ 04839 ast_write(other, f); 04840 } 04841 ast_frfree(f); 04842 /* Swap who gets priority */ 04843 cs[2] = cs[0]; 04844 cs[0] = cs[1]; 04845 cs[1] = cs[2]; 04846 } 04847 lock_both(callno0, callno1); 04848 if(iaxs[callno0]) 04849 iaxs[callno0]->bridgecallno = 0; 04850 if(iaxs[callno1]) 04851 iaxs[callno1]->bridgecallno = 0; 04852 unlock_both(callno0, callno1); 04853 return res; 04854 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4397 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_copy_string(), AST_FRAME_IAX, 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, 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, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_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_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, and chan_iax2_pvt::username.
04398 { 04399 struct sockaddr_in sin; 04400 char *l=NULL, *n=NULL, *tmpstr; 04401 struct iax_ie_data ied; 04402 char *defaultrdest = "s"; 04403 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04404 struct parsed_dial_string pds; 04405 struct create_addr_info cai; 04406 04407 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04408 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04409 return -1; 04410 } 04411 04412 memset(&cai, 0, sizeof(cai)); 04413 cai.encmethods = iax2_encryption; 04414 04415 memset(&pds, 0, sizeof(pds)); 04416 tmpstr = ast_strdupa(dest); 04417 parse_dial_string(tmpstr, &pds); 04418 04419 if (ast_strlen_zero(pds.peer)) { 04420 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04421 return -1; 04422 } 04423 04424 if (!pds.exten) { 04425 pds.exten = defaultrdest; 04426 } 04427 04428 if (create_addr(pds.peer, c, &sin, &cai)) { 04429 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04430 return -1; 04431 } 04432 04433 if (!pds.username && !ast_strlen_zero(cai.username)) 04434 pds.username = cai.username; 04435 if (!pds.password && !ast_strlen_zero(cai.secret)) 04436 pds.password = cai.secret; 04437 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04438 pds.key = cai.outkey; 04439 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04440 pds.context = cai.peercontext; 04441 04442 /* Keep track of the context for outgoing calls too */ 04443 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04444 04445 if (pds.port) 04446 sin.sin_port = htons(atoi(pds.port)); 04447 04448 l = c->cid.cid_num; 04449 n = c->cid.cid_name; 04450 04451 /* Now build request */ 04452 memset(&ied, 0, sizeof(ied)); 04453 04454 /* On new call, first IE MUST be IAX version of caller */ 04455 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04456 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04457 if (pds.options && strchr(pds.options, 'a')) { 04458 /* Request auto answer */ 04459 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04460 } 04461 04462 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04463 04464 if (l) { 04465 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04466 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04467 } else { 04468 if (n) 04469 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04470 else 04471 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04472 } 04473 04474 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04475 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04476 04477 if (n) 04478 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04479 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04480 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04481 04482 if (!ast_strlen_zero(c->language)) 04483 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04484 if (!ast_strlen_zero(c->cid.cid_dnid)) 04485 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04486 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04487 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04488 04489 if (pds.context) 04490 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04491 04492 if (pds.username) 04493 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04494 04495 if (cai.encmethods) 04496 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04497 04498 ast_mutex_lock(&iaxsl[callno]); 04499 04500 if (!ast_strlen_zero(c->context)) 04501 ast_string_field_set(iaxs[callno], context, c->context); 04502 04503 if (pds.username) 04504 ast_string_field_set(iaxs[callno], username, pds.username); 04505 04506 iaxs[callno]->encmethods = cai.encmethods; 04507 04508 iaxs[callno]->adsi = cai.adsi; 04509 04510 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04511 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04512 04513 if (pds.key) 04514 ast_string_field_set(iaxs[callno], outkey, pds.key); 04515 if (pds.password) 04516 ast_string_field_set(iaxs[callno], secret, pds.password); 04517 04518 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04519 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04520 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04521 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04522 04523 if (iaxs[callno]->maxtime) { 04524 /* Initialize pingtime and auto-congest time */ 04525 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04526 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04527 } else if (autokill) { 04528 iaxs[callno]->pingtime = autokill / 2; 04529 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04530 } 04531 04532 /* send the command using the appropriate socket for this peer */ 04533 iaxs[callno]->sockfd = cai.sockfd; 04534 04535 /* Transmit the string in a "NEW" request */ 04536 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04537 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04538 04539 ast_mutex_unlock(&iaxsl[callno]); 04540 ast_setstate(c, AST_STATE_RINGING); 04541 04542 return 0; 04543 }
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 12019 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, CACHE_FLAG_CANEXIST, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
12020 { 12021 int res = 0; 12022 struct iax2_dpcache *dp; 12023 #if 0 12024 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12025 #endif 12026 if ((priority != 1) && (priority != 2)) 12027 return 0; 12028 ast_mutex_lock(&dpcache_lock); 12029 dp = find_cache(chan, data, context, exten, priority); 12030 if (dp) { 12031 if (dp->flags & CACHE_FLAG_CANEXIST) 12032 res= 1; 12033 } 12034 ast_mutex_unlock(&dpcache_lock); 12035 if (!dp) { 12036 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12037 } 12038 return res; 12039 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4064 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
04065 { 04066 time_t t; 04067 struct tm tm; 04068 unsigned int tmp; 04069 time(&t); 04070 if (!ast_strlen_zero(tz)) 04071 ast_localtime(&t, &tm, tz); 04072 else 04073 ast_localtime(&t, &tm, NULL); 04074 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04075 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04076 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04077 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04078 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04079 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04080 return tmp; 04081 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1441 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_queue_hangup(), AST_SCHED_DEL_SPINLOCK, DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), sched, 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().
01442 { 01443 struct chan_iax2_pvt *pvt; 01444 struct ast_channel *owner; 01445 01446 retry: 01447 pvt = iaxs[callno]; 01448 01449 owner = pvt ? pvt->owner : NULL; 01450 01451 if (owner) { 01452 if (ast_mutex_trylock(&owner->lock)) { 01453 if (option_debug > 2) 01454 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01455 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01456 goto retry; 01457 } 01458 } 01459 01460 /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we 01461 * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee 01462 * the pvt stays around, a ref count is added to it. */ 01463 if (!owner && pvt) { 01464 ao2_ref(pvt, +1); 01465 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01466 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01467 ao2_ref(pvt, -1); 01468 if (iaxs[callno]) { 01469 iaxs[callno] = NULL; 01470 } else { 01471 pvt = NULL; 01472 } 01473 } 01474 01475 if (pvt) { 01476 if (!owner) { 01477 pvt->owner = NULL; 01478 } else { 01479 /* If there's an owner, prod it to give up */ 01480 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01481 * because we already hold the owner channel lock. */ 01482 ast_queue_hangup(owner); 01483 } 01484 01485 if (pvt->peercallno) { 01486 remove_by_peercallno(pvt); 01487 } 01488 01489 if (pvt->transfercallno) { 01490 remove_by_transfercallno(pvt); 01491 } 01492 01493 if (!owner) { 01494 ao2_ref(pvt, -1); 01495 pvt = NULL; 01496 } 01497 } 01498 01499 if (owner) { 01500 ast_mutex_unlock(&owner->lock); 01501 } 01502 01503 if (callno & 0x4000) { 01504 update_max_trunk(); 01505 } 01506 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1352 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, iax2_user::name, chan_iax2_pvt::pingid, sched, user_unref(), chan_iax2_pvt::username, and users.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01353 { 01354 /* Decrement AUTHREQ count if needed */ 01355 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01356 struct iax2_user *user; 01357 struct iax2_user tmp_user = { 01358 .name = pvt->username, 01359 }; 01360 01361 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01362 if (user) { 01363 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01364 user = user_unref(user); 01365 } 01366 01367 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01368 } 01369 01370 /* No more pings or lagrq's */ 01371 AST_SCHED_DEL(sched, pvt->pingid); 01372 AST_SCHED_DEL(sched, pvt->lagid); 01373 AST_SCHED_DEL(sched, pvt->autoid); 01374 AST_SCHED_DEL(sched, pvt->authid); 01375 AST_SCHED_DEL(sched, pvt->initid); 01376 AST_SCHED_DEL(sched, pvt->jbid); 01377 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 12210 of file chan_iax2.c.
References iax2_peer::addr, 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, option_debug, parse_dial_string(), and peer_unref().
12211 { 12212 struct parsed_dial_string pds; 12213 char *tmp = ast_strdupa(data); 12214 struct iax2_peer *p; 12215 int res = AST_DEVICE_INVALID; 12216 12217 memset(&pds, 0, sizeof(pds)); 12218 parse_dial_string(tmp, &pds); 12219 12220 if (ast_strlen_zero(pds.peer)) { 12221 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12222 return res; 12223 } 12224 12225 if (option_debug > 2) 12226 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 12227 12228 /* SLD: FIXME: second call to find_peer during registration */ 12229 if (!(p = find_peer(pds.peer, 1))) 12230 return res; 12231 12232 res = AST_DEVICE_UNAVAILABLE; 12233 if (option_debug > 2) 12234 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 12235 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 12236 12237 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 12238 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 12239 /* Peer is registered, or have default IP address 12240 and a valid registration */ 12241 if (p->historicms == 0 || p->historicms <= p->maxms) 12242 /* let the core figure out whether it is in use or not */ 12243 res = AST_DEVICE_UNKNOWN; 12244 } 12245 12246 peer_unref(p); 12247 12248 return res; 12249 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 3680 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03681 { 03682 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 03683 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 3685 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03686 { 03687 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 03688 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6221 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06222 { 06223 if (argc < 2 || argc > 3) 06224 return RESULT_SHOWUSAGE; 06225 iaxdebug = 1; 06226 ast_cli(fd, "IAX2 Debugging Enabled\n"); 06227 return RESULT_SUCCESS; 06228 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6239 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06240 { 06241 if (argc < 3 || argc > 4) 06242 return RESULT_SHOWUSAGE; 06243 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 06244 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 06245 return RESULT_SUCCESS; 06246 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 10092 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, 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().
10093 { 10094 struct iax_ie_data ied; 10095 if (option_debug && iaxdebug) 10096 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 10097 10098 if (reg->dnsmgr && 10099 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 10100 /* Maybe the IP has changed, force DNS refresh */ 10101 ast_dnsmgr_refresh(reg->dnsmgr); 10102 } 10103 10104 /* 10105 * if IP has Changed, free allocated call to create a new one with new IP 10106 * call has the pointer to IP and must be updated to the new one 10107 */ 10108 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 10109 int callno = reg->callno; 10110 ast_mutex_lock(&iaxsl[callno]); 10111 iax2_destroy(callno); 10112 ast_mutex_unlock(&iaxsl[callno]); 10113 reg->callno = 0; 10114 } 10115 if (!reg->addr.sin_addr.s_addr) { 10116 if (option_debug && iaxdebug) 10117 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 10118 /* Setup the next registration attempt */ 10119 AST_SCHED_DEL(sched, reg->expire); 10120 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10121 return -1; 10122 } 10123 10124 if (!reg->callno) { 10125 if (option_debug) 10126 ast_log(LOG_DEBUG, "Allocate call number\n"); 10127 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 10128 if (reg->callno < 1) { 10129 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 10130 return -1; 10131 } else if (option_debug) 10132 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 10133 iaxs[reg->callno]->reg = reg; 10134 ast_mutex_unlock(&iaxsl[reg->callno]); 10135 } 10136 /* Schedule the next registration attempt */ 10137 AST_SCHED_DEL(sched, reg->expire); 10138 /* Setup the next registration a little early */ 10139 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10140 /* Send the request */ 10141 memset(&ied, 0, sizeof(ied)); 10142 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 10143 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 10144 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 10145 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 10146 reg->regstate = REG_STATE_REGSENT; 10147 return 0; 10148 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7065 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
07066 { 07067 #ifdef SCHED_MULTITHREADED 07068 if (schedule_action(__iax2_do_register_s, data)) 07069 #endif 07070 __iax2_do_register_s(data); 07071 return 0; 07072 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6230 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06231 { 06232 if (argc < 3 || argc > 4) 06233 return RESULT_SHOWUSAGE; 06234 iaxtrunkdebug = 1; 06235 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 06236 return RESULT_SUCCESS; 06237 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 7790 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
07791 { 07792 struct iax_ie_data ied; 07793 /* Auto-hangup with 30 seconds of inactivity */ 07794 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 07795 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 07796 memset(&ied, 0, sizeof(ied)); 07797 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 07798 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 07799 dp->flags |= CACHE_FLAG_TRANSMITTED; 07800 }
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 12065 of file chan_iax2.c.
References ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
12066 { 12067 char odata[256]; 12068 char req[256]; 12069 char *ncontext; 12070 struct iax2_dpcache *dp; 12071 struct ast_app *dial; 12072 #if 0 12073 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); 12074 #endif 12075 if (priority == 2) { 12076 /* Indicate status, can be overridden in dialplan */ 12077 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 12078 if (dialstatus) { 12079 dial = pbx_findapp(dialstatus); 12080 if (dial) 12081 pbx_exec(chan, dial, ""); 12082 } 12083 return -1; 12084 } else if (priority != 1) 12085 return -1; 12086 ast_mutex_lock(&dpcache_lock); 12087 dp = find_cache(chan, data, context, exten, priority); 12088 if (dp) { 12089 if (dp->flags & CACHE_FLAG_EXISTS) { 12090 ast_copy_string(odata, data, sizeof(odata)); 12091 ncontext = strchr(odata, '/'); 12092 if (ncontext) { 12093 *ncontext = '\0'; 12094 ncontext++; 12095 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 12096 } else { 12097 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 12098 } 12099 if (option_verbose > 2) 12100 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 12101 } else { 12102 ast_mutex_unlock(&dpcache_lock); 12103 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 12104 return -1; 12105 } 12106 } 12107 ast_mutex_unlock(&dpcache_lock); 12108 dial = pbx_findapp("Dial"); 12109 if (dial) { 12110 return pbx_exec(chan, dial, req); 12111 } else { 12112 ast_log(LOG_WARNING, "No dial application registered\n"); 12113 } 12114 return -1; 12115 }
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 11996 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
11997 { 11998 struct iax2_dpcache *dp; 11999 int res = 0; 12000 #if 0 12001 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12002 #endif 12003 if ((priority != 1) && (priority != 2)) 12004 return 0; 12005 ast_mutex_lock(&dpcache_lock); 12006 dp = find_cache(chan, data, context, exten, priority); 12007 if (dp) { 12008 if (dp->flags & CACHE_FLAG_EXISTS) 12009 res= 1; 12010 } 12011 ast_mutex_unlock(&dpcache_lock); 12012 if (!dp) { 12013 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12014 } 12015 return res; 12016 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3707 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
03708 { 03709 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 03710 ast_mutex_lock(&iaxsl[callno]); 03711 if (iaxs[callno]) 03712 iaxs[callno]->owner = newchan; 03713 else 03714 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 03715 ast_mutex_unlock(&iaxsl[callno]); 03716 return 0; 03717 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1435 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().
01436 { 01437 AST_SCHED_DEL(sched, fr->retrans); 01438 iax_frame_free(fr); 01439 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1321 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().
01322 { 01323 struct iax2_peer *peer = NULL; 01324 int res = 0; 01325 struct ao2_iterator i; 01326 01327 i = ao2_iterator_init(peers, 0); 01328 while ((peer = ao2_iterator_next(&i))) { 01329 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01330 (peer->addr.sin_port == sin.sin_port)) { 01331 ast_copy_string(host, peer->name, len); 01332 peer_unref(peer); 01333 res = 1; 01334 break; 01335 } 01336 peer_unref(peer); 01337 } 01338 ao2_iterator_destroy(&i); 01339 01340 if (!peer) { 01341 peer = realtime_peer(NULL, &sin); 01342 if (peer) { 01343 ast_copy_string(host, peer->name, len); 01344 peer_unref(peer); 01345 res = 1; 01346 } 01347 } 01348 01349 return res; 01350 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 4923 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().
04924 { 04925 struct iax2_peer *peer; 04926 int res = 0; 04927 struct ao2_iterator i; 04928 04929 i = ao2_iterator_init(peers, 0); 04930 while ((peer = ao2_iterator_next(&i))) { 04931 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 04932 (peer->addr.sin_port == sin.sin_port)) { 04933 res = ast_test_flag(peer, IAX_TRUNK); 04934 peer_unref(peer); 04935 break; 04936 } 04937 peer_unref(peer); 04938 } 04939 ao2_iterator_destroy(&i); 04940 04941 return res; 04942 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4545 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_verbose(), CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), iax2_sched_add(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_WARNING, ast_channel::name, option_debug, option_verbose, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
04546 { 04547 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04548 struct iax_ie_data ied; 04549 int alreadygone; 04550 memset(&ied, 0, sizeof(ied)); 04551 ast_mutex_lock(&iaxsl[callno]); 04552 if (callno && iaxs[callno]) { 04553 if (option_debug) 04554 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 04555 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04556 /* Send the hangup unless we have had a transmission error or are already gone */ 04557 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04558 if (!iaxs[callno]->error && !alreadygone) { 04559 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04560 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04561 } 04562 if (!iaxs[callno]) { 04563 ast_mutex_unlock(&iaxsl[callno]); 04564 return 0; 04565 } 04566 } 04567 /* Explicitly predestroy it */ 04568 iax2_predestroy(callno); 04569 /* If we were already gone to begin with, destroy us now */ 04570 if (iaxs[callno] && alreadygone) { 04571 if (option_debug) 04572 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 04573 iax2_destroy(callno); 04574 } else if (iaxs[callno]) { 04575 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 04576 } 04577 } else if (c->tech_pvt) { 04578 /* If this call no longer exists, but the channel still 04579 * references it we need to set the channel's tech_pvt to null 04580 * to avoid ast_channel_free() trying to free it. 04581 */ 04582 c->tech_pvt = NULL; 04583 } 04584 ast_mutex_unlock(&iaxsl[callno]); 04585 if (option_verbose > 2) 04586 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 04587 return 0; 04588 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 4864 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, chan_iax2_pvt::mohinterpret, option_debug, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
04865 { 04866 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04867 struct chan_iax2_pvt *pvt; 04868 int res = 0; 04869 04870 if (option_debug && iaxdebug) 04871 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 04872 04873 ast_mutex_lock(&iaxsl[callno]); 04874 pvt = iaxs[callno]; 04875 04876 if (wait_for_peercallno(pvt)) { 04877 res = -1; 04878 goto done; 04879 } 04880 04881 switch (condition) { 04882 case AST_CONTROL_HOLD: 04883 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04884 ast_moh_start(c, data, pvt->mohinterpret); 04885 goto done; 04886 } 04887 break; 04888 case AST_CONTROL_UNHOLD: 04889 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04890 ast_moh_stop(c); 04891 goto done; 04892 } 04893 } 04894 04895 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 04896 04897 done: 04898 ast_mutex_unlock(&iaxsl[callno]); 04899 04900 return res; 04901 }
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 12042 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, CACHE_FLAG_MATCHMORE, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
12043 { 12044 int res = 0; 12045 struct iax2_dpcache *dp; 12046 #if 0 12047 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12048 #endif 12049 if ((priority != 1) && (priority != 2)) 12050 return 0; 12051 ast_mutex_lock(&dpcache_lock); 12052 dp = find_cache(chan, data, context, exten, priority); 12053 if (dp) { 12054 if (dp->flags & CACHE_FLAG_MATCHMORE) 12055 res= 1; 12056 } 12057 ast_mutex_unlock(&dpcache_lock); 12058 if (!dp) { 12059 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12060 } 12061 return res; 12062 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6248 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06249 { 06250 if (argc < 3 || argc > 4) 06251 return RESULT_SHOWUSAGE; 06252 iaxdebug = 0; 06253 ast_cli(fd, "IAX2 Debugging Disabled\n"); 06254 return RESULT_SUCCESS; 06255 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6266 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06267 { 06268 if (argc < 4 || argc > 5) 06269 return RESULT_SHOWUSAGE; 06270 jb_setoutput(jb_error_output, jb_warning_output, NULL); 06271 jb_debug_output("\n"); 06272 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 06273 return RESULT_SUCCESS; 06274 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6257 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06258 { 06259 if (argc < 4 || argc > 5) 06260 return RESULT_SHOWUSAGE; 06261 iaxtrunkdebug = 0; 06262 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 06263 return RESULT_SUCCESS; 06264 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10292 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
10293 { 10294 struct iax2_peer *peer = (struct iax2_peer *)data; 10295 peer->pokeexpire = -1; 10296 #ifdef SCHED_MULTITHREADED 10297 if (schedule_action(__iax2_poke_noanswer, data)) 10298 #endif 10299 __iax2_poke_noanswer(data); 10300 peer_unref(peer); 10301 return 0; 10302 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 10313 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, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
10314 { 10315 int callno; 10316 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 10317 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 10318 immediately after clearing things out */ 10319 peer->lastms = 0; 10320 peer->historicms = 0; 10321 peer->pokeexpire = -1; 10322 peer->callno = 0; 10323 return 0; 10324 } 10325 10326 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 10327 if ((callno = peer->callno) > 0) { 10328 ast_log(LOG_NOTICE, "Still have a callno...\n"); 10329 ast_mutex_lock(&iaxsl[callno]); 10330 iax2_destroy(callno); 10331 ast_mutex_unlock(&iaxsl[callno]); 10332 } 10333 if (heldcall) 10334 ast_mutex_unlock(&iaxsl[heldcall]); 10335 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 10336 if (heldcall) 10337 ast_mutex_lock(&iaxsl[heldcall]); 10338 if (peer->callno < 1) { 10339 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 10340 return -1; 10341 } 10342 10343 /* Speed up retransmission times for this qualify call */ 10344 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 10345 iaxs[peer->callno]->peerpoke = peer; 10346 10347 /* Remove any pending pokeexpire task */ 10348 if (peer->pokeexpire > -1) { 10349 if (!ast_sched_del(sched, peer->pokeexpire)) { 10350 peer->pokeexpire = -1; 10351 peer_unref(peer); 10352 } 10353 } 10354 10355 /* Queue up a new task to handle no reply */ 10356 /* If the host is already unreachable then use the unreachable interval instead */ 10357 if (peer->lastms < 0) { 10358 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 10359 } else 10360 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 10361 10362 if (peer->pokeexpire == -1) 10363 peer_unref(peer); 10364 10365 /* And send the poke */ 10366 ast_mutex_lock(&iaxsl[callno]); 10367 if (iaxs[callno]) { 10368 struct iax_ie_data ied = { 10369 .buf = { 0 }, 10370 .pos = 0, 10371 }; 10372 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 10373 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 10374 } 10375 ast_mutex_unlock(&iaxsl[callno]); 10376 10377 return 0; 10378 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10304 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
10305 { 10306 struct iax2_peer *peer = obj; 10307 10308 iax2_poke_peer(peer, 0); 10309 10310 return 0; 10311 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7830 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
07831 { 07832 struct iax2_peer *peer = (struct iax2_peer *)data; 07833 peer->pokeexpire = -1; 07834 #ifdef SCHED_MULTITHREADED 07835 if (schedule_action(__iax2_poke_peer_s, data)) 07836 #endif 07837 __iax2_poke_peer_s(data); 07838 return 0; 07839 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3009 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().
03010 { 03011 struct ast_channel *c; 03012 struct chan_iax2_pvt *pvt = iaxs[callno]; 03013 03014 if (!pvt) 03015 return -1; 03016 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 03017 iax2_destroy_helper(pvt); 03018 ast_set_flag(pvt, IAX_ALREADYGONE); 03019 } 03020 c = pvt->owner; 03021 if (c) { 03022 c->tech_pvt = NULL; 03023 iax2_queue_hangup(callno); 03024 pvt->owner = NULL; 03025 ast_module_unref(ast_module_info->self); 03026 } 03027 return 0; 03028 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 9967 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_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
09968 { 09969 struct iax2_thread *thread = data; 09970 struct timeval tv; 09971 struct timespec ts; 09972 int put_into_idle = 0; 09973 09974 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 09975 pthread_cleanup_push(iax2_process_thread_cleanup, data); 09976 for(;;) { 09977 /* Wait for something to signal us to be awake */ 09978 ast_mutex_lock(&thread->lock); 09979 09980 /* Flag that we're ready to accept signals */ 09981 thread->ready_for_signal = 1; 09982 09983 /* Put into idle list if applicable */ 09984 if (put_into_idle) 09985 insert_idle_thread(thread); 09986 09987 if (thread->type == IAX_TYPE_DYNAMIC) { 09988 struct iax2_thread *t = NULL; 09989 /* Wait to be signalled or time out */ 09990 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 09991 ts.tv_sec = tv.tv_sec; 09992 ts.tv_nsec = tv.tv_usec * 1000; 09993 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 09994 /* This thread was never put back into the available dynamic 09995 * thread list, so just go away. */ 09996 if (!put_into_idle) { 09997 ast_mutex_unlock(&thread->lock); 09998 break; 09999 } 10000 AST_LIST_LOCK(&dynamic_list); 10001 /* Account for the case where this thread is acquired *right* after a timeout */ 10002 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 10003 iaxdynamicthreadcount--; 10004 AST_LIST_UNLOCK(&dynamic_list); 10005 if (t) { 10006 /* This dynamic thread timed out waiting for a task and was 10007 * not acquired immediately after the timeout, 10008 * so it's time to go away. */ 10009 ast_mutex_unlock(&thread->lock); 10010 break; 10011 } 10012 /* Someone grabbed our thread *right* after we timed out. 10013 * Wait for them to set us up with something to do and signal 10014 * us to continue. */ 10015 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 10016 ts.tv_sec = tv.tv_sec; 10017 ts.tv_nsec = tv.tv_usec * 1000; 10018 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 10019 { 10020 ast_mutex_unlock(&thread->lock); 10021 break; 10022 } 10023 } 10024 } else { 10025 ast_cond_wait(&thread->cond, &thread->lock); 10026 } 10027 10028 /* Go back into our respective list */ 10029 put_into_idle = 1; 10030 10031 ast_mutex_unlock(&thread->lock); 10032 10033 if (thread->iostate == IAX_IOSTATE_IDLE) 10034 continue; 10035 10036 /* Add ourselves to the active list now */ 10037 AST_LIST_LOCK(&active_list); 10038 AST_LIST_INSERT_HEAD(&active_list, thread, list); 10039 AST_LIST_UNLOCK(&active_list); 10040 10041 /* See what we need to do */ 10042 switch(thread->iostate) { 10043 case IAX_IOSTATE_READY: 10044 thread->actions++; 10045 thread->iostate = IAX_IOSTATE_PROCESSING; 10046 socket_process(thread); 10047 handle_deferred_full_frames(thread); 10048 break; 10049 case IAX_IOSTATE_SCHEDREADY: 10050 thread->actions++; 10051 thread->iostate = IAX_IOSTATE_PROCESSING; 10052 #ifdef SCHED_MULTITHREADED 10053 thread->schedfunc(thread->scheddata); 10054 #endif 10055 break; 10056 } 10057 time(&thread->checktime); 10058 thread->iostate = IAX_IOSTATE_IDLE; 10059 #ifdef DEBUG_SCHED_MULTITHREAD 10060 thread->curfunc[0]='\0'; 10061 #endif 10062 10063 /* Now... remove ourselves from the active list, and return to the idle list */ 10064 AST_LIST_LOCK(&active_list); 10065 AST_LIST_REMOVE(&active_list, thread, list); 10066 AST_LIST_UNLOCK(&active_list); 10067 10068 /* Make sure another frame didn't sneak in there after we thought we were done. */ 10069 handle_deferred_full_frames(thread); 10070 } 10071 10072 /*!\note For some reason, idle threads are exiting without being removed 10073 * from an idle list, which is causing memory corruption. Forcibly remove 10074 * it from the list, if it's there. 10075 */ 10076 AST_LIST_LOCK(&idle_list); 10077 AST_LIST_REMOVE(&idle_list, thread, list); 10078 AST_LIST_UNLOCK(&idle_list); 10079 10080 AST_LIST_LOCK(&dynamic_list); 10081 AST_LIST_REMOVE(&dynamic_list, thread, list); 10082 AST_LIST_UNLOCK(&dynamic_list); 10083 10084 /* I am exiting here on my own volition, I need to clean up my own data structures 10085 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 10086 */ 10087 pthread_cleanup_pop(1); 10088 10089 return NULL; 10090 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 9958 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy, ast_mutex_destroy, free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
09959 { 09960 struct iax2_thread *thread = data; 09961 ast_mutex_destroy(&thread->lock); 09962 ast_cond_destroy(&thread->cond); 09963 free(thread); 09964 ast_atomic_dec_and_test(&iaxactivethreadcount); 09965 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10247 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
10248 { 10249 int force = 0; 10250 int res; 10251 if (argc < 4) 10252 return RESULT_SHOWUSAGE; 10253 if ((argc > 4)) { 10254 if (!strcasecmp(argv[4], "forced")) 10255 force = 1; 10256 else 10257 return RESULT_SHOWUSAGE; 10258 } 10259 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 10260 if (res < 0) 10261 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 10262 else if (res < 1) 10263 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 10264 else 10265 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 10266 return RESULT_SUCCESS; 10267 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10150 of file chan_iax2.c.
References iax_prov_complete_template().
10151 { 10152 if (pos != 3) 10153 return NULL; 10154 return iax_prov_complete_template(line, word, pos, state); 10155 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 10157 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_unlock, AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
10158 { 10159 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 10160 is found for template */ 10161 struct iax_ie_data provdata; 10162 struct iax_ie_data ied; 10163 unsigned int sig; 10164 struct sockaddr_in sin; 10165 int callno; 10166 struct create_addr_info cai; 10167 10168 memset(&cai, 0, sizeof(cai)); 10169 10170 if (option_debug) 10171 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 10172 10173 if (iax_provision_build(&provdata, &sig, template, force)) { 10174 if (option_debug) 10175 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 10176 return 0; 10177 } 10178 10179 if (end) { 10180 memcpy(&sin, end, sizeof(sin)); 10181 cai.sockfd = sockfd; 10182 } else if (create_addr(dest, NULL, &sin, &cai)) 10183 return -1; 10184 10185 /* Build the rest of the message */ 10186 memset(&ied, 0, sizeof(ied)); 10187 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 10188 10189 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10190 if (!callno) 10191 return -1; 10192 10193 if (iaxs[callno]) { 10194 /* Schedule autodestruct in case they don't ever give us anything back */ 10195 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 10196 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 10197 ast_set_flag(iaxs[callno], IAX_PROVISION); 10198 /* Got a call number now, so go ahead and send the provisioning information */ 10199 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 10200 } 10201 ast_mutex_unlock(&iaxsl[callno]); 10202 10203 return 1; 10204 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3147 of file chan_iax2.c.
References ao2_unlink(), ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), prune_peers(), prune_users(), RESULT_SHOWUSAGE, RESULT_SUCCESS, user_unref(), and users.
03148 { 03149 struct iax2_peer *peer = NULL; 03150 struct iax2_user *user = NULL; 03151 03152 if (argc != 4) 03153 return RESULT_SHOWUSAGE; 03154 if (!strcmp(argv[3],"all")) { 03155 prune_users(); 03156 prune_peers(); 03157 ast_cli(fd, "OK cache is flushed.\n"); 03158 return RESULT_SUCCESS; 03159 } 03160 peer = find_peer(argv[3], 0); 03161 user = find_user(argv[3]); 03162 if (peer || user) { 03163 if (peer) { 03164 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03165 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03166 expire_registry(peer_ref(peer)); 03167 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]); 03168 } else { 03169 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]); 03170 } 03171 peer_unref(peer); 03172 } 03173 if (user) { 03174 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03175 ast_set_flag(user, IAX_RTAUTOCLEAR); 03176 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]); 03177 } else { 03178 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]); 03179 } 03180 ao2_unlink(users,user); 03181 user_unref(user); 03182 } 03183 } else { 03184 ast_cli(fd, "%s was not found in the cache.\n", argv[3]); 03185 } 03186 03187 return RESULT_SUCCESS; 03188 }
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 2619 of file chan_iax2.c.
References ast_mutex_trylock, ast_mutex_unlock, ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
02621 { 02622 for (;;) { 02623 if (iaxs[callno] && iaxs[callno]->owner) { 02624 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02625 /* Avoid deadlock by pausing and trying again */ 02626 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02627 } else { 02628 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02629 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02630 break; 02631 } 02632 } else 02633 break; 02634 } 02635 return 0; 02636 }
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 2557 of file chan_iax2.c.
References ast_mutex_trylock, ast_mutex_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02558 { 02559 for (;;) { 02560 if (iaxs[callno] && iaxs[callno]->owner) { 02561 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02562 /* Avoid deadlock by pausing and trying again */ 02563 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02564 } else { 02565 ast_queue_frame(iaxs[callno]->owner, f); 02566 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02567 break; 02568 } 02569 } else 02570 break; 02571 } 02572 return 0; 02573 }
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 2588 of file chan_iax2.c.
References ast_mutex_trylock, ast_mutex_unlock, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02589 { 02590 for (;;) { 02591 if (iaxs[callno] && iaxs[callno]->owner) { 02592 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02593 /* Avoid deadlock by pausing and trying again */ 02594 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02595 } else { 02596 ast_queue_hangup(iaxs[callno]->owner); 02597 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02598 break; 02599 } 02600 } else 02601 break; 02602 } 02603 return 0; 02604 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4654 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
04655 { 04656 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 04657 return NULL; 04658 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 7290 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::entry, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, and secret.
Referenced by set_config().
07291 { 07292 struct iax2_registry *reg; 07293 char copy[256]; 07294 char *username, *hostname, *secret; 07295 char *porta; 07296 char *stringp=NULL; 07297 07298 if (!value) 07299 return -1; 07300 ast_copy_string(copy, value, sizeof(copy)); 07301 stringp=copy; 07302 username = strsep(&stringp, "@"); 07303 hostname = strsep(&stringp, "@"); 07304 if (!hostname) { 07305 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 07306 return -1; 07307 } 07308 stringp=username; 07309 username = strsep(&stringp, ":"); 07310 secret = strsep(&stringp, ":"); 07311 stringp=hostname; 07312 hostname = strsep(&stringp, ":"); 07313 porta = strsep(&stringp, ":"); 07314 07315 if (porta && !atoi(porta)) { 07316 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 07317 return -1; 07318 } 07319 if (!(reg = ast_calloc(1, sizeof(*reg)))) 07320 return -1; 07321 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 07322 free(reg); 07323 return -1; 07324 } 07325 ast_copy_string(reg->username, username, sizeof(reg->username)); 07326 if (secret) 07327 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 07328 reg->expire = -1; 07329 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 07330 reg->addr.sin_family = AF_INET; 07331 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 07332 AST_LIST_LOCK(®istrations); 07333 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 07334 AST_LIST_UNLOCK(®istrations); 07335 07336 return 0; 07337 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11760 of file chan_iax2.c.
References reload_config().
11761 { 11762 return reload_config(); 11763 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 10390 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, iaxsl, 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.
10391 { 10392 int callno; 10393 int res; 10394 int fmt, native; 10395 struct sockaddr_in sin; 10396 struct ast_channel *c; 10397 struct parsed_dial_string pds; 10398 struct create_addr_info cai; 10399 char *tmpstr; 10400 10401 memset(&pds, 0, sizeof(pds)); 10402 tmpstr = ast_strdupa(data); 10403 parse_dial_string(tmpstr, &pds); 10404 10405 if (ast_strlen_zero(pds.peer)) { 10406 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10407 return NULL; 10408 } 10409 10410 memset(&cai, 0, sizeof(cai)); 10411 cai.capability = iax2_capability; 10412 10413 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10414 10415 /* Populate our address from the given */ 10416 if (create_addr(pds.peer, NULL, &sin, &cai)) { 10417 *cause = AST_CAUSE_UNREGISTERED; 10418 return NULL; 10419 } 10420 10421 if (pds.port) 10422 sin.sin_port = htons(atoi(pds.port)); 10423 10424 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10425 if (callno < 1) { 10426 ast_log(LOG_WARNING, "Unable to create call\n"); 10427 *cause = AST_CAUSE_CONGESTION; 10428 return NULL; 10429 } 10430 10431 /* If this is a trunk, update it now */ 10432 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10433 if (ast_test_flag(&cai, IAX_TRUNK)) { 10434 int new_callno; 10435 if ((new_callno = make_trunk(callno, 1)) != -1) 10436 callno = new_callno; 10437 } 10438 iaxs[callno]->maxtime = cai.maxtime; 10439 if (cai.found) 10440 ast_string_field_set(iaxs[callno], host, pds.peer); 10441 10442 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 10443 10444 ast_mutex_unlock(&iaxsl[callno]); 10445 10446 if (c) { 10447 /* Choose a format we can live with */ 10448 if (c->nativeformats & format) 10449 c->nativeformats &= format; 10450 else { 10451 native = c->nativeformats; 10452 fmt = format; 10453 res = ast_translator_best_choice(&fmt, &native); 10454 if (res < 0) { 10455 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 10456 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 10457 ast_hangup(c); 10458 return NULL; 10459 } 10460 c->nativeformats = native; 10461 } 10462 c->readformat = ast_best_codec(c->nativeformats); 10463 c->writeformat = c->readformat; 10464 } 10465 10466 return c; 10467 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1104 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), and sched_lock.
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_hangup(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), sched_delay_remove(), socket_process(), update_jbsched(), and update_registry().
01105 { 01106 int res; 01107 01108 ast_mutex_lock(&sched_lock); 01109 res = ast_sched_add(con, when, callback, data); 01110 ast_cond_signal(&sched_cond); 01111 ast_mutex_unlock(&sched_lock); 01112 01113 return res; 01114 }
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 5521 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::ecx, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, 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().
05522 { 05523 /* Queue a packet for delivery on a given private structure. Use "ts" for 05524 timestamp, or calculate if ts is 0. Send immediately without retransmission 05525 or delayed, with retransmission */ 05526 struct ast_iax2_full_hdr *fh; 05527 struct ast_iax2_mini_hdr *mh; 05528 struct ast_iax2_video_hdr *vh; 05529 struct { 05530 struct iax_frame fr2; 05531 unsigned char buffer[4096]; 05532 } frb; 05533 struct iax_frame *fr; 05534 int res; 05535 int sendmini=0; 05536 unsigned int lastsent; 05537 unsigned int fts; 05538 05539 frb.fr2.afdatalen = sizeof(frb.buffer); 05540 05541 if (!pvt) { 05542 ast_log(LOG_WARNING, "No private structure for packet?\n"); 05543 return -1; 05544 } 05545 05546 lastsent = pvt->lastsent; 05547 05548 /* Calculate actual timestamp */ 05549 fts = calc_timestamp(pvt, ts, f); 05550 05551 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 05552 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 05553 * increment the "predicted timestamps" for voice, if we're predecting */ 05554 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 05555 return 0; 05556 05557 05558 if ((ast_test_flag(pvt, IAX_TRUNK) || 05559 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 05560 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 05561 /* High two bytes are the same on timestamp, or sending on a trunk */ && 05562 (f->frametype == AST_FRAME_VOICE) 05563 /* is a voice frame */ && 05564 (f->subclass == pvt->svoiceformat) 05565 /* is the same type */ ) { 05566 /* Force immediate rather than delayed transmission */ 05567 now = 1; 05568 /* Mark that mini-style frame is appropriate */ 05569 sendmini = 1; 05570 } 05571 if ( f->frametype == AST_FRAME_VIDEO ) { 05572 /* 05573 * If the lower 15 bits of the timestamp roll over, or if 05574 * the video format changed then send a full frame. 05575 * Otherwise send a mini video frame 05576 */ 05577 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 05578 ((f->subclass & ~0x1) == pvt->svideoformat) 05579 ) { 05580 now = 1; 05581 sendmini = 1; 05582 } else { 05583 now = 0; 05584 sendmini = 0; 05585 } 05586 pvt->lastvsent = fts; 05587 } 05588 if (f->frametype == AST_FRAME_IAX) { 05589 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 05590 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 05591 if (!pvt->first_iax_message) { 05592 pvt->first_iax_message = pvt->last_iax_message; 05593 } 05594 } 05595 /* Allocate an iax_frame */ 05596 if (now) { 05597 fr = &frb.fr2; 05598 } else 05599 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)); 05600 if (!fr) { 05601 ast_log(LOG_WARNING, "Out of memory\n"); 05602 return -1; 05603 } 05604 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 05605 iax_frame_wrap(fr, f); 05606 05607 fr->ts = fts; 05608 fr->callno = pvt->callno; 05609 fr->transfer = transfer; 05610 fr->final = final; 05611 fr->encmethods = 0; 05612 if (!sendmini) { 05613 /* We need a full frame */ 05614 if (seqno > -1) 05615 fr->oseqno = seqno; 05616 else 05617 fr->oseqno = pvt->oseqno++; 05618 fr->iseqno = pvt->iseqno; 05619 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 05620 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 05621 fh->ts = htonl(fr->ts); 05622 fh->oseqno = fr->oseqno; 05623 if (transfer) { 05624 fh->iseqno = 0; 05625 } else 05626 fh->iseqno = fr->iseqno; 05627 /* Keep track of the last thing we've acknowledged */ 05628 if (!transfer) 05629 pvt->aseqno = fr->iseqno; 05630 fh->type = fr->af.frametype & 0xFF; 05631 if (fr->af.frametype == AST_FRAME_VIDEO) 05632 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 05633 else 05634 fh->csub = compress_subclass(fr->af.subclass); 05635 if (transfer) { 05636 fr->dcallno = pvt->transfercallno; 05637 } else 05638 fr->dcallno = pvt->peercallno; 05639 fh->dcallno = htons(fr->dcallno); 05640 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 05641 fr->data = fh; 05642 fr->retries = 0; 05643 /* Retry after 2x the ping time has passed */ 05644 fr->retrytime = pvt->pingtime * 2; 05645 if (fr->retrytime < MIN_RETRY_TIME) 05646 fr->retrytime = MIN_RETRY_TIME; 05647 if (fr->retrytime > MAX_RETRY_TIME) 05648 fr->retrytime = MAX_RETRY_TIME; 05649 /* Acks' don't get retried */ 05650 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 05651 fr->retries = -1; 05652 else if (f->frametype == AST_FRAME_VOICE) 05653 pvt->svoiceformat = f->subclass; 05654 else if (f->frametype == AST_FRAME_VIDEO) 05655 pvt->svideoformat = f->subclass & ~0x1; 05656 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05657 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05658 if (iaxdebug) { 05659 if (fr->transfer) 05660 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05661 else 05662 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05663 } 05664 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 05665 fr->encmethods = pvt->encmethods; 05666 fr->ecx = pvt->ecx; 05667 fr->mydcx = pvt->mydcx; 05668 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 05669 } else 05670 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05671 } 05672 05673 if (now) { 05674 res = send_packet(fr); 05675 } else 05676 res = iax2_transmit(fr); 05677 } else { 05678 if (ast_test_flag(pvt, IAX_TRUNK)) { 05679 iax2_trunk_queue(pvt, fr); 05680 res = 0; 05681 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 05682 /* Video frame have no sequence number */ 05683 fr->oseqno = -1; 05684 fr->iseqno = -1; 05685 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 05686 vh->zeros = 0; 05687 vh->callno = htons(0x8000 | fr->callno); 05688 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 05689 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 05690 fr->data = vh; 05691 fr->retries = -1; 05692 res = send_packet(fr); 05693 } else { 05694 /* Mini-frames have no sequence number */ 05695 fr->oseqno = -1; 05696 fr->iseqno = -1; 05697 /* Mini frame will do */ 05698 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 05699 mh->callno = htons(fr->callno); 05700 mh->ts = htons(fr->ts & 0xFFFF); 05701 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 05702 fr->data = mh; 05703 fr->retries = -1; 05704 if (pvt->transferring == TRANSFER_MEDIAPASS) 05705 fr->transfer = 1; 05706 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05707 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05708 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 05709 } else 05710 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05711 } 05712 res = send_packet(fr); 05713 } 05714 } 05715 return res; 05716 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3702 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03703 { 03704 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 03705 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 3697 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
03698 { 03699 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 03700 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 3690 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03691 { 03692 03693 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 03694 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 03695 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4612 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
04613 { 04614 struct ast_option_header *h; 04615 int res; 04616 04617 switch (option) { 04618 case AST_OPTION_TXGAIN: 04619 case AST_OPTION_RXGAIN: 04620 /* these two cannot be sent, because they require a result */ 04621 errno = ENOSYS; 04622 return -1; 04623 default: 04624 { 04625 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04626 struct chan_iax2_pvt *pvt; 04627 04628 ast_mutex_lock(&iaxsl[callno]); 04629 pvt = iaxs[callno]; 04630 04631 if (wait_for_peercallno(pvt)) { 04632 ast_mutex_unlock(&iaxsl[callno]); 04633 return -1; 04634 } 04635 04636 ast_mutex_unlock(&iaxsl[callno]); 04637 04638 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 04639 return -1; 04640 } 04641 04642 h->flag = AST_OPTION_FLAG_REQUEST; 04643 h->option = htons(option); 04644 memcpy(h->data, data, datalen); 04645 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 04646 AST_CONTROL_OPTION, 0, (unsigned char *) h, 04647 datalen + sizeof(*h), -1); 04648 free(h); 04649 return res; 04650 } 04651 } 04652 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3375 of file chan_iax2.c.
References ast_cli(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, dpcache_lock, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
03376 { 03377 struct iax2_dpcache *dp; 03378 char tmp[1024], *pc; 03379 int s; 03380 int x,y; 03381 struct timeval tv; 03382 gettimeofday(&tv, NULL); 03383 ast_mutex_lock(&dpcache_lock); 03384 dp = dpcache; 03385 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03386 while(dp) { 03387 s = dp->expiry.tv_sec - tv.tv_sec; 03388 tmp[0] = '\0'; 03389 if (dp->flags & CACHE_FLAG_EXISTS) 03390 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03391 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03392 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03393 if (dp->flags & CACHE_FLAG_CANEXIST) 03394 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03395 if (dp->flags & CACHE_FLAG_PENDING) 03396 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03397 if (dp->flags & CACHE_FLAG_TIMEOUT) 03398 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03399 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03400 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03401 if (dp->flags & CACHE_FLAG_MATCHMORE) 03402 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03403 if (dp->flags & CACHE_FLAG_UNKNOWN) 03404 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03405 /* Trim trailing pipe */ 03406 if (!ast_strlen_zero(tmp)) 03407 tmp[strlen(tmp) - 1] = '\0'; 03408 else 03409 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03410 y=0; 03411 pc = strchr(dp->peercontext, '@'); 03412 if (!pc) 03413 pc = dp->peercontext; 03414 else 03415 pc++; 03416 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 03417 if (dp->waiters[x] > -1) 03418 y++; 03419 if (s > 0) 03420 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03421 else 03422 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03423 dp = dp->next; 03424 } 03425 ast_mutex_unlock(&dpcache_lock); 03426 return RESULT_SUCCESS; 03427 }
static int iax2_show_callnumber_usage | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2176 of file chan_iax2.c.
References peercnt::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_ref(), ast_cli(), ast_inet_ntoa(), peercnt::cur, peercnt::limit, peercnts, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02177 { 02178 struct ao2_iterator i; 02179 struct peercnt *peercnt; 02180 struct sockaddr_in sin; 02181 int found = 0; 02182 02183 if (argc < 4 || argc > 5) 02184 return RESULT_SHOWUSAGE; 02185 02186 ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02187 i = ao2_iterator_init(peercnts, 0); 02188 while ((peercnt = ao2_iterator_next(&i))) { 02189 sin.sin_addr.s_addr = peercnt->addr; 02190 if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02191 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02192 found = 1; 02193 break; 02194 } else { 02195 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02196 } 02197 ao2_ref(peercnt, -1); 02198 } 02199 ao2_iterator_destroy(&i); 02200 if (argc == 4) { 02201 ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02202 } else if (argc == 5 && !found) { 02203 ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] ); 02204 } 02205 return RESULT_SUCCESS; 02206 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6062 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
06063 { 06064 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 06065 #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" 06066 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 06067 int x; 06068 int numchans = 0; 06069 int usedchans = 0; 06070 char first_message[10] = { 0, }; 06071 char last_message[10] = { 0, }; 06072 06073 if (argc != 3) 06074 return RESULT_SHOWUSAGE; 06075 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06076 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06077 ast_mutex_lock(&iaxsl[x]); 06078 if (iaxs[x]) { 06079 int lag, jitter, localdelay; 06080 jb_info jbinfo; 06081 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06082 jb_getinfo(iaxs[x]->jb, &jbinfo); 06083 jitter = jbinfo.jitter; 06084 localdelay = jbinfo.current - jbinfo.min; 06085 } else { 06086 jitter = -1; 06087 localdelay = 0; 06088 } 06089 06090 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06091 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06092 lag = iaxs[x]->remote_rr.delay; 06093 ast_cli(fd, FORMAT, 06094 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06095 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06096 S_OR(iaxs[x]->username, "(None)"), 06097 iaxs[x]->callno, iaxs[x]->peercallno, 06098 iaxs[x]->oseqno, iaxs[x]->iseqno, 06099 lag, 06100 jitter, 06101 localdelay, 06102 ast_getformatname(iaxs[x]->voiceformat), 06103 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06104 first_message, 06105 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06106 last_message); 06107 numchans++; 06108 if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */ 06109 usedchans++; 06110 } 06111 } 06112 ast_mutex_unlock(&iaxsl[x]); 06113 } 06114 ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 06115 ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 06116 return RESULT_SUCCESS; 06117 #undef FORMAT 06118 #undef FORMAT2 06119 #undef FORMATB 06120 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5973 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, FORMAT, FORMAT2, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
05974 { 05975 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 05976 #if !defined(__FreeBSD__) 05977 #define FORMAT "%-15.15s %-15d %-15d\n" 05978 #else /* __FreeBSD__ */ 05979 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 05980 #endif /* __FreeBSD__ */ 05981 struct iax_firmware *cur; 05982 if ((argc != 3) && (argc != 4)) 05983 return RESULT_SHOWUSAGE; 05984 ast_mutex_lock(&waresl.lock); 05985 05986 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 05987 for (cur = waresl.wares;cur;cur = cur->next) { 05988 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 05989 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 05990 (int)ntohl(cur->fwh->datalen)); 05991 } 05992 ast_mutex_unlock(&waresl.lock); 05993 return RESULT_SUCCESS; 05994 #undef FORMAT 05995 #undef FORMAT2 05996 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6209 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06210 { 06211 int numchans = 0; 06212 if (argc != 3) 06213 return RESULT_SHOWUSAGE; 06214 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06215 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06216 numchans = ast_cli_netstats(NULL, fd, 1); 06217 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06218 return RESULT_SUCCESS; 06219 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 3259 of file chan_iax2.c.
References iax2_peer::addr, 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, iax2_peer::context, iax2_peer::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mailbox, iax2_peer::maxcallno, iax2_peer::name, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.
03260 { 03261 char status[30]; 03262 char cbuf[256]; 03263 struct iax2_peer *peer; 03264 char codec_buf[512]; 03265 int x = 0, codec = 0, load_realtime = 0; 03266 03267 if (argc < 4) 03268 return RESULT_SHOWUSAGE; 03269 03270 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 03271 03272 peer = find_peer(argv[3], load_realtime); 03273 if (peer) { 03274 ast_cli(fd,"\n\n"); 03275 ast_cli(fd, " * Name : %s\n", peer->name); 03276 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 03277 ast_cli(fd, " Context : %s\n", peer->context); 03278 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 03279 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 03280 ast_cli(fd, " Callnum limit: %d\n", peer->maxcallno); 03281 ast_cli(fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03282 03283 03284 ast_cli(fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03285 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03286 ast_cli(fd, " Expire : %d\n", peer->expire); 03287 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 03288 ast_cli(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)); 03289 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03290 ast_cli(fd, " Username : %s\n", peer->username); 03291 ast_cli(fd, " Codecs : "); 03292 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03293 ast_cli(fd, "%s\n", codec_buf); 03294 03295 ast_cli(fd, " Codec Order : ("); 03296 for(x = 0; x < 32 ; x++) { 03297 codec = ast_codec_pref_index(&peer->prefs,x); 03298 if(!codec) 03299 break; 03300 ast_cli(fd, "%s", ast_getformatname(codec)); 03301 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03302 ast_cli(fd, "|"); 03303 } 03304 03305 if (!x) 03306 ast_cli(fd, "none"); 03307 ast_cli(fd, ")\n"); 03308 03309 ast_cli(fd, " Status : "); 03310 peer_status(peer, status, sizeof(status)); 03311 ast_cli(fd, "%s\n",status); 03312 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03313 ast_cli(fd,"\n"); 03314 peer_unref(peer); 03315 } else { 03316 ast_cli(fd,"Peer %s not found.\n", argv[3]); 03317 ast_cli(fd,"\n"); 03318 } 03319 03320 return RESULT_SUCCESS; 03321 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5962 of file chan_iax2.c.
References __iax2_show_peers().
05963 { 05964 return __iax2_show_peers(0, fd, NULL, argc, argv); 05965 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6034 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, iax2_registry::entry, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
06035 { 06036 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 06037 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 06038 struct iax2_registry *reg = NULL; 06039 06040 char host[80]; 06041 char perceived[80]; 06042 if (argc != 3) 06043 return RESULT_SHOWUSAGE; 06044 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 06045 AST_LIST_LOCK(®istrations); 06046 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06047 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06048 if (reg->us.sin_addr.s_addr) 06049 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06050 else 06051 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06052 ast_cli(fd, FORMAT, host, 06053 (reg->dnsmgr) ? "Y" : "N", 06054 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 06055 } 06056 AST_LIST_UNLOCK(®istrations); 06057 return RESULT_SUCCESS; 06058 #undef FORMAT 06059 #undef FORMAT2 06060 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3349 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::list, ast_iax2_queue::queue, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
03350 { 03351 struct iax_frame *cur; 03352 int cnt = 0, dead=0, final=0; 03353 03354 if (argc != 3) 03355 return RESULT_SHOWUSAGE; 03356 03357 AST_LIST_LOCK(&iaxq.queue); 03358 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 03359 if (cur->retries < 0) 03360 dead++; 03361 if (cur->final) 03362 final++; 03363 cnt++; 03364 } 03365 AST_LIST_UNLOCK(&iaxq.queue); 03366 03367 ast_cli(fd, " IAX Statistics\n"); 03368 ast_cli(fd, "---------------------\n"); 03369 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03370 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03371 03372 return RESULT_SUCCESS; 03373 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5903 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.
05904 { 05905 struct iax2_thread *thread = NULL; 05906 time_t t; 05907 int threadcount = 0, dynamiccount = 0; 05908 char type; 05909 05910 if (argc != 3) 05911 return RESULT_SHOWUSAGE; 05912 05913 ast_cli(fd, "IAX2 Thread Information\n"); 05914 time(&t); 05915 ast_cli(fd, "Idle Threads:\n"); 05916 AST_LIST_LOCK(&idle_list); 05917 AST_LIST_TRAVERSE(&idle_list, thread, list) { 05918 #ifdef DEBUG_SCHED_MULTITHREAD 05919 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05920 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05921 #else 05922 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05923 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05924 #endif 05925 threadcount++; 05926 } 05927 AST_LIST_UNLOCK(&idle_list); 05928 ast_cli(fd, "Active Threads:\n"); 05929 AST_LIST_LOCK(&active_list); 05930 AST_LIST_TRAVERSE(&active_list, thread, list) { 05931 if (thread->type == IAX_TYPE_DYNAMIC) 05932 type = 'D'; 05933 else 05934 type = 'P'; 05935 #ifdef DEBUG_SCHED_MULTITHREAD 05936 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 05937 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05938 #else 05939 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 05940 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05941 #endif 05942 threadcount++; 05943 } 05944 AST_LIST_UNLOCK(&active_list); 05945 ast_cli(fd, "Dynamic Threads:\n"); 05946 AST_LIST_LOCK(&dynamic_list); 05947 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 05948 #ifdef DEBUG_SCHED_MULTITHREAD 05949 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05950 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05951 #else 05952 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05953 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05954 #endif 05955 dynamiccount++; 05956 } 05957 AST_LIST_UNLOCK(&dynamic_list); 05958 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 05959 return RESULT_SUCCESS; 05960 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5718 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, user_unref(), and users.
05719 { 05720 regex_t regexbuf; 05721 int havepattern = 0; 05722 05723 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 05724 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 05725 05726 struct iax2_user *user = NULL; 05727 char auth[90]; 05728 char *pstr = ""; 05729 struct ao2_iterator i; 05730 05731 switch (argc) { 05732 case 5: 05733 if (!strcasecmp(argv[3], "like")) { 05734 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05735 return RESULT_SHOWUSAGE; 05736 havepattern = 1; 05737 } else 05738 return RESULT_SHOWUSAGE; 05739 case 3: 05740 break; 05741 default: 05742 return RESULT_SHOWUSAGE; 05743 } 05744 05745 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 05746 i = ao2_iterator_init(users, 0); 05747 for (user = ao2_iterator_next(&i); user; 05748 user_unref(user), user = ao2_iterator_next(&i)) { 05749 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 05750 continue; 05751 05752 if (!ast_strlen_zero(user->secret)) { 05753 ast_copy_string(auth,user->secret,sizeof(auth)); 05754 } else if (!ast_strlen_zero(user->inkeys)) { 05755 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 05756 } else 05757 ast_copy_string(auth, "-no secret-", sizeof(auth)); 05758 05759 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 05760 pstr = "REQ Only"; 05761 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 05762 pstr = "Disabled"; 05763 else 05764 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 05765 05766 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 05767 user->contexts ? user->contexts->context : context, 05768 user->ha ? "Yes" : "No", pstr); 05769 } 05770 ao2_iterator_destroy(&i); 05771 05772 if (havepattern) 05773 regfree(®exbuf); 05774 05775 return RESULT_SUCCESS; 05776 #undef FORMAT 05777 #undef FORMAT2 05778 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 4660 of file chan_iax2.c.
References AST_FRAME_IAX, ast_random(), 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, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
04661 { 04662 int res; 04663 struct iax_ie_data ied0; 04664 struct iax_ie_data ied1; 04665 unsigned int transferid = (unsigned int)ast_random(); 04666 memset(&ied0, 0, sizeof(ied0)); 04667 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 04668 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 04669 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 04670 04671 memset(&ied1, 0, sizeof(ied1)); 04672 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 04673 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 04674 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 04675 04676 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 04677 if (res) 04678 return -1; 04679 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 04680 if (res) 04681 return -1; 04682 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04683 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04684 return 0; 04685 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3190 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03191 { 03192 if (argc != 4) 03193 return RESULT_SHOWUSAGE; 03194 03195 test_losspct = atoi(argv[3]); 03196 03197 return RESULT_SUCCESS; 03198 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 4903 of file chan_iax2.c.
References ast_copy_string(), AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04904 { 04905 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04906 struct iax_ie_data ied; 04907 char tmp[256], *context; 04908 ast_copy_string(tmp, dest, sizeof(tmp)); 04909 context = strchr(tmp, '@'); 04910 if (context) { 04911 *context = '\0'; 04912 context++; 04913 } 04914 memset(&ied, 0, sizeof(ied)); 04915 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 04916 if (context) 04917 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 04918 if (option_debug) 04919 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 04920 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 04921 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3661 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_iax2_queue::count, iaxq, ast_iax2_queue::queue, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
03662 { 03663 /* Lock the queue and place this packet at the end */ 03664 /* By setting this to 0, the network thread will send it for us, and 03665 queue retransmission if necessary */ 03666 fr->sentyet = 0; 03667 AST_LIST_LOCK(&iaxq.queue); 03668 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 03669 iaxq.count++; 03670 AST_LIST_UNLOCK(&iaxq.queue); 03671 /* Wake up the network and scheduler thread */ 03672 if (netthreadid != AST_PTHREADT_NULL) 03673 pthread_kill(netthreadid, SIGURG); 03674 signal_condition(&sched_lock, &sched_cond); 03675 return 0; 03676 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 7885 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
07886 { 07887 /* Drop when trunk is about 5 seconds idle */ 07888 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 07889 return 1; 07890 return 0; 07891 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 5273 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag, 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, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, 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().
05274 { 05275 struct ast_frame *f; 05276 struct iax2_trunk_peer *tpeer; 05277 void *tmp, *ptr; 05278 struct ast_iax2_meta_trunk_entry *met; 05279 struct ast_iax2_meta_trunk_mini *mtm; 05280 05281 f = &fr->af; 05282 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05283 if (tpeer) { 05284 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05285 /* Need to reallocate space */ 05286 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 05287 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05288 ast_mutex_unlock(&tpeer->lock); 05289 return -1; 05290 } 05291 05292 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05293 tpeer->trunkdata = tmp; 05294 if (option_debug) 05295 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 05296 } else { 05297 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)); 05298 ast_mutex_unlock(&tpeer->lock); 05299 return -1; 05300 } 05301 } 05302 05303 /* Append to meta frame */ 05304 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05305 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05306 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05307 mtm->len = htons(f->datalen); 05308 mtm->mini.callno = htons(pvt->callno); 05309 mtm->mini.ts = htons(0xffff & fr->ts); 05310 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05311 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05312 } else { 05313 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05314 /* Store call number and length in meta header */ 05315 met->callno = htons(pvt->callno); 05316 met->len = htons(f->datalen); 05317 /* Advance pointers/decrease length past trunk entry header */ 05318 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05319 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05320 } 05321 /* Copy actual trunk data */ 05322 memcpy(ptr, f->data, f->datalen); 05323 tpeer->trunkdatalen += f->datalen; 05324 05325 tpeer->calls++; 05326 ast_mutex_unlock(&tpeer->lock); 05327 } 05328 return 0; 05329 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 7802 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
07803 { 07804 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 07805 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 6276 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag, iax2_registry::callno, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
06277 { 06278 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 06279 int res = -1; 06280 ast_mutex_lock(&iaxsl[callno]); 06281 if (iaxs[callno]) { 06282 /* If there's an outstanding error, return failure now */ 06283 if (!iaxs[callno]->error) { 06284 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 06285 res = 0; 06286 /* Don't waste bandwidth sending null frames */ 06287 else if (f->frametype == AST_FRAME_NULL) 06288 res = 0; 06289 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 06290 res = 0; 06291 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 06292 res = 0; 06293 else 06294 /* Simple, just queue for transmission */ 06295 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 06296 } else { 06297 if (option_debug) 06298 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 06299 } 06300 } 06301 /* If it's already gone, just return */ 06302 ast_mutex_unlock(&iaxsl[callno]); 06303 return res; 06304 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2792 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by update_registry().
02793 { 02794 int res = 0; 02795 struct iax_firmware *cur; 02796 if (!ast_strlen_zero(dev)) { 02797 ast_mutex_lock(&waresl.lock); 02798 cur = waresl.wares; 02799 while(cur) { 02800 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02801 res = ntohs(cur->fwh->version); 02802 break; 02803 } 02804 cur = cur->next; 02805 } 02806 ast_mutex_unlock(&waresl.lock); 02807 } 02808 return res; 02809 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 868 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00869 { 00870 if (iaxdebug) 00871 ast_verbose("%s", data); 00872 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 874 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00875 { 00876 ast_log(LOG_WARNING, "%s", data); 00877 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 2811 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_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, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.
Referenced by socket_process().
02812 { 02813 int res = -1; 02814 unsigned int bs = desc & 0xff; 02815 unsigned int start = (desc >> 8) & 0xffffff; 02816 unsigned int bytes; 02817 struct iax_firmware *cur; 02818 if (!ast_strlen_zero((char *)dev) && bs) { 02819 start *= bs; 02820 ast_mutex_lock(&waresl.lock); 02821 cur = waresl.wares; 02822 while(cur) { 02823 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 02824 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02825 if (start < ntohl(cur->fwh->datalen)) { 02826 bytes = ntohl(cur->fwh->datalen) - start; 02827 if (bytes > bs) 02828 bytes = bs; 02829 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02830 } else { 02831 bytes = 0; 02832 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02833 } 02834 if (bytes == bs) 02835 res = 0; 02836 else 02837 res = 1; 02838 break; 02839 } 02840 cur = cur->next; 02841 } 02842 ast_mutex_unlock(&waresl.lock); 02843 } 02844 return res; 02845 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 8073 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_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
08074 { 08075 struct iax_dual *d; 08076 struct ast_channel *chan1m, *chan2m; 08077 pthread_t th; 08078 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 08079 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 08080 if (chan2m && chan1m) { 08081 /* Make formats okay */ 08082 chan1m->readformat = chan1->readformat; 08083 chan1m->writeformat = chan1->writeformat; 08084 ast_channel_masquerade(chan1m, chan1); 08085 /* Setup the extensions and such */ 08086 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08087 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08088 chan1m->priority = chan1->priority; 08089 08090 /* We make a clone of the peer channel too, so we can play 08091 back the announcement */ 08092 /* Make formats okay */ 08093 chan2m->readformat = chan2->readformat; 08094 chan2m->writeformat = chan2->writeformat; 08095 ast_channel_masquerade(chan2m, chan2); 08096 /* Setup the extensions and such */ 08097 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08098 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08099 chan2m->priority = chan2->priority; 08100 if (ast_do_masquerade(chan2m)) { 08101 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08102 ast_hangup(chan2m); 08103 return -1; 08104 } 08105 } else { 08106 if (chan1m) 08107 ast_hangup(chan1m); 08108 if (chan2m) 08109 ast_hangup(chan2m); 08110 return -1; 08111 } 08112 if ((d = ast_calloc(1, sizeof(*d)))) { 08113 pthread_attr_t attr; 08114 08115 pthread_attr_init(&attr); 08116 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08117 08118 d->chan1 = chan1m; 08119 d->chan2 = chan2m; 08120 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 08121 pthread_attr_destroy(&attr); 08122 return 0; 08123 } 08124 pthread_attr_destroy(&attr); 08125 free(d); 08126 } 08127 return -1; 08128 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 8053 of file chan_iax2.c.
References ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, free, and LOG_NOTICE.
Referenced by iax_park().
08054 { 08055 struct ast_channel *chan1, *chan2; 08056 struct iax_dual *d; 08057 struct ast_frame *f; 08058 int ext; 08059 int res; 08060 d = stuff; 08061 chan1 = d->chan1; 08062 chan2 = d->chan2; 08063 free(d); 08064 f = ast_read(chan1); 08065 if (f) 08066 ast_frfree(f); 08067 res = ast_park_call(chan1, chan2, 0, &ext); 08068 ast_hangup(chan2); 08069 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 08070 return NULL; 08071 }
Definition at line 1655 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().
01656 { 01657 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01658 if (new) { 01659 size_t afdatalen = new->afdatalen; 01660 memcpy(new, fr, sizeof(*new)); 01661 iax_frame_wrap(new, &fr->af); 01662 new->afdatalen = afdatalen; 01663 new->data = NULL; 01664 new->datalen = 0; 01665 new->direction = DIRECTION_INGRESS; 01666 new->retrans = -1; 01667 } 01668 return new; 01669 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1012 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.
Referenced by iax2_process_thread().
01013 { 01014 if (thread->type == IAX_TYPE_DYNAMIC) { 01015 AST_LIST_LOCK(&dynamic_list); 01016 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01017 AST_LIST_UNLOCK(&dynamic_list); 01018 } else { 01019 AST_LIST_LOCK(&idle_list); 01020 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01021 AST_LIST_UNLOCK(&idle_list); 01022 } 01023 01024 return; 01025 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 903 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00904 { 00905 va_list args; 00906 char buf[1024]; 00907 00908 va_start(args, fmt); 00909 vsnprintf(buf, 1024, fmt, args); 00910 va_end(args); 00911 00912 ast_verbose("%s", buf); 00913 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 879 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00880 { 00881 va_list args; 00882 char buf[1024]; 00883 00884 va_start(args, fmt); 00885 vsnprintf(buf, 1024, fmt, args); 00886 va_end(args); 00887 00888 ast_log(LOG_ERROR, "%s", buf); 00889 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 891 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00892 { 00893 va_list args; 00894 char buf[1024]; 00895 00896 va_start(args, fmt); 00897 vsnprintf(buf, 1024, fmt, args); 00898 va_end(args); 00899 00900 ast_log(LOG_WARNING, "%s", buf); 00901 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 12694 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_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_random(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, DAHDI_FILE_PSEUDO, DAHDI_FILE_TIMER, iax2_registry::entry, errno, 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, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), netsock, option_verbose, outsock, peer_set_sock_cb(), peers, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), VERBOSE_PREFIX_2, and waresl.
12695 { 12696 static const char config[] = "iax.conf"; 12697 int res = 0; 12698 int x; 12699 struct iax2_registry *reg = NULL; 12700 12701 if (load_objects()) { 12702 return AST_MODULE_LOAD_FAILURE; 12703 } 12704 12705 randomcalltokendata = ast_random(); 12706 ast_custom_function_register(&iaxpeer_function); 12707 12708 iax_set_output(iax_debug_output); 12709 iax_set_error(iax_error_output); 12710 jb_setoutput(jb_error_output, jb_warning_output, NULL); 12711 12712 #ifdef HAVE_DAHDI 12713 #ifdef DAHDI_TIMERACK 12714 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 12715 if (timingfd < 0) 12716 #endif 12717 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 12718 if (timingfd < 0) 12719 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 12720 #endif 12721 12722 memset(iaxs, 0, sizeof(iaxs)); 12723 12724 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12725 ast_mutex_init(&iaxsl[x]); 12726 } 12727 12728 ast_cond_init(&sched_cond, NULL); 12729 12730 io = io_context_create(); 12731 sched = sched_context_create(); 12732 12733 if (!io || !sched) { 12734 ast_log(LOG_ERROR, "Out of memory\n"); 12735 return -1; 12736 } 12737 12738 netsock = ast_netsock_list_alloc(); 12739 if (!netsock) { 12740 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 12741 return -1; 12742 } 12743 ast_netsock_init(netsock); 12744 12745 outsock = ast_netsock_list_alloc(); 12746 if (!outsock) { 12747 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12748 return -1; 12749 } 12750 ast_netsock_init(outsock); 12751 12752 ast_mutex_init(&waresl.lock); 12753 12754 AST_LIST_HEAD_INIT(&iaxq.queue); 12755 12756 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12757 12758 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 12759 12760 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 12761 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 12762 12763 if(set_config(config, 0) == -1) 12764 return AST_MODULE_LOAD_DECLINE; 12765 12766 if (ast_channel_register(&iax2_tech)) { 12767 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 12768 __unload_module(); 12769 return -1; 12770 } 12771 12772 if (ast_register_switch(&iax2_switch)) 12773 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 12774 12775 res = start_network_thread(); 12776 if (!res) { 12777 if (option_verbose > 1) 12778 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 12779 } else { 12780 ast_log(LOG_ERROR, "Unable to start network thread\n"); 12781 ast_netsock_release(netsock); 12782 ast_netsock_release(outsock); 12783 } 12784 12785 AST_LIST_LOCK(®istrations); 12786 AST_LIST_TRAVERSE(®istrations, reg, entry) 12787 iax2_do_register(reg); 12788 AST_LIST_UNLOCK(®istrations); 12789 12790 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 12791 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 12792 12793 reload_firmware(0); 12794 iax_provision_reload(); 12795 return res; 12796 }
static int load_objects | ( | void | ) | [static] |
Definition at line 12637 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().
12638 { 12639 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 12640 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 12641 12642 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 12643 goto container_fail; 12644 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 12645 goto container_fail; 12646 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 12647 goto container_fail; 12648 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 12649 goto container_fail; 12650 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 12651 goto container_fail; 12652 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12653 goto container_fail; 12654 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12655 goto container_fail; 12656 } else if (create_callno_pools()) { 12657 goto container_fail; 12658 } 12659 12660 return 0; 12661 12662 container_fail: 12663 if (peers) { 12664 ao2_ref(peers, -1); 12665 } 12666 if (users) { 12667 ao2_ref(users, -1); 12668 } 12669 if (iax_peercallno_pvts) { 12670 ao2_ref(iax_peercallno_pvts, -1); 12671 } 12672 if (iax_transfercallno_pvts) { 12673 ao2_ref(iax_transfercallno_pvts, -1); 12674 } 12675 if (peercnts) { 12676 ao2_ref(peercnts, -1); 12677 } 12678 if (callno_limits) { 12679 ao2_ref(callno_limits, -1); 12680 } 12681 if (calltoken_ignores) { 12682 ao2_ref(calltoken_ignores, -1); 12683 } 12684 if (callno_pool) { 12685 ao2_ref(callno_pool, -1); 12686 } 12687 if (callno_pool_trunk) { 12688 ao2_ref(callno_pool_trunk, -1); 12689 } 12690 return AST_MODULE_LOAD_FAILURE; 12691 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4687 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
04688 { 04689 ast_mutex_lock(&iaxsl[callno0]); 04690 while (ast_mutex_trylock(&iaxsl[callno1])) { 04691 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 04692 } 04693 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1719 of file chan_iax2.c.
References 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, iaxsl, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, 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().
01720 { 01721 int x; 01722 int res= 0; 01723 struct callno_entry *callno_entry; 01724 if (iaxs[callno]->oseqno) { 01725 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01726 return -1; 01727 } 01728 if (callno & TRUNK_CALL_START) { 01729 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01730 return -1; 01731 } 01732 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01733 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01734 return -1; 01735 } 01736 01737 x = callno_entry->callno; 01738 ast_mutex_lock(&iaxsl[x]); 01739 01740 /*! 01741 * \note We delete these before switching the slot, because if 01742 * they fire in the meantime, they will generate a warning. 01743 */ 01744 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01745 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01746 iaxs[x] = iaxs[callno]; 01747 iaxs[x]->callno = x; 01748 01749 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01750 * before assigning the new one */ 01751 if (iaxs[x]->callno_entry) { 01752 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01753 } 01754 iaxs[x]->callno_entry = callno_entry; 01755 01756 iaxs[callno] = NULL; 01757 /* Update the two timers that should have been started */ 01758 iaxs[x]->pingid = iax2_sched_add(sched, 01759 ping_time * 1000, send_ping, (void *)(long)x); 01760 iaxs[x]->lagid = iax2_sched_add(sched, 01761 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01762 01763 if (locked) 01764 ast_mutex_unlock(&iaxsl[callno]); 01765 res = x; 01766 if (!locked) 01767 ast_mutex_unlock(&iaxsl[x]); 01768 01769 if (option_debug) 01770 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01771 /* We move this call from a non-trunked to a trunked call */ 01772 update_max_trunk(); 01773 update_max_nontrunk(); 01774 return res; 01775 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 5966 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
05967 { 05968 ast_cli_netstats(s, -1, 0); 05969 astman_append(s, "\r\n"); 05970 return RESULT_SUCCESS; 05971 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 5999 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
06000 { 06001 char *a[] = { "iax2", "show", "users" }; 06002 int ret; 06003 const char *id = astman_get_header(m,"ActionID"); 06004 06005 if (!ast_strlen_zero(id)) 06006 astman_append(s, "ActionID: %s\r\n",id); 06007 ret = __iax2_show_peers(1, -1, s, 3, a ); 06008 astman_append(s, "\r\n\r\n" ); 06009 return ret; 06010 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1685 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), softhangup_exec(), and transfercallno_pvt_cmp_cb().
01686 { 01687 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01688 (cur->addr.sin_port == sin->sin_port)) { 01689 /* This is the main host */ 01690 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01691 (check_dcallno ? dcallno == cur->callno : 1) ) { 01692 /* That's us. Be sure we keep track of the peer call number */ 01693 return 1; 01694 } 01695 } 01696 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01697 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01698 /* We're transferring */ 01699 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01700 return 1; 01701 } 01702 return 0; 01703 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5359 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05360 { 05361 #if 0 05362 /* Debug with "fake encryption" */ 05363 int x; 05364 if (len % 16) 05365 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05366 for (x=0;x<len;x++) 05367 dst[x] = src[x] ^ 0xff; 05368 #else 05369 unsigned char lastblock[16] = { 0 }; 05370 int x; 05371 while(len > 0) { 05372 aes_decrypt(src, dst, dcx); 05373 for (x=0;x<16;x++) 05374 dst[x] ^= lastblock[x]; 05375 memcpy(lastblock, src, sizeof(lastblock)); 05376 dst += 16; 05377 src += 16; 05378 len -= 16; 05379 } 05380 #endif 05381 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 5383 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05384 { 05385 #if 0 05386 /* Debug with "fake encryption" */ 05387 int x; 05388 if (len % 16) 05389 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05390 for (x=0;x<len;x++) 05391 dst[x] = src[x] ^ 0xff; 05392 #else 05393 unsigned char curblock[16] = { 0 }; 05394 int x; 05395 while(len > 0) { 05396 for (x=0;x<16;x++) 05397 curblock[x] ^= src[x]; 05398 aes_encrypt(curblock, dst, ecx); 05399 memcpy(curblock, dst, sizeof(curblock)); 05400 dst += 16; 05401 src += 16; 05402 len -= 16; 05403 } 05404 #endif 05405 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 6616 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
06617 { 06618 /* Select exactly one common encryption if there are any */ 06619 p->encmethods &= enc; 06620 if (p->encmethods) { 06621 if (p->encmethods & IAX_ENCRYPT_AES128) 06622 p->encmethods = IAX_ENCRYPT_AES128; 06623 else 06624 p->encmethods = 0; 06625 } 06626 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 10504 of file chan_iax2.c.
References 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_log(), ast_mutex_trylock, ast_mutex_unlock, attempt_transmit(), ast_iax2_queue::count, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, iax_frame::list, option_debug, ast_iax2_queue::queue, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
10505 { 10506 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 10507 from the network, and queue them for delivery to the channels */ 10508 int res, count, wakeup; 10509 struct iax_frame *f; 10510 10511 if (timingfd > -1) 10512 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 10513 10514 for(;;) { 10515 pthread_testcancel(); 10516 10517 /* Go through the queue, sending messages which have not yet been 10518 sent, and scheduling retransmissions if appropriate */ 10519 AST_LIST_LOCK(&iaxq.queue); 10520 count = 0; 10521 wakeup = -1; 10522 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 10523 if (f->sentyet) 10524 continue; 10525 10526 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 10527 if (ast_mutex_trylock(&iaxsl[f->callno])) { 10528 wakeup = 1; 10529 continue; 10530 } 10531 10532 f->sentyet++; 10533 10534 if (iaxs[f->callno]) { 10535 send_packet(f); 10536 count++; 10537 } 10538 10539 ast_mutex_unlock(&iaxsl[f->callno]); 10540 10541 if (f->retries < 0) { 10542 /* This is not supposed to be retransmitted */ 10543 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 10544 iaxq.count--; 10545 /* Free the iax frame */ 10546 iax_frame_free(f); 10547 } else { 10548 /* We need reliable delivery. Schedule a retransmission */ 10549 f->retries++; 10550 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 10551 } 10552 } 10553 AST_LIST_TRAVERSE_SAFE_END 10554 AST_LIST_UNLOCK(&iaxq.queue); 10555 10556 pthread_testcancel(); 10557 10558 if (option_debug && count >= 20) 10559 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 10560 10561 /* Now do the IO, and run scheduled tasks */ 10562 res = ast_io_wait(io, wakeup); 10563 if (res >= 0) { 10564 if (option_debug && res >= 20) 10565 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 10566 } 10567 } 10568 return NULL; 10569 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1613 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(), and jb_conf::resync_threshold.
Referenced by __find_callno().
01614 { 01615 struct chan_iax2_pvt *tmp; 01616 jb_conf jbconf; 01617 01618 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01619 return NULL; 01620 } 01621 01622 if (ast_string_field_init(tmp, 32)) { 01623 ao2_ref(tmp, -1); 01624 tmp = NULL; 01625 return NULL; 01626 } 01627 01628 tmp->prefs = prefs; 01629 tmp->callno = 0; 01630 tmp->peercallno = 0; 01631 tmp->transfercallno = 0; 01632 tmp->bridgecallno = 0; 01633 tmp->pingid = -1; 01634 tmp->lagid = -1; 01635 tmp->autoid = -1; 01636 tmp->authid = -1; 01637 tmp->initid = -1; 01638 01639 ast_string_field_set(tmp,exten, "s"); 01640 ast_string_field_set(tmp,host, host); 01641 01642 tmp->jb = jb_new(); 01643 tmp->jbid = -1; 01644 jbconf.max_jitterbuf = maxjitterbuffer; 01645 jbconf.resync_threshold = resyncthreshold; 01646 jbconf.max_contig_interp = maxjitterinterps; 01647 jb_setconf(tmp->jb,&jbconf); 01648 01649 tmp->hold_signaling = 1; 01650 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01651 01652 return tmp; 01653 }
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 4357 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
04358 { 04359 if (ast_strlen_zero(data)) 04360 return; 04361 04362 pds->peer = strsep(&data, "/"); 04363 pds->exten = strsep(&data, "/"); 04364 pds->options = data; 04365 04366 if (pds->exten) { 04367 data = pds->exten; 04368 pds->exten = strsep(&data, "@"); 04369 pds->context = data; 04370 } 04371 04372 if (strchr(pds->peer, '@')) { 04373 data = pds->peer; 04374 pds->username = strsep(&data, "@"); 04375 pds->peer = data; 04376 } 04377 04378 if (pds->username) { 04379 data = pds->username; 04380 pds->username = strsep(&data, ":"); 04381 pds->password = data; 04382 } 04383 04384 data = pds->peer; 04385 pds->peer = strsep(&data, ":"); 04386 pds->port = data; 04387 04388 /* check for a key name wrapped in [] in the secret position, if found, 04389 move it to the key field instead 04390 */ 04391 if (pds->password && (pds->password[0] == '[')) { 04392 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04393 pds->password = NULL; 04394 } 04395 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1241 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_objects().
01242 { 01243 struct iax2_peer *peer = obj, *peer2 = arg; 01244 01245 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01246 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11231 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11232 { 11233 struct iax2_peer *peer = obj; 11234 11235 ast_set_flag(peer, IAX_DELME); 11236 11237 return 0; 11238 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 10727 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, and register_peer_exten().
Referenced by build_peer().
10728 { 10729 struct iax2_peer *peer = obj; 10730 int callno = peer->callno; 10731 10732 ast_free_ha(peer->ha); 10733 10734 if (callno > 0) { 10735 ast_mutex_lock(&iaxsl[callno]); 10736 iax2_destroy(callno); 10737 ast_mutex_unlock(&iaxsl[callno]); 10738 } 10739 10740 register_peer_exten(peer, 0); 10741 10742 if (peer->dnsmgr) 10743 ast_dnsmgr_release(peer->dnsmgr); 10744 10745 ast_string_field_free_memory(peer); 10746 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1231 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_objects().
01232 { 01233 const struct iax2_peer *peer = obj; 01234 01235 return ast_str_hash(peer->name); 01236 }
Definition at line 1288 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), reg_source_db(), socket_process(), and update_registry().
01289 { 01290 ao2_ref(peer, +1); 01291 return peer; 01292 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12590 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
12591 { 12592 struct iax2_peer *peer = obj; 12593 12594 if (peer->sockfd < 0) 12595 peer->sockfd = defaultsockfd; 12596 12597 return 0; 12598 }
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 10654 of file chan_iax2.c.
References 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, option_debug, outsock, socket_read(), and iax2_peer::sockfd.
Referenced by build_peer().
10655 { 10656 struct sockaddr_in sin; 10657 int nonlocal = 1; 10658 int port = IAX_DEFAULT_PORTNO; 10659 int sockfd = defaultsockfd; 10660 char *tmp; 10661 char *addr; 10662 char *portstr; 10663 10664 if (!(tmp = ast_strdupa(srcaddr))) 10665 return -1; 10666 10667 addr = strsep(&tmp, ":"); 10668 portstr = tmp; 10669 10670 if (portstr) { 10671 port = atoi(portstr); 10672 if (port < 1) 10673 port = IAX_DEFAULT_PORTNO; 10674 } 10675 10676 if (!ast_get_ip(&sin, addr)) { 10677 struct ast_netsock *sock; 10678 int res; 10679 10680 sin.sin_port = 0; 10681 sin.sin_family = AF_INET; 10682 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 10683 if (res == 0) { 10684 /* ip address valid. */ 10685 sin.sin_port = htons(port); 10686 if (!(sock = ast_netsock_find(netsock, &sin))) 10687 sock = ast_netsock_find(outsock, &sin); 10688 if (sock) { 10689 sockfd = ast_netsock_sockfd(sock); 10690 nonlocal = 0; 10691 } else { 10692 unsigned int orig_saddr = sin.sin_addr.s_addr; 10693 /* INADDR_ANY matches anyway! */ 10694 sin.sin_addr.s_addr = INADDR_ANY; 10695 if (ast_netsock_find(netsock, &sin)) { 10696 sin.sin_addr.s_addr = orig_saddr; 10697 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 10698 if (sock) { 10699 sockfd = ast_netsock_sockfd(sock); 10700 ast_netsock_unref(sock); 10701 nonlocal = 0; 10702 } else { 10703 nonlocal = 2; 10704 } 10705 } 10706 } 10707 } 10708 } 10709 10710 peer->sockfd = sockfd; 10711 10712 if (nonlocal == 1) { 10713 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 10714 srcaddr, peer->name); 10715 return -1; 10716 } else if (nonlocal == 2) { 10717 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 10718 srcaddr, peer->name); 10719 return -1; 10720 } else { 10721 if (option_debug) 10722 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 10723 return 0; 10724 } 10725 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3236 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(), and iax2_show_peer().
03237 { 03238 int res = 0; 03239 if (peer->maxms) { 03240 if (peer->lastms < 0) { 03241 ast_copy_string(status, "UNREACHABLE", statuslen); 03242 } else if (peer->lastms > peer->maxms) { 03243 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03244 res = 1; 03245 } else if (peer->lastms) { 03246 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03247 res = 1; 03248 } else { 03249 ast_copy_string(status, "UNKNOWN", statuslen); 03250 } 03251 } else { 03252 ast_copy_string(status, "Unmonitored", statuslen); 03253 res = -1; 03254 } 03255 return res; 03256 }
Definition at line 1294 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_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01295 { 01296 ao2_ref(peer, -1); 01297 return NULL; 01298 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 1970 of file chan_iax2.c.
References peercnt::addr, ao2_alloc(), ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), LOG_DEBUG, LOG_ERROR, option_debug, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
01971 { 01972 struct peercnt *peercnt; 01973 unsigned long addr = sin->sin_addr.s_addr; 01974 int res = 0; 01975 struct peercnt tmp = { 01976 .addr = addr, 01977 }; 01978 01979 /* Reasoning for peercnts container lock: Two identical ip addresses 01980 * could be added by different threads at the "same time". Without the container 01981 * lock, both threads could alloc space for the same object and attempt 01982 * to link to table. With the lock, one would create the object and link 01983 * to table while the other would find the already created peercnt object 01984 * rather than creating a new one. */ 01985 ao2_lock(peercnts); 01986 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 01987 ao2_lock(peercnt); 01988 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 01989 ao2_lock(peercnt); 01990 /* create and set defaults */ 01991 peercnt->addr = addr; 01992 set_peercnt_limit(peercnt); 01993 /* guarantees it does not go away after unlocking table 01994 * ao2_find automatically adds this */ 01995 ao2_link(peercnts, peercnt); 01996 } else { 01997 ao2_unlock(peercnts); 01998 return -1; 01999 } 02000 02001 /* check to see if the address has hit its callno limit. If not increment cur. */ 02002 if (peercnt->limit > peercnt->cur) { 02003 peercnt->cur++; 02004 if (option_debug) { 02005 ast_log(LOG_DEBUG, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02006 } 02007 } else { /* max num call numbers for this peer has been reached! */ 02008 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02009 res = -1; 02010 } 02011 02012 /* clean up locks and ref count */ 02013 ao2_unlock(peercnt); 02014 ao2_unlock(peercnts); 02015 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02016 02017 return res; 02018 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1804 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
01805 { 01806 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 01807 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 01808 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1798 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 1940 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), peercnt::limit, LOG_DEBUG, option_debug, peercnts, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
01941 { 01942 /* this function turns off and on custom callno limits set by peer registration */ 01943 struct peercnt *peercnt; 01944 struct peercnt tmp = { 01945 .addr = sin->sin_addr.s_addr, 01946 }; 01947 01948 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 01949 peercnt->reg = reg; 01950 if (limit) { 01951 peercnt->limit = limit; 01952 } else { 01953 set_peercnt_limit(peercnt); 01954 } 01955 if (option_debug) { 01956 ast_log(LOG_DEBUG, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 01957 } 01958 ao2_ref(peercnt, -1); /* decrement ref from find */ 01959 } 01960 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2024 of file chan_iax2.c.
References peercnt::addr, ao2_unlink(), ast_inet_ntoa(), ast_log(), peercnt::cur, LOG_DEBUG, option_debug, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02025 { 02026 struct sockaddr_in sin = { 02027 .sin_addr.s_addr = peercnt->addr, 02028 }; 02029 02030 if (peercnt) { 02031 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02032 * peercnt_add could try and grab this entry from the table and modify it at the 02033 * "same time" this thread attemps to unlink it.*/ 02034 ao2_lock(peercnts); 02035 peercnt->cur--; 02036 if (option_debug) { 02037 ast_log(LOG_DEBUG, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02038 } 02039 /* if this was the last connection from the peer remove it from table */ 02040 if (peercnt->cur == 0) { 02041 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02042 } 02043 ao2_unlock(peercnts); 02044 } 02045 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2065 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
02066 { 02067 struct peercnt *peercnt; 02068 struct peercnt tmp = { 02069 .addr = sin->sin_addr.s_addr, 02070 }; 02071 02072 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02073 peercnt_remove(peercnt); 02074 ao2_ref(peercnt, -1); /* decrement ref from find */ 02075 } 02076 return 0; 02077 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2051 of file chan_iax2.c.
References ao2_ref(), and peercnt_remove().
Referenced by sched_delay_remove().
02052 { 02053 struct peercnt *peercnt = (struct peercnt *) obj; 02054 02055 peercnt_remove(peercnt); 02056 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02057 02058 return 0; 02059 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 11724 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().
11725 { 11726 struct ao2_iterator i; 11727 struct iax2_peer *peer; 11728 11729 i = ao2_iterator_init(peers, 0); 11730 while ((peer = ao2_iterator_next(&i))) { 11731 iax2_poke_peer(peer, 0); 11732 peer_unref(peer); 11733 } 11734 ao2_iterator_destroy(&i); 11735 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1929 of file chan_iax2.c.
References addr_range::delme.
Referenced by reload_config().
01930 { 01931 struct addr_range *addr_range = obj; 01932 01933 return addr_range->delme ? CMP_MATCH : 0; 01934 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 11292 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().
11293 { 11294 struct iax2_peer *peer; 11295 struct ao2_iterator i; 11296 11297 i = ao2_iterator_init(peers, 0); 11298 while ((peer = ao2_iterator_next(&i))) { 11299 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 11300 unlink_peer(peer); 11301 } 11302 peer_unref(peer); 11303 } 11304 ao2_iterator_destroy(&i); 11305 }
static void prune_users | ( | void | ) | [static] |
Definition at line 11276 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_unref(), and users.
Referenced by iax2_prune_realtime(), and reload_config().
11277 { 11278 struct iax2_user *user; 11279 struct ao2_iterator i; 11280 11281 i = ao2_iterator_init(users, 0); 11282 while ((user = ao2_iterator_next(&i))) { 11283 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 11284 ao2_unlink(users, user); 11285 } 11286 user_unref(user); 11287 } 11288 ao2_iterator_destroy(&i); 11289 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12607 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12608 { 12609 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12610 12611 /* The frames_received field is used to hold whether we're matching 12612 * against a full frame or not ... */ 12613 12614 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 12615 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12616 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1567 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, chan_iax2_pvt::callno_entry, jb_frame::data, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax2_registry::next, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, s, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.
Referenced by new_iax().
01568 { 01569 struct chan_iax2_pvt *pvt = obj; 01570 struct iax_frame *cur = NULL; 01571 struct signaling_queue_entry *s = NULL; 01572 01573 iax2_destroy_helper(pvt); 01574 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01575 pvt->callno_entry = NULL; 01576 01577 /* Already gone */ 01578 ast_set_flag(pvt, IAX_ALREADYGONE); 01579 01580 AST_LIST_LOCK(&iaxq.queue); 01581 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01582 /* Cancel any pending transmissions */ 01583 if (cur->callno == pvt->callno) { 01584 cur->retries = -1; 01585 } 01586 } 01587 AST_LIST_UNLOCK(&iaxq.queue); 01588 01589 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01590 free_signaling_queue_entry(s); 01591 } 01592 01593 if (pvt->reg) { 01594 pvt->reg->callno = 0; 01595 } 01596 01597 if (!pvt->owner) { 01598 jb_frame frame; 01599 if (pvt->vars) { 01600 ast_variables_destroy(pvt->vars); 01601 pvt->vars = NULL; 01602 } 01603 01604 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01605 iax2_frame_free(frame.data); 01606 } 01607 01608 jb_destroy(pvt->jb); 01609 ast_string_field_free_memory(pvt); 01610 } 01611 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12600 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
12601 { 12602 const struct chan_iax2_pvt *pvt = obj; 12603 12604 return pvt->peercallno; 12605 }
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 1543 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_registry::next, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01544 { 01545 struct signaling_queue_entry *new; 01546 01547 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01548 return 1; /* do not queue this frame */ 01549 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01550 return -1; /* out of memory */ 01551 } 01552 01553 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01554 01555 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01556 if (!(new->f.data = ast_calloc(1, new->f.datalen))) { 01557 free_signaling_queue_entry(new); 01558 return -1; 01559 } 01560 memcpy(new->f.data, f->data, sizeof(*new->f.data)); 01561 } 01562 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01563 01564 return 0; 01565 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 6598 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), 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().
06599 { 06600 struct ast_iax2_full_hdr fh; 06601 fh.scallno = htons(src | IAX_FLAG_FULL); 06602 fh.dcallno = htons(dst); 06603 fh.ts = 0; 06604 fh.oseqno = 0; 06605 fh.iseqno = 0; 06606 fh.type = AST_FRAME_IAX; 06607 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 06608 if (iaxdebug) 06609 iax_showframe(NULL, &fh, 0, sin, 0); 06610 if (option_debug) 06611 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 06612 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 06613 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 06614 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3723 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, ast_variable::value, and var.
03724 { 03725 struct ast_variable *var = NULL; 03726 struct ast_variable *tmp; 03727 struct iax2_peer *peer=NULL; 03728 time_t regseconds = 0, nowtime; 03729 int dynamic=0; 03730 03731 if (peername) { 03732 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 03733 if (!var && sin) 03734 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03735 } else if (sin) { 03736 char porta[25]; 03737 sprintf(porta, "%d", ntohs(sin->sin_port)); 03738 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03739 if (var) { 03740 /* We'll need the peer name in order to build the structure! */ 03741 for (tmp = var; tmp; tmp = tmp->next) { 03742 if (!strcasecmp(tmp->name, "name")) 03743 peername = tmp->value; 03744 } 03745 } 03746 } 03747 if (!var && peername) { /* Last ditch effort */ 03748 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 03749 /*!\note 03750 * If this one loaded something, then we need to ensure that the host 03751 * field matched. The only reason why we can't have this as a criteria 03752 * is because we only have the IP address and the host field might be 03753 * set as a name (and the reverse PTR might not match). 03754 */ 03755 if (var && sin) { 03756 for (tmp = var; tmp; tmp = tmp->next) { 03757 if (!strcasecmp(tmp->name, "host")) { 03758 struct ast_hostent ahp; 03759 struct hostent *hp; 03760 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03761 /* No match */ 03762 ast_variables_destroy(var); 03763 var = NULL; 03764 } 03765 break; 03766 } 03767 } 03768 } 03769 } 03770 if (!var) 03771 return NULL; 03772 03773 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 03774 03775 if (!peer) { 03776 ast_variables_destroy(var); 03777 return NULL; 03778 } 03779 03780 for (tmp = var; tmp; tmp = tmp->next) { 03781 /* Make sure it's not a user only... */ 03782 if (!strcasecmp(tmp->name, "type")) { 03783 if (strcasecmp(tmp->value, "friend") && 03784 strcasecmp(tmp->value, "peer")) { 03785 /* Whoops, we weren't supposed to exist! */ 03786 peer = peer_unref(peer); 03787 break; 03788 } 03789 } else if (!strcasecmp(tmp->name, "regseconds")) { 03790 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 03791 } else if (!strcasecmp(tmp->name, "ipaddr")) { 03792 inet_aton(tmp->value, &(peer->addr.sin_addr)); 03793 } else if (!strcasecmp(tmp->name, "port")) { 03794 peer->addr.sin_port = htons(atoi(tmp->value)); 03795 } else if (!strcasecmp(tmp->name, "host")) { 03796 if (!strcasecmp(tmp->value, "dynamic")) 03797 dynamic = 1; 03798 } 03799 } 03800 03801 ast_variables_destroy(var); 03802 03803 if (!peer) 03804 return NULL; 03805 03806 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03807 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 03808 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 03809 if (peer->expire > -1) { 03810 if (!ast_sched_del(sched, peer->expire)) { 03811 peer->expire = -1; 03812 peer_unref(peer); 03813 } 03814 } 03815 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 03816 if (peer->expire == -1) 03817 peer_unref(peer); 03818 } 03819 ao2_link(peers, peer); 03820 if (ast_test_flag(peer, IAX_DYNAMIC)) 03821 reg_source_db(peer); 03822 } else { 03823 ast_set_flag(peer, IAX_TEMPONLY); 03824 } 03825 03826 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 03827 time(&nowtime); 03828 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 03829 memset(&peer->addr, 0, sizeof(peer->addr)); 03830 realtime_update_peer(peer->name, &peer->addr, 0); 03831 if (option_debug) 03832 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 03833 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03834 } 03835 else { 03836 if (option_debug) 03837 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 03838 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03839 } 03840 } 03841 03842 return peer; 03843 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3916 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03917 { 03918 char port[10]; 03919 char regseconds[20]; 03920 03921 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03922 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03923 ast_update_realtime("iaxpeers", "name", peername, 03924 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03925 "regseconds", regseconds, NULL); 03926 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3845 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, ast_variable::value, and var.
03846 { 03847 struct ast_variable *var; 03848 struct ast_variable *tmp; 03849 struct iax2_user *user=NULL; 03850 03851 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 03852 if (!var) 03853 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03854 if (!var && sin) { 03855 char porta[6]; 03856 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 03857 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03858 if (!var) 03859 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03860 } 03861 if (!var) { /* Last ditch effort */ 03862 var = ast_load_realtime("iaxusers", "name", username, NULL); 03863 /*!\note 03864 * If this one loaded something, then we need to ensure that the host 03865 * field matched. The only reason why we can't have this as a criteria 03866 * is because we only have the IP address and the host field might be 03867 * set as a name (and the reverse PTR might not match). 03868 */ 03869 if (var) { 03870 for (tmp = var; tmp; tmp = tmp->next) { 03871 if (!strcasecmp(tmp->name, "host")) { 03872 struct ast_hostent ahp; 03873 struct hostent *hp; 03874 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03875 /* No match */ 03876 ast_variables_destroy(var); 03877 var = NULL; 03878 } 03879 break; 03880 } 03881 } 03882 } 03883 } 03884 if (!var) 03885 return NULL; 03886 03887 tmp = var; 03888 while(tmp) { 03889 /* Make sure it's not a peer only... */ 03890 if (!strcasecmp(tmp->name, "type")) { 03891 if (strcasecmp(tmp->value, "friend") && 03892 strcasecmp(tmp->value, "user")) { 03893 return NULL; 03894 } 03895 } 03896 tmp = tmp->next; 03897 } 03898 03899 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03900 03901 ast_variables_destroy(var); 03902 03903 if (!user) 03904 return NULL; 03905 03906 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03907 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03908 ao2_link(users, user); 03909 } else { 03910 ast_set_flag(user, IAX_TEMPONLY); 03911 } 03912 03913 return user; 03914 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 7421 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, iax2_peer::name, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
07422 { 07423 char data[80]; 07424 struct in_addr in; 07425 char *c, *d; 07426 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 07427 c = strchr(data, ':'); 07428 if (c) { 07429 *c = '\0'; 07430 c++; 07431 if (inet_aton(data, &in)) { 07432 d = strchr(c, ':'); 07433 if (d) { 07434 *d = '\0'; 07435 d++; 07436 if (option_verbose > 2) 07437 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 07438 ast_inet_ntoa(in), atoi(c), atoi(d)); 07439 iax2_poke_peer(p, 0); 07440 p->expiry = atoi(d); 07441 memset(&p->addr, 0, sizeof(p->addr)); 07442 p->addr.sin_family = AF_INET; 07443 p->addr.sin_addr = in; 07444 p->addr.sin_port = htons(atoi(c)); 07445 if (p->expire > -1) { 07446 if (!ast_sched_del(sched, p->expire)) { 07447 p->expire = -1; 07448 peer_unref(p); 07449 } 07450 } 07451 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07452 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07453 if (p->expire == -1) 07454 peer_unref(p); 07455 if (iax2_regfunk) 07456 iax2_regfunk(p->name, 1); 07457 register_peer_exten(p, 1); 07458 } 07459 07460 } 07461 } 07462 } 07463 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 7339 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, and S_OR.
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
07340 { 07341 char multi[256]; 07342 char *stringp, *ext; 07343 if (!ast_strlen_zero(regcontext)) { 07344 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 07345 stringp = multi; 07346 while((ext = strsep(&stringp, "&"))) { 07347 if (onoff) { 07348 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 07349 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 07350 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 07351 } else 07352 ast_context_remove_extension(regcontext, ext, 1, NULL); 07353 } 07354 } 07355 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 6765 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, iaxsl, ies, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax2_peer::secret, and secret.
Referenced by handle_request_register(), and socket_process().
06766 { 06767 char requeststr[256] = ""; 06768 char peer[256] = ""; 06769 char md5secret[256] = ""; 06770 char rsasecret[256] = ""; 06771 char secret[256] = ""; 06772 struct iax2_peer *p = NULL; 06773 struct ast_key *key; 06774 char *keyn; 06775 int x; 06776 int expire = 0; 06777 int res = -1; 06778 06779 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06780 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 06781 if (ies->username) 06782 ast_copy_string(peer, ies->username, sizeof(peer)); 06783 if (ies->password) 06784 ast_copy_string(secret, ies->password, sizeof(secret)); 06785 if (ies->md5_result) 06786 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06787 if (ies->rsa_result) 06788 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06789 if (ies->refresh) 06790 expire = ies->refresh; 06791 06792 if (ast_strlen_zero(peer)) { 06793 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 06794 return -1; 06795 } 06796 06797 /* SLD: first call to lookup peer during registration */ 06798 ast_mutex_unlock(&iaxsl[callno]); 06799 p = find_peer(peer, 1); 06800 ast_mutex_lock(&iaxsl[callno]); 06801 if (!p || !iaxs[callno]) { 06802 if (iaxs[callno]) { 06803 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 06804 06805 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06806 06807 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 06808 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 06809 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 06810 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 06811 * to be plaintext, indicating it is an authmethod used by other peers on the system. 06812 * 06813 * If none of these cases exist, res will be returned as 0 without authentication indicating 06814 * an AUTHREQ needs to be sent out. */ 06815 06816 if (ast_strlen_zero(iaxs[callno]->challenge) && 06817 !(!ast_strlen_zero(secret) && plaintext)) { 06818 /* by setting res to 0, an REGAUTH will be sent */ 06819 res = 0; 06820 } 06821 } 06822 if (authdebug && !p) 06823 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06824 06825 goto return_unref; 06826 } 06827 06828 if (!ast_test_flag(p, IAX_DYNAMIC)) { 06829 if (authdebug) 06830 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06831 goto return_unref; 06832 } 06833 06834 if (!ast_apply_ha(p->ha, sin)) { 06835 if (authdebug) 06836 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06837 goto return_unref; 06838 } 06839 ast_string_field_set(iaxs[callno], secret, p->secret); 06840 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 06841 /* Check secret against what we have on file */ 06842 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06843 if (!ast_strlen_zero(p->inkeys)) { 06844 char tmpkeys[256]; 06845 char *stringp=NULL; 06846 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 06847 stringp=tmpkeys; 06848 keyn = strsep(&stringp, ":"); 06849 while(keyn) { 06850 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06851 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 06852 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06853 break; 06854 } else if (!key) 06855 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 06856 keyn = strsep(&stringp, ":"); 06857 } 06858 if (!keyn) { 06859 if (authdebug) 06860 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 06861 goto return_unref; 06862 } 06863 } else { 06864 if (authdebug) 06865 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 06866 goto return_unref; 06867 } 06868 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06869 struct MD5Context md5; 06870 unsigned char digest[16]; 06871 char *tmppw, *stringp; 06872 06873 tmppw = ast_strdupa(p->secret); 06874 stringp = tmppw; 06875 while((tmppw = strsep(&stringp, ";"))) { 06876 MD5Init(&md5); 06877 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06878 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06879 MD5Final(digest, &md5); 06880 for (x=0;x<16;x++) 06881 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06882 if (!strcasecmp(requeststr, md5secret)) 06883 break; 06884 } 06885 if (tmppw) { 06886 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06887 } else { 06888 if (authdebug) 06889 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 06890 goto return_unref; 06891 } 06892 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 06893 /* They've provided a plain text password and we support that */ 06894 if (strcmp(secret, p->secret)) { 06895 if (authdebug) 06896 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06897 goto return_unref; 06898 } else 06899 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06900 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 06901 /* if challenge has been sent, but no challenge response if given, reject. */ 06902 goto return_unref; 06903 } 06904 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06905 06906 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 06907 res = 0; 06908 return_unref: 06909 06910 if (iaxs[callno]) { 06911 ast_string_field_set(iaxs[callno], peer, peer); 06912 06913 /* Choose lowest expiry number */ 06914 if (expire && (expire < iaxs[callno]->expiry)) { 06915 iaxs[callno]->expiry = expire; 06916 } 06917 } 06918 06919 if (p) { 06920 peer_unref(p); 06921 } 06922 return res; 06923 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 7610 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), and send_command().
Referenced by socket_process().
07611 { 07612 struct iax_ie_data ied; 07613 struct iax2_peer *p; 07614 char challenge[10]; 07615 const char *peer_name; 07616 int sentauthmethod; 07617 07618 peer_name = ast_strdupa(iaxs[callno]->peer); 07619 07620 /* SLD: third call to find_peer in registration */ 07621 ast_mutex_unlock(&iaxsl[callno]); 07622 if ((p = find_peer(peer_name, 1))) { 07623 last_authmethod = p->authmethods; 07624 } 07625 07626 ast_mutex_lock(&iaxsl[callno]); 07627 if (!iaxs[callno]) 07628 goto return_unref; 07629 07630 memset(&ied, 0, sizeof(ied)); 07631 /* The selection of which delayed reject is sent may leak information, 07632 * if it sets a static response. For example, if a host is known to only 07633 * use MD5 authentication, then an RSA response would indicate that the 07634 * peer does not exist, and vice-versa. 07635 * Therefore, we use whatever the last peer used (which may vary over the 07636 * course of a server, which should leak minimal information). */ 07637 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07638 if (!p) { 07639 iaxs[callno]->authmethods = sentauthmethod; 07640 } 07641 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 07642 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 07643 /* Build the challenge */ 07644 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07645 ast_string_field_set(iaxs[callno], challenge, challenge); 07646 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 07647 } 07648 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 07649 07650 return_unref: 07651 if (p) { 07652 peer_unref(p); 07653 } 07654 07655 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 07656 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 7658 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_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_process().
07659 { 07660 struct iax2_registry *reg; 07661 /* Start pessimistic */ 07662 struct iax_ie_data ied; 07663 char peer[256] = ""; 07664 char challenge[256] = ""; 07665 int res; 07666 int authmethods = 0; 07667 if (ies->authmethods) 07668 authmethods = ies->authmethods; 07669 if (ies->username) 07670 ast_copy_string(peer, ies->username, sizeof(peer)); 07671 if (ies->challenge) 07672 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 07673 memset(&ied, 0, sizeof(ied)); 07674 reg = iaxs[callno]->reg; 07675 if (reg) { 07676 if (inaddrcmp(®->addr, sin)) { 07677 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07678 return -1; 07679 } 07680 if (ast_strlen_zero(reg->secret)) { 07681 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 07682 reg->regstate = REG_STATE_NOAUTH; 07683 return -1; 07684 } 07685 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07686 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07687 if (reg->secret[0] == '[') { 07688 char tmpkey[256]; 07689 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 07690 tmpkey[strlen(tmpkey) - 1] = '\0'; 07691 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 07692 } else 07693 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 07694 if (!res) { 07695 reg->regstate = REG_STATE_AUTHSENT; 07696 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 07697 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07698 } else 07699 return -1; 07700 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 07701 } else 07702 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 07703 return -1; 07704 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 6012 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_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
06013 { 06014 switch(regstate) { 06015 case REG_STATE_UNREGISTERED: 06016 return "Unregistered"; 06017 case REG_STATE_REGSENT: 06018 return "Request Sent"; 06019 case REG_STATE_AUTHSENT: 06020 return "Auth. Sent"; 06021 case REG_STATE_REGISTERED: 06022 return "Registered"; 06023 case REG_STATE_REJECTED: 06024 return "Rejected"; 06025 case REG_STATE_TIMEOUT: 06026 return "Timeout"; 06027 case REG_STATE_NOAUTH: 06028 return "No Authentication"; 06029 default: 06030 return "Unknown"; 06031 } 06032 }
static int reload | ( | void | ) | [static] |
Definition at line 11765 of file chan_iax2.c.
References reload_config().
11766 { 11767 return reload_config(); 11768 }
static int reload_config | ( | void | ) | [static] |
Definition at line 11736 of file chan_iax2.c.
References ao2_callback(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, callno_limits, calltoken_ignores, config, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
11737 { 11738 static const char config[] = "iax.conf"; 11739 struct iax2_registry *reg; 11740 11741 if (set_config(config, 1) > 0) { 11742 prune_peers(); 11743 prune_users(); 11744 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11745 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11746 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 11747 AST_LIST_LOCK(®istrations); 11748 AST_LIST_TRAVERSE(®istrations, reg, entry) 11749 iax2_do_register(reg); 11750 AST_LIST_UNLOCK(®istrations); 11751 /* Qualify hosts, too */ 11752 poke_all_peers(); 11753 } 11754 reload_firmware(0); 11755 iax_provision_reload(); 11756 11757 return 0; 11758 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2848 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), iax_firmware::dead, destroy_firmware(), errno, ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by __unload_module(), load_module(), and reload_config().
02849 { 02850 struct iax_firmware *cur, *curl, *curp; 02851 DIR *fwd; 02852 struct dirent *de; 02853 char dir[256]; 02854 char fn[256]; 02855 /* Mark all as dead */ 02856 ast_mutex_lock(&waresl.lock); 02857 cur = waresl.wares; 02858 while(cur) { 02859 cur->dead = 1; 02860 cur = cur->next; 02861 } 02862 02863 /* Now that we've freed them, load the new ones */ 02864 if (!unload) { 02865 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02866 fwd = opendir(dir); 02867 if (fwd) { 02868 while((de = readdir(fwd))) { 02869 if (de->d_name[0] != '.') { 02870 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02871 if (!try_firmware(fn)) { 02872 if (option_verbose > 1) 02873 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02874 } 02875 } 02876 } 02877 closedir(fwd); 02878 } else 02879 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02880 } 02881 02882 /* Clean up leftovers */ 02883 cur = waresl.wares; 02884 curp = NULL; 02885 while(cur) { 02886 curl = cur; 02887 cur = cur->next; 02888 if (curl->dead) { 02889 if (curp) { 02890 curp->next = cur; 02891 } else { 02892 waresl.wares = cur; 02893 } 02894 destroy_firmware(curl); 02895 } else { 02896 curp = cur; 02897 } 02898 } 02899 ast_mutex_unlock(&waresl.lock); 02900 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1408 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().
01409 { 01410 if (!pvt->peercallno) { 01411 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01412 return; 01413 } 01414 01415 ao2_unlink(iax_peercallno_pvts, pvt); 01416 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1389 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().
01390 { 01391 if (!pvt->transfercallno) { 01392 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01393 return; 01394 } 01395 01396 ao2_unlink(iax_transfercallno_pvts, pvt); 01397 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2245 of file chan_iax2.c.
References ao2_ref(), ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02246 { 02247 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02248 02249 /* the callno_pool container is locked here primarily to ensure thread 02250 * safety of the total_nonval_callno_used check and decrement */ 02251 ao2_lock(callno_pool); 02252 02253 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02254 total_nonval_callno_used--; 02255 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02256 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02257 } 02258 02259 if (callno_entry->callno < TRUNK_CALL_START) { 02260 ao2_link(callno_pool, callno_entry); 02261 } else { 02262 ao2_link(callno_pool_trunk, callno_entry); 02263 } 02264 ao2_ref(callno_entry, -1); /* only container ref remains */ 02265 02266 ao2_unlock(callno_pool); 02267 return 0; 02268 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4214 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().
Referenced by handle_call_token().
04215 { 04216 struct iax2_user *user = NULL; 04217 struct iax2_peer *peer = NULL; 04218 04219 if (ast_strlen_zero(name)) { 04220 return; /* no username given */ 04221 } 04222 04223 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04224 user->calltoken_required = CALLTOKEN_YES; 04225 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04226 peer->calltoken_required = CALLTOKEN_YES; 04227 } 04228 04229 if (peer) { 04230 peer_unref(peer); 04231 } 04232 if (user) { 04233 user_unref(user); 04234 } 04235 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4130 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, iaxq, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, ast_iax2_queue::queue, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().
Referenced by socket_process().
04131 { 04132 struct chan_iax2_pvt *pvt = iaxs[callno]; 04133 int frametype = f->af.frametype; 04134 int subclass = f->af.subclass; 04135 struct { 04136 struct ast_iax2_full_hdr fh; 04137 struct iax_ie_data ied; 04138 } data = { 04139 .ied.buf = { 0 }, 04140 .ied.pos = 0, 04141 }; 04142 /* total len - header len gives us the frame's IE len */ 04143 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04144 04145 if (!pvt) { 04146 return; /* this should not be possible if called from socket_process() */ 04147 } 04148 04149 /* 04150 * Check to make sure last frame sent is valid for call token resend 04151 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04152 * 2. Frame should _NOT_ already have a destination callno 04153 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04154 * 4. Pvt must have a calltoken_ie_len which represents the number of 04155 * bytes at the end of the frame used for the previous calltoken ie. 04156 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04157 * 6. Total length of f->data must be _LESS_ than size of our data struct 04158 * because f->data must be able to fit within data. 04159 */ 04160 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04161 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04162 (f->datalen > sizeof(data))) { 04163 04164 return; /* ignore resend, token was not valid for the dialog */ 04165 } 04166 04167 /* token is valid 04168 * 1. Copy frame data over 04169 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04170 * NOTE: Having the ie always be last is not protocol specified, 04171 * it is only an implementation choice. Since we only expect the ie to 04172 * be last for frames we have sent, this can no way be affected by 04173 * another end point. 04174 * 3. Remove frame from queue 04175 * 4. Free old frame 04176 * 5. Clear previous seqnos 04177 * 6. Resend with CALLTOKEN ie. 04178 */ 04179 04180 /* ---1.--- */ 04181 memcpy(&data, f->data, f->datalen); 04182 data.ied.pos = ie_data_pos; 04183 04184 /* ---2.--- */ 04185 /* move to the beginning of the calltoken ie so we can write over it */ 04186 data.ied.pos -= pvt->calltoken_ie_len; 04187 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04188 04189 /* make sure to update token length incase it ever has to be stripped off again */ 04190 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04191 04192 /* ---3.--- */ 04193 AST_LIST_LOCK(&iaxq.queue); 04194 AST_LIST_REMOVE(&iaxq.queue, f, list); 04195 AST_LIST_UNLOCK(&iaxq.queue); 04196 04197 /* ---4.--- */ 04198 iax2_frame_free(f); 04199 04200 /* ---5.--- */ 04201 pvt->oseqno = 0; 04202 pvt->rseqno = 0; 04203 pvt->iseqno = 0; 04204 pvt->aseqno = 0; 04205 if (pvt->peercallno) { 04206 remove_by_peercallno(pvt); 04207 pvt->peercallno = 0; 04208 } 04209 04210 /* ---6.--- */ 04211 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04212 }
Definition at line 8163 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
08164 { 08165 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 08166 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 08167 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 08168 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 08169 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 08170 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 08171 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 08172 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2317 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), iax2_sched_add(), LOG_DEBUG, MIN_REUSE_TIME, option_debug, peercnt_remove_cb(), peercnts, replace_callno(), and sched.
Referenced by pvt_destructor().
02318 { 02319 int i; 02320 struct peercnt *peercnt; 02321 struct peercnt tmp = { 02322 .addr = sin->sin_addr.s_addr, 02323 }; 02324 02325 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02326 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02327 if (option_debug) { 02328 ast_log(LOG_DEBUG, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02329 } 02330 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02331 if (i == -1) { 02332 ao2_ref(peercnt, -1); 02333 } 02334 } 02335 02336 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02337 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 10469 of file chan_iax2.c.
References ast_cond_timedwait, ast_cond_wait, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), option_debug, sched, and sched_lock.
Referenced by start_network_thread().
10470 { 10471 for (;;) { 10472 int ms, count; 10473 struct timespec ts; 10474 10475 pthread_testcancel(); 10476 10477 ast_mutex_lock(&sched_lock); 10478 10479 ms = ast_sched_wait(sched); 10480 10481 if (ms == -1) { 10482 ast_cond_wait(&sched_cond, &sched_lock); 10483 } else { 10484 struct timeval tv; 10485 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 10486 ts.tv_sec = tv.tv_sec; 10487 ts.tv_nsec = tv.tv_usec * 1000; 10488 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 10489 } 10490 10491 ast_mutex_unlock(&sched_lock); 10492 10493 pthread_testcancel(); 10494 10495 count = ast_sched_runq(sched); 10496 if (option_debug && count >= 20) { 10497 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 10498 } 10499 } 10500 10501 return NULL; 10502 }
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 3576 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), 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, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
03577 { 03578 int type, len; 03579 int ret; 03580 int needfree = 0; 03581 struct ast_channel *owner = NULL; 03582 struct ast_channel *bridge = NULL; 03583 03584 /* Attempt to recover wrapped timestamps */ 03585 unwrap_timestamp(fr); 03586 03587 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03588 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03589 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03590 else { 03591 #if 0 03592 if (option_debug) 03593 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03594 #endif 03595 fr->af.delivery = ast_tv(0,0); 03596 } 03597 03598 type = JB_TYPE_CONTROL; 03599 len = 0; 03600 03601 if(fr->af.frametype == AST_FRAME_VOICE) { 03602 type = JB_TYPE_VOICE; 03603 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03604 } else if(fr->af.frametype == AST_FRAME_CNG) { 03605 type = JB_TYPE_SILENCE; 03606 } 03607 03608 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 03609 if (tsout) 03610 *tsout = fr->ts; 03611 __do_deliver(fr); 03612 return -1; 03613 } 03614 03615 if ((owner = iaxs[fr->callno]->owner)) 03616 bridge = ast_bridged_channel(owner); 03617 03618 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 03619 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 03620 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 03621 jb_frame frame; 03622 03623 /* deliver any frames in the jb */ 03624 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 03625 __do_deliver(frame.data); 03626 /* __do_deliver() can make the call disappear */ 03627 if (!iaxs[fr->callno]) 03628 return -1; 03629 } 03630 03631 jb_reset(iaxs[fr->callno]->jb); 03632 03633 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 03634 03635 /* deliver this frame now */ 03636 if (tsout) 03637 *tsout = fr->ts; 03638 __do_deliver(fr); 03639 return -1; 03640 } 03641 03642 /* insert into jitterbuffer */ 03643 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 03644 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 03645 calc_rxstamp(iaxs[fr->callno],fr->ts)); 03646 if (ret == JB_DROP) { 03647 needfree++; 03648 } else if (ret == JB_SCHED) { 03649 update_jbsched(iaxs[fr->callno]); 03650 } 03651 if (tsout) 03652 *tsout = fr->ts; 03653 if (needfree) { 03654 /* Free our iax frame */ 03655 iax2_frame_free(fr); 03656 return -1; 03657 } 03658 return 0; 03659 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1508 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_registry::callno, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01509 { 01510 short callno = PTR_TO_CALLNO(vid); 01511 ast_mutex_lock(&iaxsl[callno]); 01512 if (iaxs[callno]) { 01513 if (option_debug) { 01514 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01515 } 01516 iax2_destroy(callno); 01517 } 01518 ast_mutex_unlock(&iaxsl[callno]); 01519 return 0; 01520 }
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 4094 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().
04097 { 04098 struct { 04099 struct ast_iax2_full_hdr f; 04100 struct iax_ie_data ied; 04101 } data; 04102 size_t size = sizeof(struct ast_iax2_full_hdr); 04103 04104 if (ied) { 04105 size += ied->pos; 04106 memcpy(&data.ied, ied->buf, ied->pos); 04107 } 04108 04109 data.f.scallno = htons(0x8000 | callno); 04110 data.f.dcallno = htons(dcallno); 04111 data.f.ts = htonl(ts); 04112 data.f.iseqno = seqno; 04113 data.f.oseqno = 0; 04114 data.f.type = AST_FRAME_IAX; 04115 data.f.csub = compress_subclass(command); 04116 04117 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04118 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6323 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_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
06324 { 06325 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 06326 }
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 6342 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().
06343 { 06344 int call_num = i->callno; 06345 /* It is assumed that the callno has already been locked */ 06346 iax2_predestroy(i->callno); 06347 if (!iaxs[call_num]) 06348 return -1; 06349 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 06350 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6352 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
06353 { 06354 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 06355 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6328 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
06329 { 06330 int res; 06331 ast_mutex_lock(&iaxsl[callno]); 06332 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 06333 ast_mutex_unlock(&iaxsl[callno]); 06334 return res; 06335 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 6357 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
06358 { 06359 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 06360 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1184 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01185 { 01186 #ifdef SCHED_MULTITHREADED 01187 if (schedule_action(__send_lagrq, data)) 01188 #endif 01189 __send_lagrq(data); 01190 01191 return 0; 01192 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2973 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), iax2_registry::callno, errno, f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, and chan_iax2_pvt::transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02974 { 02975 int res; 02976 int callno = f->callno; 02977 02978 /* Don't send if there was an error, but return error instead */ 02979 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02980 return -1; 02981 02982 /* Called with iaxsl held */ 02983 if (option_debug > 2 && iaxdebug) 02984 ast_log(LOG_DEBUG, "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)); 02985 if (f->transfer) { 02986 if (iaxdebug) 02987 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02988 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02989 sizeof(iaxs[callno]->transfer)); 02990 } else { 02991 if (iaxdebug) 02992 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02993 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02994 sizeof(iaxs[callno]->addr)); 02995 } 02996 if (res < 0) { 02997 if (option_debug && iaxdebug) 02998 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02999 handle_error(); 03000 } else 03001 res = 0; 03002 return res; 03003 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1139 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01140 { 01141 #ifdef SCHED_MULTITHREADED 01142 if (schedule_action(__send_ping, data)) 01143 #endif 01144 __send_ping(data); 01145 01146 return 0; 01147 }
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 1530 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_registry::next, s, and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01531 { 01532 struct signaling_queue_entry *s = NULL; 01533 01534 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01535 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01536 free_signaling_queue_entry(s); 01537 } 01538 pvt->hold_signaling = 0; 01539 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 7841 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), 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, option_debug, 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 timing_read().
07842 { 07843 int res = 0; 07844 struct iax_frame *fr; 07845 struct ast_iax2_meta_hdr *meta; 07846 struct ast_iax2_meta_trunk_hdr *mth; 07847 int calls = 0; 07848 07849 /* Point to frame */ 07850 fr = (struct iax_frame *)tpeer->trunkdata; 07851 /* Point to meta data */ 07852 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 07853 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 07854 if (tpeer->trunkdatalen) { 07855 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 07856 meta->zeros = 0; 07857 meta->metacmd = IAX_META_TRUNK; 07858 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 07859 meta->cmddata = IAX_META_TRUNK_MINI; 07860 else 07861 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 07862 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 07863 /* And the rest of the ast_iax2 header */ 07864 fr->direction = DIRECTION_OUTGRESS; 07865 fr->retrans = -1; 07866 fr->transfer = 0; 07867 /* Any appropriate call will do */ 07868 fr->data = fr->afdata; 07869 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 07870 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 07871 calls = tpeer->calls; 07872 #if 0 07873 if (option_debug) 07874 ast_log(LOG_DEBUG, "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)); 07875 #endif 07876 /* Reset transmit trunk side data */ 07877 tpeer->trunkdatalen = 0; 07878 tpeer->calls = 0; 07879 } 07880 if (res < 0) 07881 return res; 07882 return calls; 07883 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 11340 of file chan_iax2.c.
References __ao2_link(), add_calltoken_ignore(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), 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_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_callno_limits(), build_peer(), build_user(), capability, 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_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_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), peers, portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
11341 { 11342 struct ast_config *cfg, *ucfg; 11343 int capability=iax2_capability; 11344 struct ast_variable *v; 11345 char *cat; 11346 const char *utype; 11347 const char *tosval; 11348 int format; 11349 int portno = IAX_DEFAULT_PORTNO; 11350 int x; 11351 struct iax2_user *user; 11352 struct iax2_peer *peer; 11353 struct ast_netsock *ns; 11354 #if 0 11355 static unsigned short int last_port=0; 11356 #endif 11357 11358 cfg = ast_config_load(config_file); 11359 11360 if (!cfg) { 11361 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 11362 return -1; 11363 } 11364 11365 if (reload) { 11366 set_config_destroy(); 11367 } 11368 11369 /* Reset global codec prefs */ 11370 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 11371 11372 /* Reset Global Flags */ 11373 memset(&globalflags, 0, sizeof(globalflags)); 11374 ast_set_flag(&globalflags, IAX_RTUPDATE); 11375 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 11376 11377 #ifdef SO_NO_CHECK 11378 nochecksums = 0; 11379 #endif 11380 11381 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11382 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11383 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 11384 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 11385 11386 maxauthreq = 3; 11387 11388 v = ast_variable_browse(cfg, "general"); 11389 11390 /* Seed initial tos value */ 11391 tosval = ast_variable_retrieve(cfg, "general", "tos"); 11392 if (tosval) { 11393 if (ast_str2tos(tosval, &tos)) 11394 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 11395 } 11396 while(v) { 11397 if (!strcasecmp(v->name, "bindport")){ 11398 if (reload) 11399 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 11400 else 11401 portno = atoi(v->value); 11402 } else if (!strcasecmp(v->name, "pingtime")) 11403 ping_time = atoi(v->value); 11404 else if (!strcasecmp(v->name, "iaxthreadcount")) { 11405 if (reload) { 11406 if (atoi(v->value) != iaxthreadcount) 11407 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 11408 } else { 11409 iaxthreadcount = atoi(v->value); 11410 if (iaxthreadcount < 1) { 11411 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 11412 iaxthreadcount = 1; 11413 } else if (iaxthreadcount > 256) { 11414 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 11415 iaxthreadcount = 256; 11416 } 11417 } 11418 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 11419 if (reload) { 11420 AST_LIST_LOCK(&dynamic_list); 11421 iaxmaxthreadcount = atoi(v->value); 11422 AST_LIST_UNLOCK(&dynamic_list); 11423 } else { 11424 iaxmaxthreadcount = atoi(v->value); 11425 if (iaxmaxthreadcount < 0) { 11426 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 11427 iaxmaxthreadcount = 0; 11428 } else if (iaxmaxthreadcount > 256) { 11429 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 11430 iaxmaxthreadcount = 256; 11431 } 11432 } 11433 } else if (!strcasecmp(v->name, "nochecksums")) { 11434 #ifdef SO_NO_CHECK 11435 if (ast_true(v->value)) 11436 nochecksums = 1; 11437 else 11438 nochecksums = 0; 11439 #else 11440 if (ast_true(v->value)) 11441 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 11442 #endif 11443 } 11444 else if (!strcasecmp(v->name, "maxjitterbuffer")) 11445 maxjitterbuffer = atoi(v->value); 11446 else if (!strcasecmp(v->name, "resyncthreshold")) 11447 resyncthreshold = atoi(v->value); 11448 else if (!strcasecmp(v->name, "maxjitterinterps")) 11449 maxjitterinterps = atoi(v->value); 11450 else if (!strcasecmp(v->name, "lagrqtime")) 11451 lagrq_time = atoi(v->value); 11452 else if (!strcasecmp(v->name, "maxregexpire")) 11453 max_reg_expire = atoi(v->value); 11454 else if (!strcasecmp(v->name, "minregexpire")) 11455 min_reg_expire = atoi(v->value); 11456 else if (!strcasecmp(v->name, "bindaddr")) { 11457 if (reload) { 11458 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 11459 } else { 11460 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 11461 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 11462 } else { 11463 if (option_verbose > 1) { 11464 if (strchr(v->value, ':')) 11465 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 11466 else 11467 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 11468 } 11469 if (defaultsockfd < 0) 11470 defaultsockfd = ast_netsock_sockfd(ns); 11471 ast_netsock_unref(ns); 11472 } 11473 } 11474 } else if (!strcasecmp(v->name, "authdebug")) 11475 authdebug = ast_true(v->value); 11476 else if (!strcasecmp(v->name, "encryption")) 11477 iax2_encryption = get_encrypt_methods(v->value); 11478 else if (!strcasecmp(v->name, "notransfer")) { 11479 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11480 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11481 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 11482 } else if (!strcasecmp(v->name, "transfer")) { 11483 if (!strcasecmp(v->value, "mediaonly")) { 11484 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11485 } else if (ast_true(v->value)) { 11486 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11487 } else 11488 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11489 } else if (!strcasecmp(v->name, "codecpriority")) { 11490 if(!strcasecmp(v->value, "caller")) 11491 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 11492 else if(!strcasecmp(v->value, "disabled")) 11493 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11494 else if(!strcasecmp(v->value, "reqonly")) { 11495 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 11496 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11497 } 11498 } else if (!strcasecmp(v->name, "jitterbuffer")) 11499 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 11500 else if (!strcasecmp(v->name, "forcejitterbuffer")) 11501 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 11502 else if (!strcasecmp(v->name, "delayreject")) 11503 delayreject = ast_true(v->value); 11504 else if (!strcasecmp(v->name, "allowfwdownload")) 11505 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 11506 else if (!strcasecmp(v->name, "rtcachefriends")) 11507 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 11508 else if (!strcasecmp(v->name, "rtignoreregexpire")) 11509 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 11510 else if (!strcasecmp(v->name, "rtupdate")) 11511 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 11512 else if (!strcasecmp(v->name, "trunktimestamps")) 11513 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 11514 else if (!strcasecmp(v->name, "rtautoclear")) { 11515 int i = atoi(v->value); 11516 if(i > 0) 11517 global_rtautoclear = i; 11518 else 11519 i = 0; 11520 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 11521 } else if (!strcasecmp(v->name, "trunkfreq")) { 11522 trunkfreq = atoi(v->value); 11523 if (trunkfreq < 10) 11524 trunkfreq = 10; 11525 } else if (!strcasecmp(v->name, "autokill")) { 11526 if (sscanf(v->value, "%30d", &x) == 1) { 11527 if (x >= 0) 11528 autokill = x; 11529 else 11530 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 11531 } else if (ast_true(v->value)) { 11532 autokill = DEFAULT_MAXMS; 11533 } else { 11534 autokill = 0; 11535 } 11536 } else if (!strcasecmp(v->name, "bandwidth")) { 11537 if (!strcasecmp(v->value, "low")) { 11538 capability = IAX_CAPABILITY_LOWBANDWIDTH; 11539 } else if (!strcasecmp(v->value, "medium")) { 11540 capability = IAX_CAPABILITY_MEDBANDWIDTH; 11541 } else if (!strcasecmp(v->value, "high")) { 11542 capability = IAX_CAPABILITY_FULLBANDWIDTH; 11543 } else 11544 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 11545 } else if (!strcasecmp(v->name, "allow")) { 11546 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 11547 } else if (!strcasecmp(v->name, "disallow")) { 11548 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 11549 } else if (!strcasecmp(v->name, "register")) { 11550 iax2_register(v->value, v->lineno); 11551 } else if (!strcasecmp(v->name, "iaxcompat")) { 11552 iaxcompat = ast_true(v->value); 11553 } else if (!strcasecmp(v->name, "regcontext")) { 11554 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 11555 /* Create context if it doesn't exist already */ 11556 if (!ast_context_find(regcontext)) 11557 ast_context_create(NULL, regcontext, "IAX2"); 11558 } else if (!strcasecmp(v->name, "tos")) { 11559 if (ast_str2tos(v->value, &tos)) 11560 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 11561 } else if (!strcasecmp(v->name, "accountcode")) { 11562 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 11563 } else if (!strcasecmp(v->name, "mohinterpret")) { 11564 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 11565 } else if (!strcasecmp(v->name, "mohsuggest")) { 11566 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 11567 } else if (!strcasecmp(v->name, "amaflags")) { 11568 format = ast_cdr_amaflags2int(v->value); 11569 if (format < 0) { 11570 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11571 } else { 11572 amaflags = format; 11573 } 11574 } else if (!strcasecmp(v->name, "language")) { 11575 ast_copy_string(language, v->value, sizeof(language)); 11576 } else if (!strcasecmp(v->name, "maxauthreq")) { 11577 maxauthreq = atoi(v->value); 11578 if (maxauthreq < 0) 11579 maxauthreq = 0; 11580 } else if (!strcasecmp(v->name, "adsi")) { 11581 adsi = ast_true(v->value); 11582 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11583 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 11584 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 11585 } 11586 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 11587 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 11588 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); 11589 } 11590 } else if (!strcasecmp(v->name, "calltokenoptional")) { 11591 if (add_calltoken_ignore(v->value)) { 11592 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 11593 } 11594 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 11595 if (ast_true(v->value)) { 11596 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 11597 } else if (ast_false(v->value)) { 11598 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID); 11599 } else { 11600 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 11601 } 11602 }/*else if (strcasecmp(v->name,"type")) */ 11603 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11604 v = v->next; 11605 } 11606 11607 if (defaultsockfd < 0) { 11608 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 11609 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 11610 } else { 11611 if (option_verbose > 1) 11612 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 11613 defaultsockfd = ast_netsock_sockfd(ns); 11614 ast_netsock_unref(ns); 11615 } 11616 } 11617 if (reload) { 11618 ast_netsock_release(outsock); 11619 outsock = ast_netsock_list_alloc(); 11620 if (!outsock) { 11621 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11622 return -1; 11623 } 11624 ast_netsock_init(outsock); 11625 } 11626 11627 if (min_reg_expire > max_reg_expire) { 11628 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 11629 min_reg_expire, max_reg_expire, max_reg_expire); 11630 min_reg_expire = max_reg_expire; 11631 } 11632 iax2_capability = capability; 11633 11634 ucfg = ast_config_load("users.conf"); 11635 if (ucfg) { 11636 struct ast_variable *gen; 11637 int genhasiax; 11638 int genregisteriax; 11639 const char *hasiax, *registeriax; 11640 11641 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 11642 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 11643 gen = ast_variable_browse(ucfg, "general"); 11644 cat = ast_category_browse(ucfg, NULL); 11645 while (cat) { 11646 if (strcasecmp(cat, "general")) { 11647 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 11648 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 11649 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 11650 /* Start with general parameters, then specific parameters, user and peer */ 11651 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 11652 if (user) { 11653 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11654 user = user_unref(user); 11655 } 11656 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 11657 if (peer) { 11658 if (ast_test_flag(peer, IAX_DYNAMIC)) 11659 reg_source_db(peer); 11660 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11661 peer = peer_unref(peer); 11662 } 11663 } 11664 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 11665 char tmp[256]; 11666 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 11667 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 11668 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 11669 if (!host) 11670 host = ast_variable_retrieve(ucfg, "general", "host"); 11671 if (!username) 11672 username = ast_variable_retrieve(ucfg, "general", "username"); 11673 if (!secret) 11674 secret = ast_variable_retrieve(ucfg, "general", "secret"); 11675 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 11676 if (!ast_strlen_zero(secret)) 11677 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 11678 else 11679 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 11680 iax2_register(tmp, 0); 11681 } 11682 } 11683 } 11684 cat = ast_category_browse(ucfg, cat); 11685 } 11686 ast_config_destroy(ucfg); 11687 } 11688 11689 cat = ast_category_browse(cfg, NULL); 11690 while(cat) { 11691 if (strcasecmp(cat, "general")) { 11692 utype = ast_variable_retrieve(cfg, cat, "type"); 11693 if (!strcasecmp(cat, "callnumberlimits")) { 11694 build_callno_limits(ast_variable_browse(cfg, cat)); 11695 } else if (utype) { 11696 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 11697 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 11698 if (user) { 11699 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11700 user = user_unref(user); 11701 } 11702 } 11703 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 11704 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 11705 if (peer) { 11706 if (ast_test_flag(peer, IAX_DYNAMIC)) 11707 reg_source_db(peer); 11708 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11709 peer = peer_unref(peer); 11710 } 11711 } else if (strcasecmp(utype, "user")) { 11712 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 11713 } 11714 } else 11715 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 11716 } 11717 cat = ast_category_browse(cfg, cat); 11718 } 11719 ast_config_destroy(cfg); 11720 set_timing(); 11721 return 1; 11722 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 11322 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, and IAX_USEJITTERBUF.
Referenced by set_config().
11323 { 11324 strcpy(accountcode, ""); 11325 strcpy(language, ""); 11326 strcpy(mohinterpret, "default"); 11327 strcpy(mohsuggest, ""); 11328 amaflags = 0; 11329 delayreject = 0; 11330 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 11331 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11332 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 11333 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 11334 delete_users(); 11335 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 11336 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 11337 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1886 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), callno_limits, addr_range::limit, peercnt::limit, LOG_DEBUG, option_debug, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
01887 { 01888 uint16_t limit = global_maxcallno; 01889 struct addr_range *addr_range; 01890 struct sockaddr_in sin = { 01891 .sin_addr.s_addr = peercnt->addr, 01892 }; 01893 01894 01895 if (peercnt->reg && peercnt->limit) { 01896 return; /* this peercnt has a custom limit set by a registration */ 01897 } 01898 01899 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 01900 limit = addr_range->limit; 01901 if (option_debug) { 01902 ast_log(LOG_DEBUG, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 01903 } 01904 ao2_ref(addr_range, -1); 01905 } 01906 01907 peercnt->limit = limit; 01908 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1914 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, option_debug, and set_peercnt_limit().
Referenced by reload_config().
01915 { 01916 struct peercnt *peercnt = obj; 01917 01918 set_peercnt_limit(peercnt); 01919 if (option_debug) { 01920 ast_log(LOG_DEBUG, "Reset limits for peercnts table\n"); 01921 } 01922 return 0; 01923 }
static void set_timing | ( | void | ) | [static] |
Definition at line 11307 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
11308 { 11309 #ifdef HAVE_DAHDI 11310 int bs = trunkfreq * 8; 11311 if (timingfd > -1) { 11312 if ( 11313 #ifdef DAHDI_TIMERACK 11314 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 11315 #endif 11316 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 11317 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 11318 } 11319 #endif 11320 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 861 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
Referenced by __schedule_action(), iax2_transmit(), and socket_read().
00862 { 00863 ast_mutex_lock(lock); 00864 ast_cond_signal(cond); 00865 ast_mutex_unlock(lock); 00866 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 8315 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, 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_device_state_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_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_trylock, 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_tvnow(), ast_tvzero(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), dpcache_lock, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), chan_iax2_pvt::first_iax_message, fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, 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_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, 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_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_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_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, iax_frame::list, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, ast_iax2_queue::queue, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax2_peer::smoothing, 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, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, 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().
08316 { 08317 struct sockaddr_in sin; 08318 int res; 08319 int updatehistory=1; 08320 int new = NEW_PREVENT; 08321 void *ptr; 08322 int dcallno = 0; 08323 char decrypted = 0; 08324 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 08325 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 08326 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 08327 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 08328 struct ast_iax2_meta_trunk_hdr *mth; 08329 struct ast_iax2_meta_trunk_entry *mte; 08330 struct ast_iax2_meta_trunk_mini *mtm; 08331 struct iax_frame *fr; 08332 struct iax_frame *cur; 08333 struct ast_frame f = { 0, }; 08334 struct ast_channel *c; 08335 struct iax2_dpcache *dp; 08336 struct iax2_peer *peer; 08337 struct iax2_trunk_peer *tpeer; 08338 struct timeval rxtrunktime; 08339 struct iax_ies ies; 08340 struct iax_ie_data ied0, ied1; 08341 int format; 08342 int fd; 08343 int exists; 08344 int minivid = 0; 08345 unsigned int ts; 08346 char empty[32]=""; /* Safety measure */ 08347 struct iax_frame *duped_fr; 08348 char host_pref_buf[128]; 08349 char caller_pref_buf[128]; 08350 struct ast_codec_pref pref; 08351 char *using_prefs = "mine"; 08352 08353 /* allocate an iax_frame with 4096 bytes of data buffer */ 08354 fr = alloca(sizeof(*fr) + 4096); 08355 memset(fr, 0, sizeof(*fr)); 08356 fr->afdatalen = 4096; /* From alloca() above */ 08357 08358 /* Copy frequently used parameters to the stack */ 08359 res = thread->buf_len; 08360 fd = thread->iofd; 08361 memcpy(&sin, &thread->iosin, sizeof(sin)); 08362 08363 if (res < sizeof(*mh)) { 08364 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 08365 return 1; 08366 } 08367 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 08368 if (res < sizeof(*vh)) { 08369 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)); 08370 return 1; 08371 } 08372 08373 /* This is a video frame, get call number */ 08374 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 08375 minivid = 1; 08376 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 08377 unsigned char metatype; 08378 08379 if (res < sizeof(*meta)) { 08380 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 08381 return 1; 08382 } 08383 08384 /* This is a meta header */ 08385 switch(meta->metacmd) { 08386 case IAX_META_TRUNK: 08387 if (res < (sizeof(*meta) + sizeof(*mth))) { 08388 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 08389 sizeof(*meta) + sizeof(*mth)); 08390 return 1; 08391 } 08392 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 08393 ts = ntohl(mth->ts); 08394 metatype = meta->cmddata; 08395 res -= (sizeof(*meta) + sizeof(*mth)); 08396 ptr = mth->data; 08397 tpeer = find_tpeer(&sin, fd); 08398 if (!tpeer) { 08399 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 08400 return 1; 08401 } 08402 tpeer->trunkact = ast_tvnow(); 08403 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 08404 tpeer->rxtrunktime = tpeer->trunkact; 08405 rxtrunktime = tpeer->rxtrunktime; 08406 ast_mutex_unlock(&tpeer->lock); 08407 while(res >= sizeof(*mte)) { 08408 /* Process channels */ 08409 unsigned short callno, trunked_ts, len; 08410 08411 if (metatype == IAX_META_TRUNK_MINI) { 08412 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 08413 ptr += sizeof(*mtm); 08414 res -= sizeof(*mtm); 08415 len = ntohs(mtm->len); 08416 callno = ntohs(mtm->mini.callno); 08417 trunked_ts = ntohs(mtm->mini.ts); 08418 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 08419 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 08420 ptr += sizeof(*mte); 08421 res -= sizeof(*mte); 08422 len = ntohs(mte->len); 08423 callno = ntohs(mte->callno); 08424 trunked_ts = 0; 08425 } else { 08426 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 08427 break; 08428 } 08429 /* Stop if we don't have enough data */ 08430 if (len > res) 08431 break; 08432 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 08433 if (fr->callno) { 08434 /* If it's a valid call, deliver the contents. If not, we 08435 drop it, since we don't have a scallno to use for an INVAL */ 08436 /* Process as a mini frame */ 08437 memset(&f, 0, sizeof(f)); 08438 f.frametype = AST_FRAME_VOICE; 08439 if (iaxs[fr->callno]) { 08440 if (iaxs[fr->callno]->voiceformat > 0) { 08441 f.subclass = iaxs[fr->callno]->voiceformat; 08442 f.datalen = len; 08443 if (f.datalen >= 0) { 08444 if (f.datalen) 08445 f.data = ptr; 08446 if(trunked_ts) { 08447 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 08448 } else 08449 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 08450 /* Don't pass any packets until we're started */ 08451 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08452 /* Common things */ 08453 f.src = "IAX2"; 08454 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 08455 f.samples = ast_codec_get_samples(&f); 08456 iax_frame_wrap(fr, &f); 08457 duped_fr = iaxfrdup2(fr); 08458 if (duped_fr) { 08459 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 08460 } 08461 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 08462 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08463 iaxs[fr->callno]->last = fr->ts; 08464 #if 1 08465 if (option_debug && iaxdebug) 08466 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08467 #endif 08468 } 08469 } 08470 } else { 08471 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08472 } 08473 } else { 08474 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 08475 iax2_vnak(fr->callno); 08476 } 08477 } 08478 ast_mutex_unlock(&iaxsl[fr->callno]); 08479 } 08480 ptr += len; 08481 res -= len; 08482 } 08483 08484 } 08485 return 1; 08486 } 08487 08488 #ifdef DEBUG_SUPPORT 08489 if (iaxdebug && (res >= sizeof(*fh))) 08490 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 08491 #endif 08492 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08493 if (res < sizeof(*fh)) { 08494 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)); 08495 return 1; 08496 } 08497 08498 /* Get the destination call number */ 08499 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 08500 08501 08502 /* check to make sure this full frame isn't encrypted before we attempt 08503 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 08504 * callno is not found here, that just means one hasn't been allocated for 08505 * this connection yet. */ 08506 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 08507 ast_mutex_lock(&iaxsl[fr->callno]); 08508 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 08509 if (decrypt_frame(fr->callno, fh, &f, &res)) { 08510 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 08511 ast_mutex_unlock(&iaxsl[fr->callno]); 08512 return 1; 08513 } 08514 decrypted = 1; 08515 } 08516 ast_mutex_unlock(&iaxsl[fr->callno]); 08517 } 08518 08519 /* Retrieve the type and subclass */ 08520 f.frametype = fh->type; 08521 if (f.frametype == AST_FRAME_VIDEO) { 08522 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 08523 } else { 08524 f.subclass = uncompress_subclass(fh->csub); 08525 } 08526 08527 /* Deal with POKE/PONG without allocating a callno */ 08528 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 08529 /* Reply back with a PONG, but don't care about the result. */ 08530 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08531 return 1; 08532 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 08533 /* Ignore */ 08534 return 1; 08535 } 08536 08537 f.datalen = res - sizeof(*fh); 08538 if (f.datalen) { 08539 if (f.frametype == AST_FRAME_IAX) { 08540 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 08541 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 08542 return 1; 08543 } 08544 f.data = NULL; 08545 f.datalen = 0; 08546 } else { 08547 f.data = thread->buf + sizeof(*fh); 08548 memset(&ies, 0, sizeof(ies)); 08549 } 08550 } else { 08551 if (f.frametype == AST_FRAME_IAX) 08552 f.data = NULL; 08553 else 08554 f.data = empty; 08555 memset(&ies, 0, sizeof(ies)); 08556 } 08557 08558 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 08559 /* only set NEW_ALLOW if calltoken checks out */ 08560 if (handle_call_token(fh, &ies, &sin, fd)) { 08561 return 1; 08562 } 08563 08564 if (ies.calltoken && ies.calltokendata) { 08565 /* if we've gotten this far, and the calltoken ie data exists, 08566 * then calltoken validation _MUST_ have taken place. If calltoken 08567 * data is provided, it is always validated reguardless of any 08568 * calltokenoptional or requirecalltoken options */ 08569 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 08570 } else { 08571 new = NEW_ALLOW; 08572 } 08573 } 08574 } else { 08575 /* Don't know anything about it yet */ 08576 f.frametype = AST_FRAME_NULL; 08577 f.subclass = 0; 08578 } 08579 08580 if (!fr->callno) { 08581 int check_dcallno = 0; 08582 08583 /* 08584 * We enforce accurate destination call numbers for ACKs. This forces the other 08585 * end to know the destination call number before call setup can complete. 08586 * 08587 * Discussed in the following thread: 08588 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 08589 */ 08590 08591 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) { 08592 check_dcallno = 1; 08593 } 08594 08595 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 08596 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 08597 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08598 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 08599 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08600 } 08601 return 1; 08602 } 08603 } 08604 08605 if (fr->callno > 0) 08606 ast_mutex_lock(&iaxsl[fr->callno]); 08607 08608 if (!fr->callno || !iaxs[fr->callno]) { 08609 /* A call arrived for a nonexistent destination. Unless it's an "inval" 08610 frame, reply with an inval */ 08611 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08612 /* We can only raw hangup control frames */ 08613 if (((f.subclass != IAX_COMMAND_INVAL) && 08614 (f.subclass != IAX_COMMAND_TXCNT) && 08615 (f.subclass != IAX_COMMAND_TXACC) && 08616 (f.subclass != IAX_COMMAND_FWDOWNL))|| 08617 (f.frametype != AST_FRAME_IAX)) 08618 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 08619 fd); 08620 } 08621 if (fr->callno > 0) 08622 ast_mutex_unlock(&iaxsl[fr->callno]); 08623 return 1; 08624 } 08625 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 08626 if (decrypt_frame(fr->callno, fh, &f, &res)) { 08627 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 08628 ast_mutex_unlock(&iaxsl[fr->callno]); 08629 return 1; 08630 } 08631 decrypted = 1; 08632 } 08633 #ifdef DEBUG_SUPPORT 08634 if (decrypted && iaxdebug) { 08635 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 08636 } 08637 #endif 08638 08639 /* count this frame */ 08640 iaxs[fr->callno]->frames_received++; 08641 08642 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 08643 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 08644 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 08645 unsigned short new_peercallno; 08646 08647 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 08648 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 08649 if (iaxs[fr->callno]->peercallno) { 08650 remove_by_peercallno(iaxs[fr->callno]); 08651 } 08652 iaxs[fr->callno]->peercallno = new_peercallno; 08653 store_by_peercallno(iaxs[fr->callno]); 08654 } 08655 } 08656 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08657 if (option_debug && iaxdebug) 08658 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 08659 /* Check if it's out of order (and not an ACK or INVAL) */ 08660 fr->oseqno = fh->oseqno; 08661 fr->iseqno = fh->iseqno; 08662 fr->ts = ntohl(fh->ts); 08663 #ifdef IAXTESTS 08664 if (test_resync) { 08665 if (option_debug) 08666 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 08667 fr->ts += test_resync; 08668 } 08669 #endif /* IAXTESTS */ 08670 #if 0 08671 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 08672 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 08673 (f.subclass == IAX_COMMAND_NEW || 08674 f.subclass == IAX_COMMAND_AUTHREQ || 08675 f.subclass == IAX_COMMAND_ACCEPT || 08676 f.subclass == IAX_COMMAND_REJECT)) ) ) 08677 #endif 08678 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 08679 updatehistory = 0; 08680 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 08681 (iaxs[fr->callno]->iseqno || 08682 ((f.subclass != IAX_COMMAND_TXCNT) && 08683 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08684 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08685 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08686 (f.subclass != IAX_COMMAND_TXACC)) || 08687 (f.frametype != AST_FRAME_IAX))) { 08688 if ( 08689 ((f.subclass != IAX_COMMAND_ACK) && 08690 (f.subclass != IAX_COMMAND_INVAL) && 08691 (f.subclass != IAX_COMMAND_TXCNT) && 08692 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08693 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08694 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08695 (f.subclass != IAX_COMMAND_TXACC) && 08696 (f.subclass != IAX_COMMAND_VNAK)) || 08697 (f.frametype != AST_FRAME_IAX)) { 08698 /* If it's not an ACK packet, it's out of order. */ 08699 if (option_debug) 08700 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 08701 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 08702 /* Check to see if we need to request retransmission, 08703 * and take sequence number wraparound into account */ 08704 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 08705 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 08706 if ((f.frametype != AST_FRAME_IAX) || 08707 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 08708 if (option_debug) 08709 ast_log(LOG_DEBUG, "Acking anyway\n"); 08710 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 08711 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 08712 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08713 } 08714 } else { 08715 /* Send a VNAK requesting retransmission */ 08716 iax2_vnak(fr->callno); 08717 } 08718 ast_mutex_unlock(&iaxsl[fr->callno]); 08719 return 1; 08720 } 08721 } else { 08722 /* Increment unless it's an ACK or VNAK */ 08723 if (((f.subclass != IAX_COMMAND_ACK) && 08724 (f.subclass != IAX_COMMAND_INVAL) && 08725 (f.subclass != IAX_COMMAND_TXCNT) && 08726 (f.subclass != IAX_COMMAND_TXACC) && 08727 (f.subclass != IAX_COMMAND_VNAK)) || 08728 (f.frametype != AST_FRAME_IAX)) 08729 iaxs[fr->callno]->iseqno++; 08730 } 08731 /* Ensure text frames are NULL-terminated */ 08732 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 08733 if (res < thread->buf_size) 08734 thread->buf[res++] = '\0'; 08735 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 08736 thread->buf[res - 1] = '\0'; 08737 } 08738 08739 /* Handle implicit ACKing unless this is an INVAL, and only if this is 08740 from the real peer, not the transfer peer */ 08741 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08742 ((f.subclass != IAX_COMMAND_INVAL) || 08743 (f.frametype != AST_FRAME_IAX))) { 08744 unsigned char x; 08745 int call_to_destroy; 08746 /* XXX This code is not very efficient. Surely there is a better way which still 08747 properly handles boundary conditions? XXX */ 08748 /* First we have to qualify that the ACKed value is within our window */ 08749 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 08750 if (fr->iseqno == x) 08751 break; 08752 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 08753 /* The acknowledgement is within our window. Time to acknowledge everything 08754 that it says to */ 08755 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 08756 /* Ack the packet with the given timestamp */ 08757 if (option_debug && iaxdebug) 08758 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 08759 call_to_destroy = 0; 08760 AST_LIST_LOCK(&iaxq.queue); 08761 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08762 /* If it's our call, and our timestamp, mark -1 retries */ 08763 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 08764 cur->retries = -1; 08765 /* Destroy call if this is the end */ 08766 if (cur->final) 08767 call_to_destroy = fr->callno; 08768 } 08769 } 08770 AST_LIST_UNLOCK(&iaxq.queue); 08771 if (call_to_destroy) { 08772 if (iaxdebug && option_debug) 08773 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 08774 ast_mutex_lock(&iaxsl[call_to_destroy]); 08775 iax2_destroy(call_to_destroy); 08776 ast_mutex_unlock(&iaxsl[call_to_destroy]); 08777 } 08778 } 08779 /* Note how much we've received acknowledgement for */ 08780 if (iaxs[fr->callno]) 08781 iaxs[fr->callno]->rseqno = fr->iseqno; 08782 else { 08783 /* Stop processing now */ 08784 ast_mutex_unlock(&iaxsl[fr->callno]); 08785 return 1; 08786 } 08787 } else if (option_debug) 08788 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 08789 } 08790 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08791 ((f.frametype != AST_FRAME_IAX) || 08792 ((f.subclass != IAX_COMMAND_TXACC) && 08793 (f.subclass != IAX_COMMAND_TXCNT)))) { 08794 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 08795 ast_mutex_unlock(&iaxsl[fr->callno]); 08796 return 1; 08797 } 08798 08799 /* when we receive the first full frame for a new incoming channel, 08800 it is safe to start the PBX on the channel because we have now 08801 completed a 3-way handshake with the peer */ 08802 if ((f.frametype == AST_FRAME_VOICE) || 08803 (f.frametype == AST_FRAME_VIDEO) || 08804 (f.frametype == AST_FRAME_IAX)) { 08805 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 08806 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 08807 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 08808 ast_mutex_unlock(&iaxsl[fr->callno]); 08809 return 1; 08810 } 08811 } 08812 } 08813 08814 /* once we receive our first IAX Full Frame that is not CallToken related, send all 08815 * queued signaling frames that were being held. */ 08816 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 08817 send_signaling(iaxs[fr->callno]); 08818 } 08819 08820 if (f.frametype == AST_FRAME_VOICE) { 08821 if (f.subclass != iaxs[fr->callno]->voiceformat) { 08822 iaxs[fr->callno]->voiceformat = f.subclass; 08823 if (option_debug) 08824 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 08825 if (iaxs[fr->callno]->owner) { 08826 int orignative; 08827 retryowner: 08828 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 08829 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 08830 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 08831 } 08832 if (iaxs[fr->callno]) { 08833 if (iaxs[fr->callno]->owner) { 08834 orignative = iaxs[fr->callno]->owner->nativeformats; 08835 iaxs[fr->callno]->owner->nativeformats = f.subclass; 08836 if (iaxs[fr->callno]->owner->readformat) 08837 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08838 iaxs[fr->callno]->owner->nativeformats = orignative; 08839 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08840 } 08841 } else { 08842 if (option_debug) 08843 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 08844 ast_mutex_unlock(&iaxsl[fr->callno]); 08845 return 1; 08846 } 08847 } 08848 } 08849 } 08850 if (f.frametype == AST_FRAME_VIDEO) { 08851 if (f.subclass != iaxs[fr->callno]->videoformat) { 08852 if (option_debug) 08853 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 08854 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 08855 } 08856 } 08857 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 08858 if (f.subclass == AST_CONTROL_BUSY) { 08859 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 08860 } else if (f.subclass == AST_CONTROL_CONGESTION) { 08861 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 08862 } 08863 } 08864 if (f.frametype == AST_FRAME_IAX) { 08865 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 08866 /* Handle the IAX pseudo frame itself */ 08867 if (option_debug && iaxdebug) { 08868 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 08869 } 08870 08871 /* Update last ts unless the frame's timestamp originated with us. */ 08872 if (iaxs[fr->callno]->last < fr->ts && 08873 f.subclass != IAX_COMMAND_ACK && 08874 f.subclass != IAX_COMMAND_PONG && 08875 f.subclass != IAX_COMMAND_LAGRP) { 08876 iaxs[fr->callno]->last = fr->ts; 08877 if (option_debug && iaxdebug) { 08878 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08879 } 08880 } 08881 iaxs[fr->callno]->last_iax_message = f.subclass; 08882 if (!iaxs[fr->callno]->first_iax_message) { 08883 iaxs[fr->callno]->first_iax_message = f.subclass; 08884 } 08885 switch(f.subclass) { 08886 case IAX_COMMAND_ACK: 08887 /* Do nothing */ 08888 break; 08889 case IAX_COMMAND_QUELCH: 08890 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08891 /* Generate Manager Hold event, if necessary*/ 08892 if (iaxs[fr->callno]->owner) { 08893 manager_event(EVENT_FLAG_CALL, "Hold", 08894 "Channel: %s\r\n" 08895 "Uniqueid: %s\r\n", 08896 iaxs[fr->callno]->owner->name, 08897 iaxs[fr->callno]->owner->uniqueid); 08898 } 08899 08900 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 08901 if (ies.musiconhold) { 08902 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 08903 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 08904 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 08905 S_OR(mohsuggest, NULL), 08906 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 08907 if (!iaxs[fr->callno]) { 08908 ast_mutex_unlock(&iaxsl[fr->callno]); 08909 return 1; 08910 } 08911 } 08912 } 08913 } 08914 break; 08915 case IAX_COMMAND_UNQUELCH: 08916 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08917 /* Generate Manager Unhold event, if necessary*/ 08918 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 08919 manager_event(EVENT_FLAG_CALL, "Unhold", 08920 "Channel: %s\r\n" 08921 "Uniqueid: %s\r\n", 08922 iaxs[fr->callno]->owner->name, 08923 iaxs[fr->callno]->owner->uniqueid); 08924 } 08925 08926 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 08927 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 08928 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 08929 if (!iaxs[fr->callno]) { 08930 ast_mutex_unlock(&iaxsl[fr->callno]); 08931 return 1; 08932 } 08933 } 08934 } 08935 break; 08936 case IAX_COMMAND_TXACC: 08937 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 08938 /* Ack the packet with the given timestamp */ 08939 AST_LIST_LOCK(&iaxq.queue); 08940 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08941 /* Cancel any outstanding txcnt's */ 08942 if ((fr->callno == cur->callno) && (cur->transfer)) 08943 cur->retries = -1; 08944 } 08945 AST_LIST_UNLOCK(&iaxq.queue); 08946 memset(&ied1, 0, sizeof(ied1)); 08947 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 08948 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 08949 iaxs[fr->callno]->transferring = TRANSFER_READY; 08950 } 08951 break; 08952 case IAX_COMMAND_NEW: 08953 /* Ignore if it's already up */ 08954 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 08955 break; 08956 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08957 ast_mutex_unlock(&iaxsl[fr->callno]); 08958 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08959 ast_mutex_lock(&iaxsl[fr->callno]); 08960 if (!iaxs[fr->callno]) { 08961 ast_mutex_unlock(&iaxsl[fr->callno]); 08962 return 1; 08963 } 08964 } 08965 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 08966 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 08967 int new_callno; 08968 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 08969 fr->callno = new_callno; 08970 } 08971 /* For security, always ack immediately */ 08972 if (delayreject) 08973 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08974 if (check_access(fr->callno, &sin, &ies)) { 08975 /* They're not allowed on */ 08976 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08977 if (authdebug) 08978 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); 08979 break; 08980 } 08981 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08982 const char *context, *exten, *cid_num; 08983 08984 context = ast_strdupa(iaxs[fr->callno]->context); 08985 exten = ast_strdupa(iaxs[fr->callno]->exten); 08986 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 08987 08988 /* This might re-enter the IAX code and need the lock */ 08989 ast_mutex_unlock(&iaxsl[fr->callno]); 08990 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 08991 ast_mutex_lock(&iaxsl[fr->callno]); 08992 08993 if (!iaxs[fr->callno]) { 08994 ast_mutex_unlock(&iaxsl[fr->callno]); 08995 return 1; 08996 } 08997 } else 08998 exists = 0; 08999 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 09000 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09001 memset(&ied0, 0, sizeof(ied0)); 09002 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09003 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09004 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09005 if (!iaxs[fr->callno]) { 09006 ast_mutex_unlock(&iaxsl[fr->callno]); 09007 return 1; 09008 } 09009 if (authdebug) 09010 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); 09011 } else { 09012 /* Select an appropriate format */ 09013 09014 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09015 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09016 using_prefs = "reqonly"; 09017 } else { 09018 using_prefs = "disabled"; 09019 } 09020 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09021 memset(&pref, 0, sizeof(pref)); 09022 strcpy(caller_pref_buf, "disabled"); 09023 strcpy(host_pref_buf, "disabled"); 09024 } else { 09025 using_prefs = "mine"; 09026 /* If the information elements are in here... use them */ 09027 if (ies.codec_prefs) 09028 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09029 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09030 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 09031 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09032 pref = iaxs[fr->callno]->rprefs; 09033 using_prefs = "caller"; 09034 } else { 09035 pref = iaxs[fr->callno]->prefs; 09036 } 09037 } else 09038 pref = iaxs[fr->callno]->prefs; 09039 09040 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09041 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09042 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09043 } 09044 if (!format) { 09045 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09046 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09047 if (!format) { 09048 memset(&ied0, 0, sizeof(ied0)); 09049 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09050 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09051 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09052 if (!iaxs[fr->callno]) { 09053 ast_mutex_unlock(&iaxsl[fr->callno]); 09054 return 1; 09055 } 09056 if (authdebug) { 09057 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09058 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); 09059 else 09060 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); 09061 } 09062 } else { 09063 /* Pick one... */ 09064 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09065 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09066 format = 0; 09067 } else { 09068 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09069 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09070 memset(&pref, 0, sizeof(pref)); 09071 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09072 strcpy(caller_pref_buf,"disabled"); 09073 strcpy(host_pref_buf,"disabled"); 09074 } else { 09075 using_prefs = "mine"; 09076 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09077 /* Do the opposite of what we tried above. */ 09078 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09079 pref = iaxs[fr->callno]->prefs; 09080 } else { 09081 pref = iaxs[fr->callno]->rprefs; 09082 using_prefs = "caller"; 09083 } 09084 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 09085 09086 } else /* if no codec_prefs IE do it the old way */ 09087 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09088 } 09089 } 09090 09091 if (!format) { 09092 memset(&ied0, 0, sizeof(ied0)); 09093 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09094 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09095 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09096 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09097 if (!iaxs[fr->callno]) { 09098 ast_mutex_unlock(&iaxsl[fr->callno]); 09099 return 1; 09100 } 09101 if (authdebug) 09102 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); 09103 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09104 break; 09105 } 09106 } 09107 } 09108 if (format) { 09109 /* No authentication required, let them in */ 09110 memset(&ied1, 0, sizeof(ied1)); 09111 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09112 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09113 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09114 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09115 if (option_verbose > 2) 09116 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 09117 "%srequested format = %s,\n" 09118 "%srequested prefs = %s,\n" 09119 "%sactual format = %s,\n" 09120 "%shost prefs = %s,\n" 09121 "%spriority = %s\n", 09122 ast_inet_ntoa(sin.sin_addr), 09123 VERBOSE_PREFIX_4, 09124 ast_getformatname(iaxs[fr->callno]->peerformat), 09125 VERBOSE_PREFIX_4, 09126 caller_pref_buf, 09127 VERBOSE_PREFIX_4, 09128 ast_getformatname(format), 09129 VERBOSE_PREFIX_4, 09130 host_pref_buf, 09131 VERBOSE_PREFIX_4, 09132 using_prefs); 09133 09134 iaxs[fr->callno]->chosenformat = format; 09135 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09136 } else { 09137 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09138 /* If this is a TBD call, we're ready but now what... */ 09139 if (option_verbose > 2) 09140 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09141 } 09142 } 09143 } 09144 break; 09145 } 09146 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 09147 merge_encryption(iaxs[fr->callno],ies.encmethods); 09148 else 09149 iaxs[fr->callno]->encmethods = 0; 09150 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 09151 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 09152 if (!iaxs[fr->callno]) { 09153 ast_mutex_unlock(&iaxsl[fr->callno]); 09154 return 1; 09155 } 09156 break; 09157 case IAX_COMMAND_DPREQ: 09158 /* Request status in the dialplan */ 09159 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 09160 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 09161 if (iaxcompat) { 09162 /* Spawn a thread for the lookup */ 09163 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 09164 } else { 09165 /* Just look it up */ 09166 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 09167 } 09168 } 09169 break; 09170 case IAX_COMMAND_HANGUP: 09171 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09172 if (option_debug) 09173 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 09174 /* Set hangup cause according to remote */ 09175 if (ies.causecode && iaxs[fr->callno]->owner) 09176 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09177 /* Send ack immediately, before we destroy */ 09178 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09179 iax2_destroy(fr->callno); 09180 break; 09181 case IAX_COMMAND_REJECT: 09182 /* Set hangup cause according to remote */ 09183 if (ies.causecode && iaxs[fr->callno]->owner) 09184 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09185 09186 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09187 if (iaxs[fr->callno]->owner && authdebug) 09188 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 09189 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 09190 ies.cause ? ies.cause : "<Unknown>"); 09191 if (option_debug) 09192 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 09193 fr->callno); 09194 } 09195 /* Send ack immediately, before we destroy */ 09196 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 09197 fr->ts, NULL, 0, fr->iseqno); 09198 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 09199 iaxs[fr->callno]->error = EPERM; 09200 iax2_destroy(fr->callno); 09201 break; 09202 case IAX_COMMAND_TRANSFER: 09203 { 09204 struct ast_channel *bridged_chan; 09205 09206 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 09207 /* Set BLINDTRANSFER channel variables */ 09208 09209 ast_mutex_unlock(&iaxsl[fr->callno]); 09210 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 09211 ast_mutex_lock(&iaxsl[fr->callno]); 09212 if (!iaxs[fr->callno]) { 09213 ast_mutex_unlock(&iaxsl[fr->callno]); 09214 return 1; 09215 } 09216 09217 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 09218 if (!strcmp(ies.called_number, ast_parking_ext())) { 09219 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 09220 ast_mutex_unlock(&iaxsl[fr->callno]); 09221 if (iax_park(bridged_chan, saved_channel)) { 09222 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 09223 } else { 09224 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 09225 } 09226 ast_mutex_lock(&iaxsl[fr->callno]); 09227 } else { 09228 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 09229 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 09230 ies.called_number, iaxs[fr->callno]->context); 09231 else 09232 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 09233 ies.called_number, iaxs[fr->callno]->context); 09234 } 09235 } else 09236 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 09237 09238 break; 09239 } 09240 case IAX_COMMAND_ACCEPT: 09241 /* Ignore if call is already up or needs authentication or is a TBD */ 09242 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 09243 break; 09244 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09245 /* Send ack immediately, before we destroy */ 09246 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09247 iax2_destroy(fr->callno); 09248 break; 09249 } 09250 if (ies.format) { 09251 iaxs[fr->callno]->peerformat = ies.format; 09252 } else { 09253 if (iaxs[fr->callno]->owner) 09254 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 09255 else 09256 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 09257 } 09258 if (option_verbose > 2) 09259 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); 09260 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 09261 memset(&ied0, 0, sizeof(ied0)); 09262 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09263 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09264 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09265 if (!iaxs[fr->callno]) { 09266 ast_mutex_unlock(&iaxsl[fr->callno]); 09267 return 1; 09268 } 09269 if (authdebug) 09270 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); 09271 } else { 09272 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09273 if (iaxs[fr->callno]->owner) { 09274 /* Switch us to use a compatible format */ 09275 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 09276 if (option_verbose > 2) 09277 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 09278 retryowner2: 09279 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 09280 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 09281 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 09282 } 09283 09284 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 09285 /* Setup read/write formats properly. */ 09286 if (iaxs[fr->callno]->owner->writeformat) 09287 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 09288 if (iaxs[fr->callno]->owner->readformat) 09289 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09290 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 09291 } 09292 } 09293 } 09294 if (iaxs[fr->callno]) { 09295 ast_mutex_lock(&dpcache_lock); 09296 dp = iaxs[fr->callno]->dpentries; 09297 while(dp) { 09298 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 09299 iax2_dprequest(dp, fr->callno); 09300 } 09301 dp = dp->peer; 09302 } 09303 ast_mutex_unlock(&dpcache_lock); 09304 } 09305 break; 09306 case IAX_COMMAND_POKE: 09307 /* Send back a pong packet with the original timestamp */ 09308 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 09309 if (!iaxs[fr->callno]) { 09310 ast_mutex_unlock(&iaxsl[fr->callno]); 09311 return 1; 09312 } 09313 break; 09314 case IAX_COMMAND_PING: 09315 { 09316 struct iax_ie_data pingied; 09317 construct_rr(iaxs[fr->callno], &pingied); 09318 /* Send back a pong packet with the original timestamp */ 09319 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 09320 } 09321 break; 09322 case IAX_COMMAND_PONG: 09323 /* Calculate ping time */ 09324 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 09325 /* save RR info */ 09326 save_rr(fr, &ies); 09327 09328 if (iaxs[fr->callno]->peerpoke) { 09329 peer = iaxs[fr->callno]->peerpoke; 09330 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 09331 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 09332 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 09333 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09334 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09335 } 09336 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 09337 if (iaxs[fr->callno]->pingtime > peer->maxms) { 09338 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 09339 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09340 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09341 } 09342 } 09343 peer->lastms = iaxs[fr->callno]->pingtime; 09344 if (peer->smoothing && (peer->lastms > -1)) 09345 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 09346 else if (peer->smoothing && peer->lastms < 0) 09347 peer->historicms = (0 + peer->historicms) / 2; 09348 else 09349 peer->historicms = iaxs[fr->callno]->pingtime; 09350 09351 /* Remove scheduled iax2_poke_noanswer */ 09352 if (peer->pokeexpire > -1) { 09353 if (!ast_sched_del(sched, peer->pokeexpire)) { 09354 peer_unref(peer); 09355 peer->pokeexpire = -1; 09356 } 09357 } 09358 /* Schedule the next cycle */ 09359 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 09360 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 09361 else 09362 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 09363 if (peer->pokeexpire == -1) 09364 peer_unref(peer); 09365 /* and finally send the ack */ 09366 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09367 /* And wrap up the qualify call */ 09368 iax2_destroy(fr->callno); 09369 peer->callno = 0; 09370 if (option_debug) 09371 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 09372 } 09373 break; 09374 case IAX_COMMAND_LAGRQ: 09375 case IAX_COMMAND_LAGRP: 09376 f.src = "LAGRQ"; 09377 f.mallocd = 0; 09378 f.offset = 0; 09379 f.samples = 0; 09380 iax_frame_wrap(fr, &f); 09381 if(f.subclass == IAX_COMMAND_LAGRQ) { 09382 /* Received a LAGRQ - echo back a LAGRP */ 09383 fr->af.subclass = IAX_COMMAND_LAGRP; 09384 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 09385 } else { 09386 /* Received LAGRP in response to our LAGRQ */ 09387 unsigned int ts; 09388 /* This is a reply we've been given, actually measure the difference */ 09389 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 09390 iaxs[fr->callno]->lag = ts - fr->ts; 09391 if (option_debug && iaxdebug) 09392 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 09393 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 09394 } 09395 break; 09396 case IAX_COMMAND_AUTHREQ: 09397 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09398 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>"); 09399 break; 09400 } 09401 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 09402 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 09403 .subclass = AST_CONTROL_HANGUP, 09404 }; 09405 ast_log(LOG_WARNING, 09406 "I don't know how to authenticate %s to %s\n", 09407 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 09408 iax2_queue_frame(fr->callno, &hangup_fr); 09409 } 09410 if (!iaxs[fr->callno]) { 09411 ast_mutex_unlock(&iaxsl[fr->callno]); 09412 return 1; 09413 } 09414 break; 09415 case IAX_COMMAND_AUTHREP: 09416 /* For security, always ack immediately */ 09417 if (delayreject) 09418 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09419 /* Ignore once we've started */ 09420 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09421 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>"); 09422 break; 09423 } 09424 if (authenticate_verify(iaxs[fr->callno], &ies)) { 09425 if (authdebug) 09426 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); 09427 memset(&ied0, 0, sizeof(ied0)); 09428 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09429 break; 09430 } 09431 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09432 /* This might re-enter the IAX code and need the lock */ 09433 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 09434 } else 09435 exists = 0; 09436 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09437 if (authdebug) 09438 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); 09439 memset(&ied0, 0, sizeof(ied0)); 09440 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09441 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09442 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09443 if (!iaxs[fr->callno]) { 09444 ast_mutex_unlock(&iaxsl[fr->callno]); 09445 return 1; 09446 } 09447 } else { 09448 /* Select an appropriate format */ 09449 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09450 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09451 using_prefs = "reqonly"; 09452 } else { 09453 using_prefs = "disabled"; 09454 } 09455 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09456 memset(&pref, 0, sizeof(pref)); 09457 strcpy(caller_pref_buf, "disabled"); 09458 strcpy(host_pref_buf, "disabled"); 09459 } else { 09460 using_prefs = "mine"; 09461 if (ies.codec_prefs) 09462 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09463 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09464 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09465 pref = iaxs[fr->callno]->rprefs; 09466 using_prefs = "caller"; 09467 } else { 09468 pref = iaxs[fr->callno]->prefs; 09469 } 09470 } else /* if no codec_prefs IE do it the old way */ 09471 pref = iaxs[fr->callno]->prefs; 09472 09473 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09474 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09475 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09476 } 09477 if (!format) { 09478 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09479 if (option_debug) 09480 ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability); 09481 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09482 } 09483 if (!format) { 09484 if (authdebug) { 09485 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09486 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); 09487 else 09488 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); 09489 } 09490 memset(&ied0, 0, sizeof(ied0)); 09491 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09492 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09493 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09494 if (!iaxs[fr->callno]) { 09495 ast_mutex_unlock(&iaxsl[fr->callno]); 09496 return 1; 09497 } 09498 } else { 09499 /* Pick one... */ 09500 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09501 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09502 format = 0; 09503 } else { 09504 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09505 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09506 memset(&pref, 0, sizeof(pref)); 09507 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 09508 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09509 strcpy(caller_pref_buf,"disabled"); 09510 strcpy(host_pref_buf,"disabled"); 09511 } else { 09512 using_prefs = "mine"; 09513 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09514 /* Do the opposite of what we tried above. */ 09515 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09516 pref = iaxs[fr->callno]->prefs; 09517 } else { 09518 pref = iaxs[fr->callno]->rprefs; 09519 using_prefs = "caller"; 09520 } 09521 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 09522 } else /* if no codec_prefs IE do it the old way */ 09523 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09524 } 09525 } 09526 if (!format) { 09527 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09528 if (authdebug) { 09529 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09530 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); 09531 else 09532 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); 09533 } 09534 memset(&ied0, 0, sizeof(ied0)); 09535 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09536 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09537 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09538 if (!iaxs[fr->callno]) { 09539 ast_mutex_unlock(&iaxsl[fr->callno]); 09540 return 1; 09541 } 09542 } 09543 } 09544 } 09545 if (format) { 09546 /* Authentication received */ 09547 memset(&ied1, 0, sizeof(ied1)); 09548 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09549 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09550 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09551 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09552 if (option_verbose > 2) 09553 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 09554 "%srequested format = %s,\n" 09555 "%srequested prefs = %s,\n" 09556 "%sactual format = %s,\n" 09557 "%shost prefs = %s,\n" 09558 "%spriority = %s\n", 09559 ast_inet_ntoa(sin.sin_addr), 09560 VERBOSE_PREFIX_4, 09561 ast_getformatname(iaxs[fr->callno]->peerformat), 09562 VERBOSE_PREFIX_4, 09563 caller_pref_buf, 09564 VERBOSE_PREFIX_4, 09565 ast_getformatname(format), 09566 VERBOSE_PREFIX_4, 09567 host_pref_buf, 09568 VERBOSE_PREFIX_4, 09569 using_prefs); 09570 09571 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09572 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 09573 iax2_destroy(fr->callno); 09574 } else { 09575 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09576 /* If this is a TBD call, we're ready but now what... */ 09577 if (option_verbose > 2) 09578 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09579 } 09580 } 09581 } 09582 break; 09583 case IAX_COMMAND_DIAL: 09584 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 09585 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09586 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 09587 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 09588 if (authdebug) 09589 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); 09590 memset(&ied0, 0, sizeof(ied0)); 09591 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09592 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09593 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09594 if (!iaxs[fr->callno]) { 09595 ast_mutex_unlock(&iaxsl[fr->callno]); 09596 return 1; 09597 } 09598 } else { 09599 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09600 if (option_verbose > 2) 09601 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 09602 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09603 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 09604 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 09605 iax2_destroy(fr->callno); 09606 } 09607 } 09608 break; 09609 case IAX_COMMAND_INVAL: 09610 iaxs[fr->callno]->error = ENOTCONN; 09611 if (option_debug) 09612 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 09613 iax2_destroy(fr->callno); 09614 if (option_debug) 09615 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 09616 break; 09617 case IAX_COMMAND_VNAK: 09618 if (option_debug) 09619 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 09620 /* Force retransmission */ 09621 vnak_retransmit(fr->callno, fr->iseqno); 09622 break; 09623 case IAX_COMMAND_REGREQ: 09624 case IAX_COMMAND_REGREL: 09625 /* For security, always ack immediately */ 09626 if (delayreject) 09627 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09628 if (register_verify(fr->callno, &sin, &ies)) { 09629 if (!iaxs[fr->callno]) { 09630 ast_mutex_unlock(&iaxsl[fr->callno]); 09631 return 1; 09632 } 09633 /* Send delayed failure */ 09634 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 09635 break; 09636 } 09637 if (!iaxs[fr->callno]) { 09638 ast_mutex_unlock(&iaxsl[fr->callno]); 09639 return 1; 09640 } 09641 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 09642 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 09643 09644 if (f.subclass == IAX_COMMAND_REGREL) 09645 memset(&sin, 0, sizeof(sin)); 09646 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 09647 ast_log(LOG_WARNING, "Registry error\n"); 09648 if (!iaxs[fr->callno]) { 09649 ast_mutex_unlock(&iaxsl[fr->callno]); 09650 return 1; 09651 } 09652 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09653 ast_mutex_unlock(&iaxsl[fr->callno]); 09654 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09655 ast_mutex_lock(&iaxsl[fr->callno]); 09656 if (!iaxs[fr->callno]) { 09657 ast_mutex_unlock(&iaxsl[fr->callno]); 09658 return 1; 09659 } 09660 } 09661 break; 09662 } 09663 registry_authrequest(fr->callno); 09664 if (!iaxs[fr->callno]) { 09665 ast_mutex_unlock(&iaxsl[fr->callno]); 09666 return 1; 09667 } 09668 break; 09669 case IAX_COMMAND_REGACK: 09670 if (iax2_ack_registry(&ies, &sin, fr->callno)) 09671 ast_log(LOG_WARNING, "Registration failure\n"); 09672 /* Send ack immediately, before we destroy */ 09673 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09674 iax2_destroy(fr->callno); 09675 break; 09676 case IAX_COMMAND_REGREJ: 09677 if (iaxs[fr->callno]->reg) { 09678 if (authdebug) { 09679 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)); 09680 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 09681 } 09682 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 09683 } 09684 /* Send ack immediately, before we destroy */ 09685 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09686 iax2_destroy(fr->callno); 09687 break; 09688 case IAX_COMMAND_REGAUTH: 09689 /* Authentication request */ 09690 if (registry_rerequest(&ies, fr->callno, &sin)) { 09691 memset(&ied0, 0, sizeof(ied0)); 09692 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 09693 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09694 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09695 if (!iaxs[fr->callno]) { 09696 ast_mutex_unlock(&iaxsl[fr->callno]); 09697 return 1; 09698 } 09699 } 09700 break; 09701 case IAX_COMMAND_TXREJ: 09702 iaxs[fr->callno]->transferring = 0; 09703 if (option_verbose > 2) 09704 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09705 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 09706 if (iaxs[fr->callno]->bridgecallno) { 09707 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 09708 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 09709 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 09710 } 09711 } 09712 break; 09713 case IAX_COMMAND_TXREADY: 09714 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 09715 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 09716 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 09717 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 09718 else 09719 iaxs[fr->callno]->transferring = TRANSFER_READY; 09720 if (option_verbose > 2) 09721 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09722 if (iaxs[fr->callno]->bridgecallno) { 09723 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 09724 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 09725 /* They're both ready, now release them. */ 09726 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 09727 if (option_verbose > 2) 09728 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09729 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09730 09731 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 09732 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 09733 09734 memset(&ied0, 0, sizeof(ied0)); 09735 memset(&ied1, 0, sizeof(ied1)); 09736 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09737 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09738 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 09739 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 09740 } else { 09741 if (option_verbose > 2) 09742 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09743 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09744 09745 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 09746 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 09747 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 09748 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09749 09750 /* Stop doing lag & ping requests */ 09751 stop_stuff(fr->callno); 09752 stop_stuff(iaxs[fr->callno]->bridgecallno); 09753 09754 memset(&ied0, 0, sizeof(ied0)); 09755 memset(&ied1, 0, sizeof(ied1)); 09756 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09757 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09758 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 09759 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 09760 } 09761 09762 } 09763 } 09764 } 09765 break; 09766 case IAX_COMMAND_TXREQ: 09767 try_transfer(iaxs[fr->callno], &ies); 09768 break; 09769 case IAX_COMMAND_TXCNT: 09770 if (iaxs[fr->callno]->transferring) 09771 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 09772 break; 09773 case IAX_COMMAND_TXREL: 09774 /* Send ack immediately, rather than waiting until we've changed addresses */ 09775 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09776 complete_transfer(fr->callno, &ies); 09777 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 09778 break; 09779 case IAX_COMMAND_TXMEDIA: 09780 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 09781 AST_LIST_LOCK(&iaxq.queue); 09782 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09783 /* Cancel any outstanding frames and start anew */ 09784 if ((fr->callno == cur->callno) && (cur->transfer)) { 09785 cur->retries = -1; 09786 } 09787 } 09788 AST_LIST_UNLOCK(&iaxq.queue); 09789 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 09790 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 09791 } 09792 break; 09793 case IAX_COMMAND_DPREP: 09794 complete_dpreply(iaxs[fr->callno], &ies); 09795 break; 09796 case IAX_COMMAND_UNSUPPORT: 09797 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 09798 break; 09799 case IAX_COMMAND_FWDOWNL: 09800 /* Firmware download */ 09801 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 09802 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 09803 break; 09804 } 09805 memset(&ied0, 0, sizeof(ied0)); 09806 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 09807 if (res < 0) 09808 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09809 else if (res > 0) 09810 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09811 else 09812 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09813 if (!iaxs[fr->callno]) { 09814 ast_mutex_unlock(&iaxsl[fr->callno]); 09815 return 1; 09816 } 09817 break; 09818 case IAX_COMMAND_CALLTOKEN: 09819 { 09820 struct iax_frame *cur; 09821 AST_LIST_LOCK(&iaxq.queue); 09822 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09823 /* find the last sent frame in our frame queue for this callno. 09824 * There are many things to take into account before resending this frame. 09825 * All of these are taken care of in resend_with_token() */ 09826 if (cur->callno == fr->callno) { 09827 break; 09828 } 09829 } 09830 AST_LIST_UNLOCK(&iaxq.queue); 09831 09832 /* find last sent frame */ 09833 if (cur && ies.calltoken && ies.calltokendata) { 09834 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 09835 } 09836 break; 09837 } 09838 default: 09839 if (option_debug) 09840 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 09841 memset(&ied0, 0, sizeof(ied0)); 09842 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 09843 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 09844 } 09845 /* Don't actually pass these frames along */ 09846 if ((f.subclass != IAX_COMMAND_ACK) && 09847 (f.subclass != IAX_COMMAND_TXCNT) && 09848 (f.subclass != IAX_COMMAND_TXACC) && 09849 (f.subclass != IAX_COMMAND_INVAL) && 09850 (f.subclass != IAX_COMMAND_VNAK)) { 09851 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09852 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09853 } 09854 ast_mutex_unlock(&iaxsl[fr->callno]); 09855 return 1; 09856 } 09857 /* Unless this is an ACK or INVAL frame, ack it */ 09858 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09859 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09860 } else if (minivid) { 09861 f.frametype = AST_FRAME_VIDEO; 09862 if (iaxs[fr->callno]->videoformat > 0) 09863 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 09864 else { 09865 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 09866 iax2_vnak(fr->callno); 09867 ast_mutex_unlock(&iaxsl[fr->callno]); 09868 return 1; 09869 } 09870 f.datalen = res - sizeof(*vh); 09871 if (f.datalen) 09872 f.data = thread->buf + sizeof(*vh); 09873 else 09874 f.data = NULL; 09875 #ifdef IAXTESTS 09876 if (test_resync) { 09877 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 09878 } else 09879 #endif /* IAXTESTS */ 09880 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 09881 } else { 09882 /* A mini frame */ 09883 f.frametype = AST_FRAME_VOICE; 09884 if (iaxs[fr->callno]->voiceformat > 0) 09885 f.subclass = iaxs[fr->callno]->voiceformat; 09886 else { 09887 if (option_debug) 09888 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 09889 iax2_vnak(fr->callno); 09890 ast_mutex_unlock(&iaxsl[fr->callno]); 09891 return 1; 09892 } 09893 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 09894 if (f.datalen < 0) { 09895 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09896 ast_mutex_unlock(&iaxsl[fr->callno]); 09897 return 1; 09898 } 09899 if (f.datalen) 09900 f.data = thread->buf + sizeof(*mh); 09901 else 09902 f.data = NULL; 09903 #ifdef IAXTESTS 09904 if (test_resync) { 09905 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 09906 } else 09907 #endif /* IAXTESTS */ 09908 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 09909 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 09910 } 09911 /* Don't pass any packets until we're started */ 09912 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09913 ast_mutex_unlock(&iaxsl[fr->callno]); 09914 return 1; 09915 } 09916 /* Common things */ 09917 f.src = "IAX2"; 09918 f.mallocd = 0; 09919 f.offset = 0; 09920 f.len = 0; 09921 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 09922 f.samples = ast_codec_get_samples(&f); 09923 /* We need to byteswap incoming slinear samples from network byte order */ 09924 if (f.subclass == AST_FORMAT_SLINEAR) 09925 ast_frame_byteswap_be(&f); 09926 } else 09927 f.samples = 0; 09928 iax_frame_wrap(fr, &f); 09929 09930 /* If this is our most recent packet, use it as our basis for timestamping */ 09931 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 09932 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 09933 fr->outoforder = 0; 09934 } else { 09935 if (option_debug && iaxdebug && iaxs[fr->callno]) 09936 ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last); 09937 fr->outoforder = -1; 09938 } 09939 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 09940 duped_fr = iaxfrdup2(fr); 09941 if (duped_fr) { 09942 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 09943 } 09944 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 09945 iaxs[fr->callno]->last = fr->ts; 09946 #if 1 09947 if (option_debug && iaxdebug) 09948 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 09949 #endif 09950 } 09951 09952 /* Always run again */ 09953 ast_mutex_unlock(&iaxsl[fr->callno]); 09954 return 1; 09955 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 8237 of file chan_iax2.c.
References ast_copy_string(), 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, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
08238 { 08239 struct iax2_thread *thread; 08240 socklen_t len; 08241 time_t t; 08242 static time_t last_errtime = 0; 08243 struct ast_iax2_full_hdr *fh; 08244 08245 if (!(thread = find_idle_thread())) { 08246 time(&t); 08247 if (t != last_errtime && option_debug) 08248 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 08249 last_errtime = t; 08250 usleep(1); 08251 return 1; 08252 } 08253 08254 len = sizeof(thread->iosin); 08255 thread->iofd = fd; 08256 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 08257 thread->buf_size = sizeof(thread->readbuf); 08258 thread->buf = thread->readbuf; 08259 if (thread->buf_len < 0) { 08260 if (errno != ECONNREFUSED && errno != EAGAIN) 08261 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 08262 handle_error(); 08263 thread->iostate = IAX_IOSTATE_IDLE; 08264 signal_condition(&thread->lock, &thread->cond); 08265 return 1; 08266 } 08267 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 08268 thread->iostate = IAX_IOSTATE_IDLE; 08269 signal_condition(&thread->lock, &thread->cond); 08270 return 1; 08271 } 08272 08273 /* Determine if this frame is a full frame; if so, and any thread is currently 08274 processing a full frame for the same callno from this peer, then drop this 08275 frame (and the peer will retransmit it) */ 08276 fh = (struct ast_iax2_full_hdr *) thread->buf; 08277 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 08278 struct iax2_thread *cur = NULL; 08279 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 08280 08281 AST_LIST_LOCK(&active_list); 08282 AST_LIST_TRAVERSE(&active_list, cur, list) { 08283 if ((cur->ffinfo.callno == callno) && 08284 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 08285 break; 08286 } 08287 if (cur) { 08288 /* we found another thread processing a full frame for this call, 08289 so queue it up for processing later. */ 08290 defer_full_frame(thread, cur); 08291 AST_LIST_UNLOCK(&active_list); 08292 thread->iostate = IAX_IOSTATE_IDLE; 08293 signal_condition(&thread->lock, &thread->cond); 08294 return 1; 08295 } else { 08296 /* this thread is going to process this frame, so mark it */ 08297 thread->ffinfo.callno = callno; 08298 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 08299 thread->ffinfo.type = fh->type; 08300 thread->ffinfo.csub = fh->csub; 08301 } 08302 AST_LIST_UNLOCK(&active_list); 08303 } 08304 08305 /* Mark as ready and send on its way */ 08306 thread->iostate = IAX_IOSTATE_READY; 08307 #ifdef DEBUG_SCHED_MULTITHREAD 08308 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 08309 #endif 08310 signal_condition(&thread->lock, &thread->cond); 08311 08312 return 1; 08313 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 8024 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
08025 { 08026 pthread_t newthread; 08027 struct dpreq_data *dpr; 08028 pthread_attr_t attr; 08029 08030 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 08031 return; 08032 08033 pthread_attr_init(&attr); 08034 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08035 08036 dpr->callno = callno; 08037 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 08038 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 08039 if (callerid) 08040 dpr->callerid = ast_strdup(callerid); 08041 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 08042 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 08043 } 08044 08045 pthread_attr_destroy(&attr); 08046 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 10571 of file chan_iax2.c.
References ast_calloc, ast_cond_init, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init, ast_pthread_create, ast_pthread_create_background, ast_verbose(), free, iax2_process_thread(), IAX_TYPE_POOL, iaxthreadcount, iax_frame::list, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
10572 { 10573 pthread_attr_t attr; 10574 int threadcount = 0; 10575 int x; 10576 for (x = 0; x < iaxthreadcount; x++) { 10577 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 10578 if (thread) { 10579 thread->type = IAX_TYPE_POOL; 10580 thread->threadnum = ++threadcount; 10581 ast_mutex_init(&thread->lock); 10582 ast_cond_init(&thread->cond, NULL); 10583 pthread_attr_init(&attr); 10584 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10585 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 10586 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 10587 free(thread); 10588 thread = NULL; 10589 } 10590 AST_LIST_LOCK(&idle_list); 10591 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 10592 AST_LIST_UNLOCK(&idle_list); 10593 } 10594 } 10595 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 10596 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 10597 if (option_verbose > 1) 10598 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 10599 return 0; 10600 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 7706 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
07707 { 07708 iax2_destroy_helper(iaxs[callno]); 07709 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1398 of file chan_iax2.c.
References ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01399 { 01400 if (!pvt->peercallno) { 01401 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01402 return; 01403 } 01404 01405 ao2_link(iax_peercallno_pvts, pvt); 01406 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1379 of file chan_iax2.c.
References ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01380 { 01381 if (!pvt->transfercallno) { 01382 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01383 return; 01384 } 01385 01386 ao2_link(iax_transfercallno_pvts, pvt); 01387 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7893 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), totalcalls, tpeerlock, tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
07894 { 07895 char buf[1024]; 07896 int res; 07897 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 07898 int processed = 0; 07899 int totalcalls = 0; 07900 #ifdef DAHDI_TIMERACK 07901 int x = 1; 07902 #endif 07903 struct timeval now; 07904 if (iaxtrunkdebug) 07905 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 07906 gettimeofday(&now, NULL); 07907 if (events & AST_IO_PRI) { 07908 #ifdef DAHDI_TIMERACK 07909 /* Great, this is a timing interface, just call the ioctl */ 07910 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 07911 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 07912 usleep(1); 07913 return -1; 07914 } 07915 #endif 07916 } else { 07917 /* Read and ignore from the pseudo channel for timing */ 07918 res = read(fd, buf, sizeof(buf)); 07919 if (res < 1) { 07920 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 07921 return 1; 07922 } 07923 } 07924 /* For each peer that supports trunking... */ 07925 ast_mutex_lock(&tpeerlock); 07926 tpeer = tpeers; 07927 while(tpeer) { 07928 processed++; 07929 res = 0; 07930 ast_mutex_lock(&tpeer->lock); 07931 /* We can drop a single tpeer per pass. That makes all this logic 07932 substantially easier */ 07933 if (!drop && iax2_trunk_expired(tpeer, &now)) { 07934 /* Take it out of the list, but don't free it yet, because it 07935 could be in use */ 07936 if (prev) 07937 prev->next = tpeer->next; 07938 else 07939 tpeers = tpeer->next; 07940 drop = tpeer; 07941 } else { 07942 res = send_trunk(tpeer, &now); 07943 if (iaxtrunkdebug) 07944 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); 07945 } 07946 totalcalls += res; 07947 res = 0; 07948 ast_mutex_unlock(&tpeer->lock); 07949 prev = tpeer; 07950 tpeer = tpeer->next; 07951 } 07952 ast_mutex_unlock(&tpeerlock); 07953 if (drop) { 07954 ast_mutex_lock(&drop->lock); 07955 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 07956 because by the time they could get tpeerlock, we've already grabbed it */ 07957 if (option_debug) 07958 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 07959 if (drop->trunkdata) { 07960 free(drop->trunkdata); 07961 drop->trunkdata = NULL; 07962 } 07963 ast_mutex_unlock(&drop->lock); 07964 ast_mutex_destroy(&drop->lock); 07965 free(drop); 07966 07967 } 07968 if (iaxtrunkdebug) 07969 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 07970 iaxtrunkdebug =0; 07971 return 1; 07972 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12625 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12626 { 12627 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12628 12629 /* The frames_received field is used to hold whether we're matching 12630 * against a full frame or not ... */ 12631 12632 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 12633 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12634 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12618 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
12619 { 12620 const struct chan_iax2_pvt *pvt = obj; 12621 12622 return pvt->transfercallno; 12623 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2959 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02960 { 02961 int res; 02962 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02963 sizeof(*sin)); 02964 if (res < 0) { 02965 if (option_debug) 02966 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02967 handle_error(); 02968 } else 02969 res = 0; 02970 return res; 02971 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2647 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
02648 { 02649 struct stat stbuf; 02650 struct iax_firmware *cur; 02651 int ifd; 02652 int fd; 02653 int res; 02654 02655 struct ast_iax2_firmware_header *fwh, fwh2; 02656 struct MD5Context md5; 02657 unsigned char sum[16]; 02658 unsigned char buf[1024]; 02659 int len, chunk; 02660 char *s2; 02661 char *last; 02662 s2 = alloca(strlen(s) + 100); 02663 if (!s2) { 02664 ast_log(LOG_WARNING, "Alloca failed!\n"); 02665 return -1; 02666 } 02667 last = strrchr(s, '/'); 02668 if (last) 02669 last++; 02670 else 02671 last = s; 02672 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02673 res = stat(s, &stbuf); 02674 if (res < 0) { 02675 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02676 return -1; 02677 } 02678 /* Make sure it's not a directory */ 02679 if (S_ISDIR(stbuf.st_mode)) 02680 return -1; 02681 ifd = open(s, O_RDONLY); 02682 if (ifd < 0) { 02683 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02684 return -1; 02685 } 02686 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 02687 if (fd < 0) { 02688 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02689 close(ifd); 02690 return -1; 02691 } 02692 /* Unlink our newly created file */ 02693 unlink(s2); 02694 02695 /* Now copy the firmware into it */ 02696 len = stbuf.st_size; 02697 while(len) { 02698 chunk = len; 02699 if (chunk > sizeof(buf)) 02700 chunk = sizeof(buf); 02701 res = read(ifd, buf, chunk); 02702 if (res != chunk) { 02703 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02704 close(ifd); 02705 close(fd); 02706 return -1; 02707 } 02708 res = write(fd, buf, chunk); 02709 if (res != chunk) { 02710 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02711 close(ifd); 02712 close(fd); 02713 return -1; 02714 } 02715 len -= chunk; 02716 } 02717 close(ifd); 02718 /* Return to the beginning */ 02719 lseek(fd, 0, SEEK_SET); 02720 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02721 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02722 close(fd); 02723 return -1; 02724 } 02725 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02726 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02727 close(fd); 02728 return -1; 02729 } 02730 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02731 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02732 close(fd); 02733 return -1; 02734 } 02735 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02736 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02737 close(fd); 02738 return -1; 02739 } 02740 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02741 if (fwh == MAP_FAILED) { 02742 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02743 close(fd); 02744 return -1; 02745 } 02746 MD5Init(&md5); 02747 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02748 MD5Final(sum, &md5); 02749 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02750 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02751 munmap((void*)fwh, stbuf.st_size); 02752 close(fd); 02753 return -1; 02754 } 02755 cur = waresl.wares; 02756 while(cur) { 02757 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02758 /* Found a candidate */ 02759 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02760 /* The version we have on loaded is older, load this one instead */ 02761 break; 02762 /* This version is no newer than what we have. Don't worry about it. 02763 We'll consider it a proper load anyhow though */ 02764 munmap((void*)fwh, stbuf.st_size); 02765 close(fd); 02766 return 0; 02767 } 02768 cur = cur->next; 02769 } 02770 if (!cur) { 02771 /* Allocate a new one and link it */ 02772 if ((cur = ast_calloc(1, sizeof(*cur)))) { 02773 cur->fd = -1; 02774 cur->next = waresl.wares; 02775 waresl.wares = cur; 02776 } 02777 } 02778 if (cur) { 02779 if (cur->fwh) { 02780 munmap((void*)cur->fwh, cur->mmaplen); 02781 } 02782 if (cur->fd > -1) 02783 close(cur->fd); 02784 cur->fwh = fwh; 02785 cur->fd = fd; 02786 cur->mmaplen = stbuf.st_size; 02787 cur->dead = 0; 02788 } 02789 return 0; 02790 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7074 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
07075 { 07076 int newcall = 0; 07077 char newip[256]; 07078 struct iax_ie_data ied; 07079 struct sockaddr_in new; 07080 07081 07082 memset(&ied, 0, sizeof(ied)); 07083 if (ies->apparent_addr) 07084 bcopy(ies->apparent_addr, &new, sizeof(new)); 07085 if (ies->callno) 07086 newcall = ies->callno; 07087 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07088 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07089 return -1; 07090 } 07091 pvt->transfercallno = newcall; 07092 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07093 inet_aton(newip, &pvt->transfer.sin_addr); 07094 pvt->transfer.sin_family = AF_INET; 07095 pvt->transferring = TRANSFER_BEGIN; 07096 pvt->transferid = ies->transferid; 07097 store_by_transfercallno(pvt); 07098 if (ies->transferid) 07099 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07100 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07101 return 0; 07102 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1214 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01215 { 01216 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01217 if (csub & IAX_FLAG_SC_LOG) { 01218 /* special case for 'compressed' -1 */ 01219 if (csub == 0xff) 01220 return -1; 01221 else 01222 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01223 } 01224 else 01225 return csub; 01226 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 7358 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().
07359 { 07360 if (peer->expire > -1) { 07361 if (!ast_sched_del(sched, peer->expire)) { 07362 peer->expire = -1; 07363 peer_unref(peer); 07364 } 07365 } 07366 07367 if (peer->pokeexpire > -1) { 07368 if (!ast_sched_del(sched, peer->pokeexpire)) { 07369 peer->pokeexpire = -1; 07370 peer_unref(peer); 07371 } 07372 } 07373 07374 ao2_unlink(peers, peer); 07375 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12584 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
12585 { 12586 ast_custom_function_unregister(&iaxpeer_function); 12587 return __unload_module(); 12588 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4695 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
04696 { 04697 ast_mutex_unlock(&iaxsl[callno1]); 04698 ast_mutex_unlock(&iaxsl[callno0]); 04699 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3431 of file chan_iax2.c.
References iax_frame::af, AST_FRAME_VIDEO, ast_log(), iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
03432 { 03433 /* Video mini frames only encode the lower 15 bits of the session 03434 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03435 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03436 const int lower_mask = (1 << ts_shift) - 1; 03437 const int upper_mask = ~lower_mask; 03438 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03439 03440 if ( (fr->ts & upper_mask) == last_upper ) { 03441 const int x = fr->ts - iaxs[fr->callno]->last; 03442 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03443 03444 if (x < -threshold) { 03445 /* Sudden big jump backwards in timestamp: 03446 What likely happened here is that miniframe timestamp has circled but we haven't 03447 gotten the update from the main packet. We'll just pretend that we did, and 03448 update the timestamp appropriately. */ 03449 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03450 if (option_debug && iaxdebug) 03451 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 03452 } else if (x > threshold) { 03453 /* Sudden apparent big jump forwards in timestamp: 03454 What's likely happened is this is an old miniframe belonging to the previous 03455 top 15 or 16-bit timestamp that has turned up out of order. 03456 Adjust the timestamp appropriately. */ 03457 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03458 if (option_debug && iaxdebug) 03459 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 03460 } 03461 } 03462 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3466 of file chan_iax2.c.
References AST_SCHED_DEL, ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
03467 { 03468 int when; 03469 03470 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03471 03472 when = jb_next(pvt->jb) - when; 03473 03474 AST_SCHED_DEL(sched, pvt->jbid); 03475 03476 if(when <= 0) { 03477 /* XXX should really just empty until when > 0.. */ 03478 when = 1; 03479 } 03480 03481 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 03482 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1705 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01706 { 01707 int max = 1; 01708 int x; 01709 /* XXX Prolly don't need locks here XXX */ 01710 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01711 if (iaxs[x]) 01712 max = x + 1; 01713 } 01714 maxnontrunkcall = max; 01715 if (option_debug && iaxdebug) 01716 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01717 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1418 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01419 { 01420 int max = TRUNK_CALL_START; 01421 int x; 01422 01423 /* XXX Prolly don't need locks here XXX */ 01424 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01425 if (iaxs[x]) { 01426 max = x + 1; 01427 } 01428 } 01429 01430 maxtrunkcall = max; 01431 if (option_debug && iaxdebug) 01432 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01433 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3030 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().
03031 { 03032 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03033 struct ast_iax2_full_hdr *fh = f->data; 03034 struct ast_frame af; 03035 03036 /* if frame is encrypted. decrypt before updating it. */ 03037 if (f->encmethods) { 03038 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03039 } 03040 /* Mark this as a retransmission */ 03041 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03042 /* Update iseqno */ 03043 f->iseqno = iaxs[f->callno]->iseqno; 03044 fh->iseqno = f->iseqno; 03045 03046 /* Now re-encrypt the frame */ 03047 if (f->encmethods) { 03048 /* since this is a retransmit frame, create a new random padding 03049 * before re-encrypting. */ 03050 build_rand_pad(f->semirand, sizeof(f->semirand)); 03051 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03052 } 03053 return 0; 03054 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 7471 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), 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_verbose(), iax2_peer::cid_name, iax2_peer::cid_num, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_peer::mailbox, manager_event(), iax2_peer::maxcallno, iax2_peer::name, option_verbose, peer_ref(), peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, VERBOSE_PREFIX_3, and iax2_peer::zonetag.
Referenced by socket_process().
07472 { 07473 /* Called from IAX thread only, with proper iaxsl lock */ 07474 struct iax_ie_data ied; 07475 struct iax2_peer *p; 07476 int msgcount; 07477 char data[80]; 07478 int version; 07479 const char *peer_name; 07480 int res = -1; 07481 07482 memset(&ied, 0, sizeof(ied)); 07483 07484 peer_name = ast_strdupa(iaxs[callno]->peer); 07485 07486 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 07487 ast_mutex_unlock(&iaxsl[callno]); 07488 if (!(p = find_peer(peer_name, 1))) { 07489 ast_mutex_lock(&iaxsl[callno]); 07490 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 07491 return -1; 07492 } 07493 ast_mutex_lock(&iaxsl[callno]); 07494 if (!iaxs[callno]) 07495 goto return_unref; 07496 07497 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 07498 if (sin->sin_addr.s_addr) { 07499 time_t nowtime; 07500 time(&nowtime); 07501 realtime_update_peer(peer_name, sin, nowtime); 07502 } else { 07503 realtime_update_peer(peer_name, sin, 0); 07504 } 07505 } 07506 if (inaddrcmp(&p->addr, sin)) { 07507 if (iax2_regfunk) 07508 iax2_regfunk(p->name, 1); 07509 07510 /* modify entry in peercnts table as _not_ registered */ 07511 peercnt_modify(0, 0, &p->addr); 07512 07513 /* Stash the IP address from which they registered */ 07514 memcpy(&p->addr, sin, sizeof(p->addr)); 07515 07516 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 07517 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 07518 ast_db_put("IAX/Registry", p->name, data); 07519 if (option_verbose > 2) 07520 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 07521 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 07522 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 07523 register_peer_exten(p, 1); 07524 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07525 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 07526 if (option_verbose > 2) 07527 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 07528 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 07529 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 07530 register_peer_exten(p, 0); 07531 ast_db_del("IAX/Registry", p->name); 07532 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07533 } 07534 /* Update the host */ 07535 /* Verify that the host is really there */ 07536 iax2_poke_peer(p, callno); 07537 } 07538 07539 /* modify entry in peercnts table as registered */ 07540 if (p->maxcallno) { 07541 peercnt_modify(1, p->maxcallno, &p->addr); 07542 } 07543 07544 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 07545 if (!iaxs[callno]) { 07546 res = -1; 07547 goto return_unref; 07548 } 07549 07550 /* Store socket fd */ 07551 p->sockfd = fd; 07552 /* Setup the expiry */ 07553 if (p->expire > -1) { 07554 if (!ast_sched_del(sched, p->expire)) { 07555 p->expire = -1; 07556 peer_unref(p); 07557 } 07558 } 07559 /* treat an unspecified refresh interval as the minimum */ 07560 if (!refresh) 07561 refresh = min_reg_expire; 07562 if (refresh > max_reg_expire) { 07563 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07564 p->name, max_reg_expire, refresh); 07565 p->expiry = max_reg_expire; 07566 } else if (refresh < min_reg_expire) { 07567 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07568 p->name, min_reg_expire, refresh); 07569 p->expiry = min_reg_expire; 07570 } else { 07571 p->expiry = refresh; 07572 } 07573 if (p->expiry && sin->sin_addr.s_addr) { 07574 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07575 if (p->expire == -1) 07576 peer_unref(p); 07577 } 07578 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 07579 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 07580 if (sin->sin_addr.s_addr) { 07581 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 07582 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 07583 if (!ast_strlen_zero(p->mailbox)) { 07584 int new, old; 07585 ast_app_inboxcount(p->mailbox, &new, &old); 07586 if (new > 255) 07587 new = 255; 07588 if (old > 255) 07589 old = 255; 07590 msgcount = (old << 8) | new; 07591 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 07592 } 07593 if (ast_test_flag(p, IAX_HASCALLERID)) { 07594 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 07595 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 07596 } 07597 } 07598 version = iax_check_version(devtype); 07599 if (version) 07600 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 07601 07602 res = 0; 07603 07604 return_unref: 07605 peer_unref(p); 07606 07607 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 07608 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1261 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_objects().
01262 { 01263 struct iax2_user *user = obj, *user2 = arg; 01264 01265 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01266 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11240 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11241 { 11242 struct iax2_user *user = obj; 11243 11244 ast_set_flag(user, IAX_DELME); 11245 11246 return 0; 11247 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 10989 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
10990 { 10991 struct iax2_user *user = obj; 10992 10993 ast_free_ha(user->ha); 10994 free_context(user->contexts); 10995 if(user->vars) { 10996 ast_variables_destroy(user->vars); 10997 user->vars = NULL; 10998 } 10999 ast_string_field_free_memory(user); 11000 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1251 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_objects().
01252 { 01253 const struct iax2_user *user = obj; 01254 01255 return ast_str_hash(user->name); 01256 }
Definition at line 1309 of file chan_iax2.c.
References ao2_ref().
01310 { 01311 ao2_ref(user, +1); 01312 return user; 01313 }
Definition at line 1315 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), prune_users(), requirecalltoken_mark_auto(), and set_config().
01316 { 01317 ao2_ref(user, -1); 01318 return NULL; 01319 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 7807 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, iax_frame::list, ast_iax2_queue::queue, and send_packet().
Referenced by socket_process().
07808 { 07809 struct iax_frame *f; 07810 07811 AST_LIST_LOCK(&iaxq.queue); 07812 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 07813 /* Send a copy immediately */ 07814 if ((f->callno == callno) && iaxs[f->callno] && 07815 ((unsigned char ) (f->oseqno - last) < 128) && 07816 (f->retries >= 0)) { 07817 send_packet(f); 07818 } 07819 } 07820 AST_LIST_UNLOCK(&iaxq.queue); 07821 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4593 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
04594 { 04595 unsigned short callno = pvt->callno; 04596 04597 if (!pvt->peercallno) { 04598 /* We don't know the remote side's call number, yet. :( */ 04599 int count = 10; 04600 while (count-- && pvt && !pvt->peercallno) { 04601 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 04602 pvt = iaxs[callno]; 04603 } 04604 if (!pvt->peercallno) { 04605 return -1; 04606 } 04607 } 04608 04609 return 0; 04610 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 12802 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 216 of file chan_iax2.c.
Referenced by __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), dahdi_new(), disa_exec(), features_call(), findmeexec(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
int amaflags = 0 [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 12802 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 156 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 711 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 671 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 676 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 674 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 714 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] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 12370 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "debug", NULL }, iax2_no_debug, NULL, NULL }
Definition at line 12375 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "jb", "debug", NULL }, iax2_no_jb_debug, NULL, NULL }
Definition at line 12385 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "trunk", "debug", NULL }, iax2_no_trunk_debug, NULL, NULL }
Definition at line 12380 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug, NULL, NULL }
Definition at line 12365 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 142 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 12339 of file chan_iax2.c.
char debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk\n" " Requests current status of IAX trunking\n"
Definition at line 12331 of file chan_iax2.c.
char debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug\n" " Enables dumping of IAX packets for debugging purposes\n"
Definition at line 12323 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 716 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 718 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 173 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 221 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
ast_mutex_t dpcache_lock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Definition at line 792 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_cache(), and socket_process().
uint16_t global_maxcallno [static] |
Definition at line 720 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 723 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 275 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 224 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), check_access(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), 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 202 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 222 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 175 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 12281 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 984 of file chan_iax2.c.
Referenced by __unload_module(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
char iax2_test_losspct_usage[] [static] |
Initial value:
"Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n"
Definition at line 12347 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 928 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 935 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 472 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 157 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 204 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 470 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 ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 916 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(), 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(), iax2_ack_registry(), 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_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_frame_subclass2str(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), socket_process(), 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] |
Definition at line 917 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), scheduled_destroy(), send_command_locked(), socket_process(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 468 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 199 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 150 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 144 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 158 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 685 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 167 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 148 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 147 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 153 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 942 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 941 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 166 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 217 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 171 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 226 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 12343 of file chan_iax2.c.
char no_debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk off\n" " Requests current status of IAX trunking\n"
Definition at line 12335 of file chan_iax2.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug off\n" " Disables dumping of IAX packets for debugging purposes\n"
Definition at line 12327 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 172 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 10206 of file chan_iax2.c.
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 10208 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 708 of file chan_iax2.c.
Referenced by __unload_module(), iax2_show_callnumber_usage(), 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 701 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), delete_users(), find_peer(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().
int ping_time = 21 [static] |
Definition at line 149 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 138 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(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 12277 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 10207 of file chan_iax2.c.
int randomcalltokendata [static] |
Definition at line 683 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 200 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 229 of file chan_iax2.c.
ast_mutex_t sched_lock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Definition at line 228 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 227 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 12265 of file chan_iax2.c.
char show_callnumber_usage[] [static] |
Initial value:
"Usage: iax2 show callnumber usage <ip optional>\n" " Show current entries in the ip Call Number Limit table.\n"
Definition at line 12273 of file chan_iax2.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: iax2 show channels\n" " Lists all currently active IAX channels.\n"
Definition at line 12297 of file chan_iax2.c.
char show_firmware_usage[] [static] |
Initial value:
"Usage: iax2 show firmware\n" " Lists all known IAX firmware images.\n"
Definition at line 12315 of file chan_iax2.c.
char show_netstats_usage[] [static] |
Initial value:
"Usage: iax2 show netstats\n" " Lists network status for all currently active IAX channels.\n"
Definition at line 12301 of file chan_iax2.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: iax2 show peer <name>\n" " Display details on specific IAX peer\n"
Definition at line 12269 of file chan_iax2.c.
char show_peers_usage[] [static] |
Initial value:
"Usage: iax2 show peers [registered] [like <pattern>]\n" " Lists all known IAX2 peers.\n" " Optional 'registered' argument lists only peers with known addresses.\n" " Optional regular expression pattern is used to filter the peer list.\n"
Definition at line 12309 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 12285 of file chan_iax2.c.
char show_reg_usage[] [static] |
Initial value:
"Usage: iax2 show registry\n" " Lists all registration requests and status.\n"
Definition at line 12319 of file chan_iax2.c.
char show_stats_usage[] [static] |
Initial value:
"Usage: iax2 show stats\n" " Display statistics on IAX channel driver.\n"
Definition at line 12261 of file chan_iax2.c.
char show_threads_usage[] [static] |
Initial value:
"Usage: iax2 show threads\n" " Lists status of IAX helper threads\n"
Definition at line 12305 of file chan_iax2.c.
char show_users_usage[] [static] |
Initial value:
"Usage: iax2 show users [like <pattern>]\n" " Lists all known IAX2 users.\n" " Optional regular expression pattern is used to filter the user list.\n"
Definition at line 12292 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 140 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 208 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 169 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 164 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 725 of file chan_iax2.c.
ast_mutex_t tpeerlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 154 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 704 of file chan_iax2.c.
Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), load_objects(), prune_users(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().