#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 IAX_MAX_CALLS / 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 void | iax2_lock_owner (int callno) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 = ((ast_mutex_t) 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+1] |
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 = ((ast_mutex_t) 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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static int | unloading |
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 774 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 770 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 784 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 772 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 776 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 778 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 780 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 782 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 124 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 112 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 130 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 199 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 198 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 127 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 197 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 463 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 137 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 180 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 188 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 193 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 182 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
Definition at line 809 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 812 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 115 of file chan_iax2.c.
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 472 of file chan_iax2.c.
Referenced by ast_cli_netstats(), iax2_send(), and iax2_show_channels().
#define MAX_JITTER_BUFFER 50 |
Definition at line 460 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 704 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 466 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 464 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 129 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 461 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 123 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 108 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1140 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START IAX_MAX_CALLS / 2 |
Definition at line 945 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 469 of file chan_iax2.c.
anonymous enum |
Definition at line 237 of file chan_iax2.c.
00237 { 00238 IAX_STATE_STARTED = (1 << 0), 00239 IAX_STATE_AUTHENTICATED = (1 << 1), 00240 IAX_STATE_TBD = (1 << 2), 00241 } iax2_state;
anonymous enum |
Definition at line 248 of file chan_iax2.c.
00248 { 00249 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00250 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00251 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00252 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00253 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00254 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00255 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00256 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00257 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00258 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00259 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00260 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00261 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00262 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00263 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00264 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00265 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00266 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00267 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00268 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00269 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00270 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00271 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00272 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00273 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00274 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00275 response, so that we've achieved a three-way handshake with 00276 them before sending voice or anything else*/ 00277 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00278 IAX_SHRINKCALLERID = (1 << 27), /*!< Turn on and off caller id shrinking */ 00279 } iax2_flags;
anonymous enum |
Definition at line 1712 of file chan_iax2.c.
01712 { 01713 /* do not allow a new call number, only search ones in use for match */ 01714 NEW_PREVENT = 0, 01715 /* search for match first, then allow a new one to be allocated */ 01716 NEW_ALLOW = 1, 01717 /* do not search for match, force a new call number */ 01718 NEW_FORCE = 2, 01719 /* do not search for match, force a new call number. Signifies call number 01720 * has been calltoken validated */ 01721 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01722 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 289 of file chan_iax2.c.
00289 { 00290 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00291 CALLTOKEN_DEFAULT = 0, 00292 /*! \brief Require call token validation. */ 00293 CALLTOKEN_YES = 1, 00294 /*! \brief Require call token validation after a successful registration 00295 * using call token validation occurs. */ 00296 CALLTOKEN_AUTO = 2, 00297 /*! \brief Do not require call token validation. */ 00298 CALLTOKEN_NO = 3, 00299 };
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 415 of file chan_iax2.c.
00415 { 00416 REG_STATE_UNREGISTERED = 0, 00417 REG_STATE_REGSENT, 00418 REG_STATE_AUTHSENT, 00419 REG_STATE_REGISTERED, 00420 REG_STATE_REJECTED, 00421 REG_STATE_TIMEOUT, 00422 REG_STATE_NOAUTH 00423 };
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 425 of file chan_iax2.c.
00425 { 00426 TRANSFER_NONE = 0, 00427 TRANSFER_BEGIN, 00428 TRANSFER_READY, 00429 TRANSFER_RELEASED, 00430 TRANSFER_PASSTHROUGH, 00431 TRANSFER_MBEGIN, 00432 TRANSFER_MREADY, 00433 TRANSFER_MRELEASED, 00434 TRANSFER_MPASSTHROUGH, 00435 TRANSFER_MEDIA, 00436 TRANSFER_MEDIAPASS 00437 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3078 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().
03079 { 03080 /* Attempt to transmit the frame to the remote peer... 03081 Called without iaxsl held. */ 03082 struct iax_frame *f = (struct iax_frame *)data; 03083 int freeme=0; 03084 int callno = f->callno; 03085 /* Make sure this call is still active */ 03086 if (callno) 03087 ast_mutex_lock(&iaxsl[callno]); 03088 if (callno && iaxs[callno]) { 03089 if ((f->retries < 0) /* Already ACK'd */ || 03090 (f->retries >= max_retries) /* Too many attempts */) { 03091 /* Record an error if we've transmitted too many times */ 03092 if (f->retries >= max_retries) { 03093 if (f->transfer) { 03094 /* Transfer timeout */ 03095 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03096 } else if (f->final) { 03097 if (f->final) 03098 iax2_destroy(callno); 03099 } else { 03100 if (iaxs[callno]->owner) 03101 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); 03102 iaxs[callno]->error = ETIMEDOUT; 03103 if (iaxs[callno]->owner) { 03104 struct ast_frame fr = { 0, }; 03105 /* Hangup the fd */ 03106 fr.frametype = AST_FRAME_CONTROL; 03107 fr.subclass = AST_CONTROL_HANGUP; 03108 iax2_queue_frame(callno, &fr); // XXX 03109 /* Remember, owner could disappear */ 03110 if (iaxs[callno] && iaxs[callno]->owner) 03111 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03112 } else { 03113 if (iaxs[callno]->reg) { 03114 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03115 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03116 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03117 } 03118 iax2_destroy(callno); 03119 } 03120 } 03121 03122 } 03123 freeme++; 03124 } else { 03125 /* Update it if it needs it */ 03126 update_packet(f); 03127 /* Attempt transmission */ 03128 send_packet(f); 03129 f->retries++; 03130 /* Try again later after 10 times as long */ 03131 f->retrytime *= 10; 03132 if (f->retrytime > MAX_RETRY_TIME) 03133 f->retrytime = MAX_RETRY_TIME; 03134 /* Transfer messages max out at one second */ 03135 if (f->transfer && (f->retrytime > 1000)) 03136 f->retrytime = 1000; 03137 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03138 } 03139 } else { 03140 /* Make sure it gets freed */ 03141 f->retries = -1; 03142 freeme++; 03143 } 03144 if (callno) 03145 ast_mutex_unlock(&iaxsl[callno]); 03146 /* Do not try again */ 03147 if (freeme) { 03148 /* Don't attempt delivery, just remove it from the queue */ 03149 AST_LIST_LOCK(&iaxq.queue); 03150 AST_LIST_REMOVE(&iaxq.queue, f, list); 03151 iaxq.count--; 03152 AST_LIST_UNLOCK(&iaxq.queue); 03153 f->retrans = -1; /* this is safe because this is the scheduled function */ 03154 /* Free the IAX frame */ 03155 iax2_frame_free(f); 03156 } 03157 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 7760 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().
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 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 07769 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 07770 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 07771 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 07772 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 07773 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07774 } 07775 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 07776 } 07777 ast_mutex_unlock(&iaxsl[callno]); 07778 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4074 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().
04075 { 04076 int callno = PTR_TO_CALLNO(nothing); 04077 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04078 ast_mutex_lock(&iaxsl[callno]); 04079 if (iaxs[callno]) { 04080 iaxs[callno]->initid = -1; 04081 iax2_queue_frame(callno, &f); 04082 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04083 } 04084 ast_mutex_unlock(&iaxsl[callno]); 04085 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 7809 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().
07810 { 07811 /* Called from IAX thread only, without iaxs lock */ 07812 int callno = (int)(long)(nothing); 07813 struct iax_ie_data ied; 07814 ast_mutex_lock(&iaxsl[callno]); 07815 if (iaxs[callno]) { 07816 memset(&ied, 0, sizeof(ied)); 07817 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 07818 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 07819 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 07820 } 07821 ast_mutex_unlock(&iaxsl[callno]); 07822 }
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 2931 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().
02932 { 02933 /* Just deliver the packet by using queueing. This is called by 02934 the IAX thread with the iaxsl lock held. */ 02935 struct iax_frame *fr = data; 02936 fr->retrans = -1; 02937 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02938 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02939 iax2_queue_frame(fr->callno, &fr->af); 02940 /* Free our iax frame */ 02941 iax2_frame_free(fr); 02942 /* And don't run again */ 02943 return 0; 02944 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7426 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().
07427 { 07428 struct iax2_peer *peer = (struct iax2_peer *) data; 07429 07430 if (!peer) 07431 return; 07432 07433 peer->expire = -1; 07434 07435 if (option_debug) 07436 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 07437 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 07438 realtime_update_peer(peer->name, &peer->addr, 0); 07439 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07440 /* modify entry in peercnts table as _not_ registered */ 07441 peercnt_modify(0, 0, &peer->addr); 07442 /* Reset the address */ 07443 memset(&peer->addr, 0, sizeof(peer->addr)); 07444 /* Reset expiry value */ 07445 peer->expiry = min_reg_expire; 07446 if (!ast_test_flag(peer, IAX_TEMPONLY)) 07447 ast_db_del("IAX/Registry", peer->name); 07448 register_peer_exten(peer, 0); 07449 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07450 if (iax2_regfunk) 07451 iax2_regfunk(peer->name, 0); 07452 07453 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 07454 unlink_peer(peer); 07455 07456 peer_unref(peer); 07457 }
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 2414 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(), maxnontrunkcall, maxtrunkcall, 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().
02415 { 02416 int res = 0; 02417 int x; 02418 /* this call is calltoken validated as long as it is either NEW_FORCE 02419 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02420 int validated = (new > NEW_ALLOW) ? 1 : 0; 02421 char host[80]; 02422 02423 if (new <= NEW_ALLOW) { 02424 if (callno) { 02425 struct chan_iax2_pvt *pvt; 02426 struct chan_iax2_pvt tmp_pvt = { 02427 .callno = dcallno, 02428 .peercallno = callno, 02429 .transfercallno = callno, 02430 /* hack!! */ 02431 .frames_received = check_dcallno, 02432 }; 02433 02434 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02435 /* this works for finding normal call numbers not involving transfering */ 02436 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02437 if (return_locked) { 02438 ast_mutex_lock(&iaxsl[pvt->callno]); 02439 } 02440 res = pvt->callno; 02441 ao2_ref(pvt, -1); 02442 pvt = NULL; 02443 return res; 02444 } 02445 /* this searches for transfer call numbers that might not get caught otherwise */ 02446 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02447 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02448 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02449 if (return_locked) { 02450 ast_mutex_lock(&iaxsl[pvt->callno]); 02451 } 02452 res = pvt->callno; 02453 ao2_ref(pvt, -1); 02454 pvt = NULL; 02455 return res; 02456 } 02457 } 02458 /* This will occur on the first response to a message that we initiated, 02459 * such as a PING. */ 02460 if (dcallno) { 02461 ast_mutex_lock(&iaxsl[dcallno]); 02462 } 02463 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02464 iaxs[dcallno]->peercallno = callno; 02465 res = dcallno; 02466 store_by_peercallno(iaxs[dcallno]); 02467 if (!res || !return_locked) { 02468 ast_mutex_unlock(&iaxsl[dcallno]); 02469 } 02470 return res; 02471 } 02472 if (dcallno) { 02473 ast_mutex_unlock(&iaxsl[dcallno]); 02474 } 02475 #ifdef IAX_OLD_FIND 02476 /* If we get here, we SHOULD NOT find a call structure for this 02477 callno; if we do, it means that there is a call structure that 02478 has a peer callno but did NOT get entered into the hash table, 02479 which is bad. 02480 02481 If we find a call structure using this old, slow method, output a log 02482 message so we'll know about it. After a few months of leaving this in 02483 place, if we don't hear about people seeing these messages, we can 02484 remove this code for good. 02485 */ 02486 02487 for (x = 1; !res && x < maxnontrunkcall; x++) { 02488 ast_mutex_lock(&iaxsl[x]); 02489 if (iaxs[x]) { 02490 /* Look for an exact match */ 02491 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02492 res = x; 02493 } 02494 } 02495 if (!res || !return_locked) 02496 ast_mutex_unlock(&iaxsl[x]); 02497 } 02498 02499 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02500 ast_mutex_lock(&iaxsl[x]); 02501 if (iaxs[x]) { 02502 /* Look for an exact match */ 02503 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02504 res = x; 02505 } 02506 } 02507 if (!res || !return_locked) 02508 ast_mutex_unlock(&iaxsl[x]); 02509 } 02510 02511 if (res) { 02512 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 02513 } 02514 #endif 02515 } 02516 if (!res && (new >= NEW_ALLOW)) { 02517 struct callno_entry *callno_entry; 02518 /* It may seem odd that we look through the peer list for a name for 02519 * this *incoming* call. Well, it is weird. However, users don't 02520 * have an IP address/port number that we can match against. So, 02521 * this is just checking for a peer that has that IP/port and 02522 * assuming that we have a user of the same name. This isn't always 02523 * correct, but it will be changed if needed after authentication. */ 02524 if (!iax2_getpeername(*sin, host, sizeof(host))) 02525 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02526 02527 if (peercnt_add(sin)) { 02528 /* This address has hit its callnumber limit. When the limit 02529 * is reached, the connection is not added to the peercnts table.*/ 02530 return 0; 02531 } 02532 02533 if (!(callno_entry = get_unused_callno(0, validated))) { 02534 /* since we ran out of space, remove the peercnt 02535 * entry we added earlier */ 02536 peercnt_remove_by_addr(sin); 02537 ast_log(LOG_WARNING, "No more space\n"); 02538 return 0; 02539 } 02540 x = callno_entry->callno; 02541 ast_mutex_lock(&iaxsl[x]); 02542 02543 iaxs[x] = new_iax(sin, host); 02544 update_max_nontrunk(); 02545 if (iaxs[x]) { 02546 if (option_debug && iaxdebug) 02547 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 02548 iaxs[x]->callno_entry = callno_entry; 02549 iaxs[x]->sockfd = sockfd; 02550 iaxs[x]->addr.sin_port = sin->sin_port; 02551 iaxs[x]->addr.sin_family = sin->sin_family; 02552 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02553 iaxs[x]->peercallno = callno; 02554 iaxs[x]->callno = x; 02555 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02556 iaxs[x]->expiry = min_reg_expire; 02557 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02558 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02559 iaxs[x]->amaflags = amaflags; 02560 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02561 02562 ast_string_field_set(iaxs[x], accountcode, accountcode); 02563 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02564 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02565 02566 if (iaxs[x]->peercallno) { 02567 store_by_peercallno(iaxs[x]); 02568 } 02569 } else { 02570 ast_log(LOG_WARNING, "Out of resources\n"); 02571 ast_mutex_unlock(&iaxsl[x]); 02572 replace_callno(callno_entry); 02573 return 0; 02574 } 02575 if (!return_locked) 02576 ast_mutex_unlock(&iaxsl[x]); 02577 res = x; 02578 } 02579 return res; 02580 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3505 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().
03506 { 03507 int callno = PTR_TO_CALLNO(p); 03508 struct chan_iax2_pvt *pvt = NULL; 03509 struct iax_frame *fr; 03510 jb_frame frame; 03511 int ret; 03512 long now; 03513 long next; 03514 struct timeval tv; 03515 03516 /* Make sure we have a valid private structure before going on */ 03517 ast_mutex_lock(&iaxsl[callno]); 03518 pvt = iaxs[callno]; 03519 if (!pvt) { 03520 /* No go! */ 03521 ast_mutex_unlock(&iaxsl[callno]); 03522 return; 03523 } 03524 03525 pvt->jbid = -1; 03526 03527 gettimeofday(&tv,NULL); 03528 /* round up a millisecond since ast_sched_runq does; */ 03529 /* prevents us from spinning while waiting for our now */ 03530 /* to catch up with runq's now */ 03531 tv.tv_usec += 1000; 03532 03533 now = ast_tvdiff_ms(tv, pvt->rxcore); 03534 03535 if(now >= (next = jb_next(pvt->jb))) { 03536 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 03537 switch(ret) { 03538 case JB_OK: 03539 fr = frame.data; 03540 __do_deliver(fr); 03541 /* __do_deliver() can cause the call to disappear */ 03542 pvt = iaxs[callno]; 03543 break; 03544 case JB_INTERP: 03545 { 03546 struct ast_frame af = { 0, }; 03547 03548 /* create an interpolation frame */ 03549 af.frametype = AST_FRAME_VOICE; 03550 af.subclass = pvt->voiceformat; 03551 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03552 af.src = "IAX2 JB interpolation"; 03553 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03554 af.offset = AST_FRIENDLY_OFFSET; 03555 03556 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03557 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03558 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03559 iax2_queue_frame(callno, &af); 03560 /* iax2_queue_frame() could cause the call to disappear */ 03561 pvt = iaxs[callno]; 03562 } 03563 } 03564 break; 03565 case JB_DROP: 03566 iax2_frame_free(frame.data); 03567 break; 03568 case JB_NOFRAME: 03569 case JB_EMPTY: 03570 /* do nothing */ 03571 break; 03572 default: 03573 /* shouldn't happen */ 03574 break; 03575 } 03576 } 03577 if (pvt) 03578 update_jbsched(pvt); 03579 ast_mutex_unlock(&iaxsl[callno]); 03580 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7102 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
07103 { 07104 struct iax2_registry *reg = (struct iax2_registry *)data; 07105 reg->expire = -1; 07106 iax2_do_register(reg); 07107 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10338 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().
10339 { 10340 struct iax2_peer *peer = (struct iax2_peer *)data; 10341 int callno; 10342 10343 if (peer->lastms > -1) { 10344 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 10345 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 10346 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 10347 } 10348 if ((callno = peer->callno) > 0) { 10349 ast_mutex_lock(&iaxsl[callno]); 10350 iax2_destroy(callno); 10351 ast_mutex_unlock(&iaxsl[callno]); 10352 } 10353 peer->callno = 0; 10354 peer->lastms = -1; 10355 /* Try again quickly */ 10356 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10357 if (peer->pokeexpire == -1) 10358 peer_unref(peer); 10359 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7872 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
07873 { 07874 struct iax2_peer *peer = (struct iax2_peer *)data; 07875 iax2_poke_peer(peer, 0); 07876 peer_unref(peer); 07877 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5824 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().
05825 { 05826 regex_t regexbuf; 05827 int havepattern = 0; 05828 int total_peers = 0; 05829 int online_peers = 0; 05830 int offline_peers = 0; 05831 int unmonitored_peers = 0; 05832 struct ao2_iterator i; 05833 05834 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 05835 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 05836 05837 struct iax2_peer *peer = NULL; 05838 char name[256]; 05839 int registeredonly=0; 05840 char *term = manager ? "\r\n" : "\n"; 05841 05842 switch (argc) { 05843 case 6: 05844 if (!strcasecmp(argv[3], "registered")) 05845 registeredonly = 1; 05846 else 05847 return RESULT_SHOWUSAGE; 05848 if (!strcasecmp(argv[4], "like")) { 05849 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 05850 return RESULT_SHOWUSAGE; 05851 havepattern = 1; 05852 } else 05853 return RESULT_SHOWUSAGE; 05854 break; 05855 case 5: 05856 if (!strcasecmp(argv[3], "like")) { 05857 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05858 return RESULT_SHOWUSAGE; 05859 havepattern = 1; 05860 } else 05861 return RESULT_SHOWUSAGE; 05862 break; 05863 case 4: 05864 if (!strcasecmp(argv[3], "registered")) 05865 registeredonly = 1; 05866 else 05867 return RESULT_SHOWUSAGE; 05868 break; 05869 case 3: 05870 break; 05871 default: 05872 return RESULT_SHOWUSAGE; 05873 } 05874 05875 05876 if (s) 05877 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05878 else 05879 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05880 05881 i = ao2_iterator_init(peers, 0); 05882 for (peer = ao2_iterator_next(&i); peer; 05883 peer_unref(peer), peer = ao2_iterator_next(&i)) { 05884 char nm[20]; 05885 char status[20]; 05886 char srch[2000]; 05887 int retstatus; 05888 05889 if (registeredonly && !peer->addr.sin_addr.s_addr) 05890 continue; 05891 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 05892 continue; 05893 05894 if (!ast_strlen_zero(peer->username)) 05895 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 05896 else 05897 ast_copy_string(name, peer->name, sizeof(name)); 05898 05899 retstatus = peer_status(peer, status, sizeof(status)); 05900 if (retstatus > 0) 05901 online_peers++; 05902 else if (!retstatus) 05903 offline_peers++; 05904 else 05905 unmonitored_peers++; 05906 05907 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 05908 05909 snprintf(srch, sizeof(srch), FORMAT, name, 05910 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05911 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05912 nm, 05913 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05914 peer->encmethods ? "(E)" : " ", status, term); 05915 05916 if (s) 05917 astman_append(s, FORMAT, name, 05918 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 05919 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05920 nm, 05921 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05922 peer->encmethods ? "(E)" : " ", status, term); 05923 else 05924 ast_cli(fd, FORMAT, name, 05925 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05926 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05927 nm, 05928 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05929 peer->encmethods ? "(E)" : " ", status, term); 05930 total_peers++; 05931 } 05932 ao2_iterator_destroy(&i); 05933 05934 if (s) 05935 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05936 else 05937 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05938 05939 if (havepattern) 05940 regfree(®exbuf); 05941 05942 return RESULT_SUCCESS; 05943 #undef FORMAT 05944 #undef FORMAT2 05945 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 12886 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1115 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.
01116 { 01117 struct iax2_thread *thread = NULL; 01118 static time_t lasterror; 01119 static time_t t; 01120 01121 thread = find_idle_thread(); 01122 01123 if (thread != NULL) { 01124 thread->schedfunc = func; 01125 thread->scheddata = data; 01126 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01127 #ifdef DEBUG_SCHED_MULTITHREAD 01128 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01129 #endif 01130 signal_condition(&thread->lock, &thread->cond); 01131 return 0; 01132 } 01133 time(&t); 01134 if (t != lasterror && option_debug) 01135 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 01136 lasterror = t; 01137 01138 return -1; 01139 }
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 6350 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().
06352 { 06353 struct ast_frame f = { 0, }; 06354 int res = 0; 06355 f.frametype = type; 06356 f.subclass = command; 06357 f.datalen = datalen; 06358 f.src = __FUNCTION__; 06359 f.data = (void *) data; 06360 06361 if ((res = queue_signalling(i, &f)) <= 0) { 06362 return res; 06363 } 06364 return iax2_send(i, &f, ts, seqno, now, transfer, final); 06365 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1202 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().
01203 { 01204 int callno = (long) data; 01205 01206 ast_mutex_lock(&iaxsl[callno]); 01207 01208 if (iaxs[callno]) { 01209 if (iaxs[callno]->peercallno) { 01210 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01211 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01212 } else { 01213 /* I am the schedule, so I'm allowed to do this */ 01214 iaxs[callno]->lagid = -1; 01215 } 01216 } else { 01217 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); 01218 } 01219 01220 ast_mutex_unlock(&iaxsl[callno]); 01221 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1157 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().
01158 { 01159 int callno = (long) data; 01160 01161 ast_mutex_lock(&iaxsl[callno]); 01162 01163 if (iaxs[callno]) { 01164 if (iaxs[callno]->peercallno) { 01165 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01166 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01167 } else { 01168 /* I am the schedule, so I'm allowed to do this */ 01169 iaxs[callno]->pingid = -1; 01170 } 01171 } else if (option_debug > 0) { 01172 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); 01173 } 01174 01175 ast_mutex_unlock(&iaxsl[callno]); 01176 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 12559 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(), thread, users, and waresl.
12560 { 12561 struct iax2_thread *thread = NULL; 12562 int x; 12563 12564 unloading = 1; 12565 12566 /* Make sure threads do not hold shared resources when they are canceled */ 12567 12568 /* Grab the sched lock resource to keep it away from threads about to die */ 12569 /* Cancel the network thread, close the net socket */ 12570 if (netthreadid != AST_PTHREADT_NULL) { 12571 AST_LIST_LOCK(&iaxq.queue); 12572 ast_mutex_lock(&sched_lock); 12573 pthread_cancel(netthreadid); 12574 ast_cond_signal(&sched_cond); 12575 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 12576 AST_LIST_UNLOCK(&iaxq.queue); 12577 pthread_join(netthreadid, NULL); 12578 } 12579 if (schedthreadid != AST_PTHREADT_NULL) { 12580 ast_mutex_lock(&sched_lock); 12581 pthread_cancel(schedthreadid); 12582 ast_cond_signal(&sched_cond); 12583 ast_mutex_unlock(&sched_lock); 12584 pthread_join(schedthreadid, NULL); 12585 } 12586 12587 /* Call for all threads to halt */ 12588 AST_LIST_LOCK(&idle_list); 12589 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 12590 AST_LIST_REMOVE_CURRENT(&idle_list, list); 12591 pthread_cancel(thread->threadid); 12592 } 12593 AST_LIST_TRAVERSE_SAFE_END 12594 AST_LIST_UNLOCK(&idle_list); 12595 12596 AST_LIST_LOCK(&active_list); 12597 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 12598 AST_LIST_REMOVE_CURRENT(&active_list, list); 12599 pthread_cancel(thread->threadid); 12600 } 12601 AST_LIST_TRAVERSE_SAFE_END 12602 AST_LIST_UNLOCK(&active_list); 12603 12604 AST_LIST_LOCK(&dynamic_list); 12605 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 12606 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 12607 pthread_cancel(thread->threadid); 12608 } 12609 AST_LIST_TRAVERSE_SAFE_END 12610 AST_LIST_UNLOCK(&dynamic_list); 12611 12612 AST_LIST_HEAD_DESTROY(&iaxq.queue); 12613 12614 /* Wait for threads to exit */ 12615 while (0 < iaxactivethreadcount) { 12616 usleep(10000); 12617 } 12618 12619 ast_netsock_release(netsock); 12620 ast_netsock_release(outsock); 12621 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 12622 if (iaxs[x]) { 12623 iax2_destroy(x); 12624 } 12625 } 12626 ast_manager_unregister( "IAXpeers" ); 12627 ast_manager_unregister( "IAXnetstats" ); 12628 ast_unregister_application(papp); 12629 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12630 ast_unregister_switch(&iax2_switch); 12631 ast_channel_unregister(&iax2_tech); 12632 delete_users(); 12633 iax_provision_unload(); 12634 reload_firmware(1); 12635 12636 ast_mutex_destroy(&waresl.lock); 12637 12638 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12639 ast_mutex_destroy(&iaxsl[x]); 12640 } 12641 12642 ao2_ref(peers, -1); 12643 ao2_ref(users, -1); 12644 ao2_ref(iax_peercallno_pvts, -1); 12645 ao2_ref(iax_transfercallno_pvts, -1); 12646 ao2_ref(peercnts, -1); 12647 ao2_ref(callno_limits, -1); 12648 ao2_ref(calltoken_ignores, -1); 12649 ao2_ref(callno_pool, -1); 12650 ao2_ref(callno_pool_trunk, -1); 12651 sched_context_destroy(sched); 12652 12653 return 0; 12654 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 12886 of file chan_iax2.c.
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2175 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), calltoken_ignores, addr_range::ha, and LOG_WARNING.
Referenced by set_config().
02176 { 02177 struct addr_range tmp; 02178 struct addr_range *addr_range = NULL; 02179 struct ast_ha *ha = NULL; 02180 02181 if (ast_strlen_zero(addr)) { 02182 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02183 return -1; 02184 } 02185 02186 ha = ast_append_ha("permit", addr, NULL); 02187 02188 /* check for valid config information */ 02189 if (!ha) { 02190 ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr); 02191 return -1; 02192 } 02193 02194 ast_copy_ha(ha, &tmp.ha); 02195 /* find or create the addr_range */ 02196 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02197 ao2_lock(addr_range); 02198 addr_range->delme = 0; 02199 ao2_unlock(addr_range); 02200 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02201 /* copy over config data into addr_range object */ 02202 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02203 ao2_link(calltoken_ignores, addr_range); 02204 } else { 02205 ast_free_ha(ha); 02206 return -1; 02207 } 02208 02209 ast_free_ha(ha); 02210 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02211 02212 return 0; 02213 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4152 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().
04153 { 04154 /* first make sure their are two empty bytes left in ied->buf */ 04155 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04156 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04157 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04158 pvt->calltoken_ie_len = 2; 04159 } 04160 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1829 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
01830 { 01831 struct addr_range *lim1 = obj, *lim2 = arg; 01832 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) && 01833 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ? 01834 CMP_MATCH | CMP_STOP : 0; 01835 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1816 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01817 { 01818 struct addr_range *lim = obj; 01819 lim->delme = 1; 01820 return 0; 01821 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1823 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01824 { 01825 const struct addr_range *lim = obj; 01826 return abs((int) lim->ha.netaddr.s_addr); 01827 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1849 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
01850 { 01851 struct addr_range *addr_range = obj; 01852 struct sockaddr_in *sin = arg; 01853 01854 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 01855 return CMP_MATCH | CMP_STOP; 01856 } 01857 return 0; 01858 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 6406 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
06407 { 06408 while(con) { 06409 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 06410 return -1; 06411 con = con->next; 06412 } 06413 return 0; 06414 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 6166 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().
06167 { 06168 int x; 06169 int numchans = 0; 06170 char first_message[10] = { 0, }; 06171 char last_message[10] = { 0, }; 06172 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06173 ast_mutex_lock(&iaxsl[x]); 06174 if (iaxs[x]) { 06175 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06176 char *fmt; 06177 jb_info jbinfo; 06178 06179 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06180 jb_getinfo(iaxs[x]->jb, &jbinfo); 06181 localjitter = jbinfo.jitter; 06182 localdelay = jbinfo.current - jbinfo.min; 06183 locallost = jbinfo.frames_lost; 06184 locallosspct = jbinfo.losspct/1000; 06185 localdropped = jbinfo.frames_dropped; 06186 localooo = jbinfo.frames_ooo; 06187 } else { 06188 localjitter = -1; 06189 localdelay = 0; 06190 locallost = -1; 06191 locallosspct = -1; 06192 localdropped = 0; 06193 localooo = -1; 06194 } 06195 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06196 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06197 if (limit_fmt) 06198 fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"; 06199 else 06200 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"; 06201 if (s) 06202 06203 astman_append(s, fmt, 06204 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06205 iaxs[x]->pingtime, 06206 localjitter, 06207 localdelay, 06208 locallost, 06209 locallosspct, 06210 localdropped, 06211 localooo, 06212 iaxs[x]->frames_received/1000, 06213 iaxs[x]->remote_rr.jitter, 06214 iaxs[x]->remote_rr.delay, 06215 iaxs[x]->remote_rr.losscnt, 06216 iaxs[x]->remote_rr.losspct, 06217 iaxs[x]->remote_rr.dropped, 06218 iaxs[x]->remote_rr.ooo, 06219 iaxs[x]->remote_rr.packets/1000, 06220 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06221 first_message, 06222 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06223 last_message); 06224 else 06225 ast_cli(fd, fmt, 06226 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06227 iaxs[x]->pingtime, 06228 localjitter, 06229 localdelay, 06230 locallost, 06231 locallosspct, 06232 localdropped, 06233 localooo, 06234 iaxs[x]->frames_received/1000, 06235 iaxs[x]->remote_rr.jitter, 06236 iaxs[x]->remote_rr.delay, 06237 iaxs[x]->remote_rr.losscnt, 06238 iaxs[x]->remote_rr.losspct, 06239 iaxs[x]->remote_rr.dropped, 06240 iaxs[x]->remote_rr.ooo, 06241 iaxs[x]->remote_rr.packets/1000, 06242 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06243 first_message, 06244 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06245 last_message); 06246 numchans++; 06247 } 06248 ast_mutex_unlock(&iaxsl[x]); 06249 } 06250 return numchans; 06251 }
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 4989 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().
04990 { 04991 struct ast_channel *tmp; 04992 struct chan_iax2_pvt *i; 04993 struct ast_variable *v = NULL; 04994 04995 if (!(i = iaxs[callno])) { 04996 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 04997 return NULL; 04998 } 04999 05000 /* Don't hold call lock */ 05001 ast_mutex_unlock(&iaxsl[callno]); 05002 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); 05003 ast_mutex_lock(&iaxsl[callno]); 05004 if (i != iaxs[callno]) { 05005 if (tmp) { 05006 /* unlock and relock iaxsl[callno] to preserve locking order */ 05007 ast_mutex_unlock(&iaxsl[callno]); 05008 ast_channel_free(tmp); 05009 ast_mutex_lock(&iaxsl[callno]); 05010 } 05011 return NULL; 05012 } 05013 05014 if (!tmp) 05015 return NULL; 05016 tmp->tech = &iax2_tech; 05017 /* We can support any format by default, until we get restricted */ 05018 tmp->nativeformats = capability; 05019 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05020 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05021 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05022 05023 /* Don't use ast_set_callerid() here because it will 05024 * generate a NewCallerID event before the NewChannel event */ 05025 if (!ast_strlen_zero(i->ani)) 05026 tmp->cid.cid_ani = ast_strdup(i->ani); 05027 else 05028 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05029 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05030 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05031 tmp->cid.cid_pres = i->calling_pres; 05032 tmp->cid.cid_ton = i->calling_ton; 05033 tmp->cid.cid_tns = i->calling_tns; 05034 if (!ast_strlen_zero(i->language)) 05035 ast_string_field_set(tmp, language, i->language); 05036 if (!ast_strlen_zero(i->accountcode)) 05037 ast_string_field_set(tmp, accountcode, i->accountcode); 05038 if (i->amaflags) 05039 tmp->amaflags = i->amaflags; 05040 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05041 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05042 if (i->adsi) 05043 tmp->adsicpe = i->peeradsicpe; 05044 else 05045 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05046 i->owner = tmp; 05047 i->capability = capability; 05048 05049 for (v = i->vars ; v ; v = v->next) 05050 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05051 05052 if (state != AST_STATE_DOWN) { 05053 if (ast_pbx_start(tmp)) { 05054 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05055 ast_hangup(tmp); 05056 i->owner = NULL; 05057 return NULL; 05058 } 05059 } 05060 05061 ast_module_ref(ast_module_info->self); 05062 05063 return tmp; 05064 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3159 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03160 { 03161 #ifdef SCHED_MULTITHREADED 03162 if (schedule_action(__attempt_transmit, data)) 03163 #endif 03164 __attempt_transmit(data); 03165 return 0; 03166 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 7794 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().
07795 { 07796 /* Schedule sending the authentication failure in one second, to prevent 07797 guessing */ 07798 if (iaxs[callno]) { 07799 iaxs[callno]->authfail = failcode; 07800 if (delayreject) { 07801 AST_SCHED_DEL(sched, iaxs[callno]->authid); 07802 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 07803 } else 07804 auth_reject((void *)(long)callno); 07805 } 07806 return 0; 07807 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 7780 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().
07781 { 07782 int callno = (int)(long)(data); 07783 ast_mutex_lock(&iaxsl[callno]); 07784 if (iaxs[callno]) 07785 iaxs[callno]->authid = -1; 07786 ast_mutex_unlock(&iaxsl[callno]); 07787 #ifdef SCHED_MULTITHREADED 07788 if (schedule_action(__auth_reject, data)) 07789 #endif 07790 __auth_reject(data); 07791 return 0; 07792 }
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 6969 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().
06970 { 06971 int res = -1; 06972 int x; 06973 if (!ast_strlen_zero(keyn)) { 06974 if (!(authmethods & IAX_AUTH_RSA)) { 06975 if (ast_strlen_zero(secret)) 06976 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)); 06977 } else if (ast_strlen_zero(challenge)) { 06978 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 06979 } else { 06980 char sig[256]; 06981 struct ast_key *key; 06982 key = ast_key_get(keyn, AST_KEY_PRIVATE); 06983 if (!key) { 06984 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 06985 } else { 06986 if (ast_sign(key, (char*)challenge, sig)) { 06987 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 06988 res = -1; 06989 } else { 06990 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 06991 res = 0; 06992 } 06993 } 06994 } 06995 } 06996 /* Fall back */ 06997 if (res && !ast_strlen_zero(secret)) { 06998 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 06999 struct MD5Context md5; 07000 unsigned char digest[16]; 07001 char digres[128]; 07002 MD5Init(&md5); 07003 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 07004 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 07005 MD5Final(digest, &md5); 07006 /* If they support md5, authenticate with it. */ 07007 for (x=0;x<16;x++) 07008 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 07009 if (pvt) { 07010 build_encryption_keys(digest, pvt); 07011 } 07012 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 07013 res = 0; 07014 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 07015 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 07016 res = 0; 07017 } else 07018 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 07019 } 07020 return res; 07021 }
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 7027 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().
07028 { 07029 struct iax2_peer *peer = NULL; 07030 /* Start pessimistic */ 07031 int res = -1; 07032 int authmethods = 0; 07033 struct iax_ie_data ied; 07034 uint16_t callno = p->callno; 07035 07036 memset(&ied, 0, sizeof(ied)); 07037 07038 if (ies->username) 07039 ast_string_field_set(p, username, ies->username); 07040 if (ies->challenge) 07041 ast_string_field_set(p, challenge, ies->challenge); 07042 if (ies->authmethods) 07043 authmethods = ies->authmethods; 07044 if (authmethods & IAX_AUTH_MD5) 07045 merge_encryption(p, ies->encmethods); 07046 else 07047 p->encmethods = 0; 07048 07049 /* Check for override RSA authentication first */ 07050 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07051 /* Normal password authentication */ 07052 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07053 } else { 07054 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07055 while ((peer = ao2_iterator_next(&i))) { 07056 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07057 /* No peer specified at our end, or this is the peer */ 07058 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07059 /* No username specified in peer rule, or this is the right username */ 07060 && (!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))) 07061 /* No specified host, or this is our host */ 07062 ) { 07063 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07064 if (!res) { 07065 peer_unref(peer); 07066 break; 07067 } 07068 } 07069 peer_unref(peer); 07070 } 07071 ao2_iterator_destroy(&i); 07072 if (!peer) { 07073 /* We checked our list and didn't find one. It's unlikely, but possible, 07074 that we're trying to authenticate *to* a realtime peer */ 07075 const char *peer_name = ast_strdupa(p->peer); 07076 ast_mutex_unlock(&iaxsl[callno]); 07077 if ((peer = realtime_peer(peer_name, NULL))) { 07078 ast_mutex_lock(&iaxsl[callno]); 07079 if (!(p = iaxs[callno])) { 07080 peer_unref(peer); 07081 return -1; 07082 } 07083 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07084 peer_unref(peer); 07085 } 07086 if (!peer) { 07087 ast_mutex_lock(&iaxsl[callno]); 07088 if (!(p = iaxs[callno])) 07089 return -1; 07090 } 07091 } 07092 } 07093 if (ies->encmethods) 07094 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07095 if (!res) 07096 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 07097 return res; 07098 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 6678 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().
06679 { 06680 struct iax_ie_data ied; 06681 int res = -1, authreq_restrict = 0; 06682 char challenge[10]; 06683 struct chan_iax2_pvt *p = iaxs[call_num]; 06684 06685 memset(&ied, 0, sizeof(ied)); 06686 06687 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 06688 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06689 struct iax2_user *user, tmp_user = { 06690 .name = p->username, 06691 }; 06692 06693 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06694 if (user) { 06695 if (user->curauthreq == user->maxauthreq) 06696 authreq_restrict = 1; 06697 else 06698 user->curauthreq++; 06699 user = user_unref(user); 06700 } 06701 } 06702 06703 /* If the AUTHREQ limit test failed, send back an error */ 06704 if (authreq_restrict) { 06705 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 06706 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 06707 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 06708 return 0; 06709 } 06710 06711 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06712 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 06713 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06714 ast_string_field_set(p, challenge, challenge); 06715 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 06716 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 06717 } 06718 if (p->encmethods) 06719 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 06720 06721 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 06722 06723 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 06724 06725 if (p->encmethods) 06726 ast_set_flag(p, IAX_ENCRYPTED); 06727 06728 return res; 06729 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6731 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().
06732 { 06733 char requeststr[256]; 06734 char md5secret[256] = ""; 06735 char secret[256] = ""; 06736 char rsasecret[256] = ""; 06737 int res = -1; 06738 int x; 06739 struct iax2_user *user, tmp_user = { 06740 .name = p->username, 06741 }; 06742 06743 if (p->authrej) { 06744 return res; 06745 } 06746 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06747 if (user) { 06748 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06749 ast_atomic_fetchadd_int(&user->curauthreq, -1); 06750 ast_clear_flag(p, IAX_MAXAUTHREQ); 06751 } 06752 ast_string_field_set(p, host, user->name); 06753 user = user_unref(user); 06754 } 06755 06756 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 06757 return res; 06758 if (ies->password) 06759 ast_copy_string(secret, ies->password, sizeof(secret)); 06760 if (ies->md5_result) 06761 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06762 if (ies->rsa_result) 06763 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06764 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 06765 struct ast_key *key; 06766 char *keyn; 06767 char tmpkey[256]; 06768 char *stringp=NULL; 06769 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 06770 stringp=tmpkey; 06771 keyn = strsep(&stringp, ":"); 06772 while(keyn) { 06773 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06774 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 06775 res = 0; 06776 break; 06777 } else if (!key) 06778 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 06779 keyn = strsep(&stringp, ":"); 06780 } 06781 } else if (p->authmethods & IAX_AUTH_MD5) { 06782 struct MD5Context md5; 06783 unsigned char digest[16]; 06784 char *tmppw, *stringp; 06785 06786 tmppw = ast_strdupa(p->secret); 06787 stringp = tmppw; 06788 while((tmppw = strsep(&stringp, ";"))) { 06789 MD5Init(&md5); 06790 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 06791 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06792 MD5Final(digest, &md5); 06793 /* If they support md5, authenticate with it. */ 06794 for (x=0;x<16;x++) 06795 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06796 if (!strcasecmp(requeststr, md5secret)) { 06797 res = 0; 06798 break; 06799 } 06800 } 06801 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 06802 if (!strcmp(secret, p->secret)) 06803 res = 0; 06804 } 06805 return res; 06806 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4087 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
04088 { 04089 #ifdef SCHED_MULTITHREADED 04090 if (schedule_action(__auto_congest, data)) 04091 #endif 04092 __auto_congest(data); 04093 return 0; 04094 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 7824 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().
07825 { 07826 int callno = (int)(long)(data); 07827 ast_mutex_lock(&iaxsl[callno]); 07828 if (iaxs[callno]) { 07829 iaxs[callno]->autoid = -1; 07830 } 07831 ast_mutex_unlock(&iaxsl[callno]); 07832 #ifdef SCHED_MULTITHREADED 07833 if (schedule_action(__auto_hangup, data)) 07834 #endif 07835 __auto_hangup(data); 07836 return 0; 07837 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2122 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by set_config().
02123 { 02124 struct addr_range *addr_range = NULL; 02125 struct addr_range tmp; 02126 struct ast_ha *ha; 02127 int limit; 02128 int found; 02129 02130 for (; v; v = v->next) { 02131 limit = -1; 02132 found = 0; 02133 ha = ast_append_ha("permit", v->name, NULL); 02134 02135 /* check for valid config information */ 02136 if (!ha) { 02137 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02138 continue; 02139 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02140 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02141 ast_free_ha(ha); 02142 continue; 02143 } 02144 02145 ast_copy_ha(ha, &tmp.ha); 02146 /* find or create the addr_range */ 02147 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02148 ao2_lock(addr_range); 02149 found = 1; 02150 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02151 ast_free_ha(ha); 02152 return; /* out of memory */ 02153 } 02154 02155 /* copy over config data into addr_range object */ 02156 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02157 ast_free_ha(ha); /* cleanup the tmp ha */ 02158 addr_range->limit = limit; 02159 addr_range->delme = 0; 02160 02161 /* cleanup */ 02162 if (found) { 02163 ao2_unlock(addr_range); 02164 } else { 02165 ao2_link(callno_limits, addr_range); 02166 } 02167 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02168 } 02169 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 10671 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
10672 { 10673 struct iax2_context *con; 10674 10675 if ((con = ast_calloc(1, sizeof(*con)))) 10676 ast_copy_string(con->context, context, sizeof(con->context)); 10677 10678 return con; 10679 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5393 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().
05394 { 05395 /* it is required to hold the corresponding decrypt key to our encrypt key 05396 * in the pvt struct because queued frames occasionally need to be decrypted and 05397 * re-encrypted when updated for a retransmission */ 05398 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05399 aes_encrypt_key128(digest, &pvt->ecx); 05400 aes_decrypt_key128(digest, &pvt->mydcx); 05401 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5387 of file chan_iax2.c.
References aes_decrypt_key128(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05388 { 05389 build_ecx_key(digest, pvt); 05390 aes_decrypt_key128(digest, &pvt->dcx); 05391 }
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 10818 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.
10819 { 10820 struct iax2_peer *peer = NULL; 10821 struct ast_ha *oldha = NULL; 10822 int maskfound=0; 10823 int found=0; 10824 int firstpass=1; 10825 struct iax2_peer tmp_peer = { 10826 .name = name, 10827 }; 10828 10829 if (!temponly) { 10830 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 10831 if (peer && !ast_test_flag(peer, IAX_DELME)) 10832 firstpass = 0; 10833 } 10834 10835 if (peer) { 10836 found++; 10837 if (firstpass) { 10838 oldha = peer->ha; 10839 peer->ha = NULL; 10840 } 10841 unlink_peer(peer); 10842 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 10843 peer->expire = -1; 10844 peer->pokeexpire = -1; 10845 peer->sockfd = defaultsockfd; 10846 if (ast_string_field_init(peer, 32)) 10847 peer = peer_unref(peer); 10848 } 10849 10850 if (peer) { 10851 if (firstpass) { 10852 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10853 peer->encmethods = iax2_encryption; 10854 peer->adsi = adsi; 10855 ast_string_field_set(peer,secret,""); 10856 if (!found) { 10857 ast_string_field_set(peer, name, name); 10858 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10859 peer->expiry = min_reg_expire; 10860 } 10861 peer->prefs = prefs; 10862 peer->capability = iax2_capability; 10863 peer->smoothing = 0; 10864 peer->pokefreqok = DEFAULT_FREQ_OK; 10865 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 10866 peer->maxcallno = 0; 10867 peercnt_modify(0, 0, &peer->addr); 10868 peer->calltoken_required = CALLTOKEN_DEFAULT; 10869 ast_string_field_set(peer,context,""); 10870 ast_string_field_set(peer,peercontext,""); 10871 ast_clear_flag(peer, IAX_HASCALLERID); 10872 ast_string_field_set(peer, cid_name, ""); 10873 ast_string_field_set(peer, cid_num, ""); 10874 ast_string_field_set(peer, mohinterpret, mohinterpret); 10875 ast_string_field_set(peer, mohsuggest, mohsuggest); 10876 } 10877 10878 if (!v) { 10879 v = alt; 10880 alt = NULL; 10881 } 10882 while(v) { 10883 if (!strcasecmp(v->name, "secret")) { 10884 ast_string_field_set(peer, secret, v->value); 10885 } else if (!strcasecmp(v->name, "mailbox")) { 10886 ast_string_field_set(peer, mailbox, v->value); 10887 } else if (!strcasecmp(v->name, "hasvoicemail")) { 10888 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 10889 ast_string_field_set(peer, mailbox, name); 10890 } 10891 } else if (!strcasecmp(v->name, "mohinterpret")) { 10892 ast_string_field_set(peer, mohinterpret, v->value); 10893 } else if (!strcasecmp(v->name, "mohsuggest")) { 10894 ast_string_field_set(peer, mohsuggest, v->value); 10895 } else if (!strcasecmp(v->name, "dbsecret")) { 10896 ast_string_field_set(peer, dbsecret, v->value); 10897 } else if (!strcasecmp(v->name, "trunk")) { 10898 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 10899 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 10900 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 10901 ast_clear_flag(peer, IAX_TRUNK); 10902 } 10903 } else if (!strcasecmp(v->name, "auth")) { 10904 peer->authmethods = get_auth_methods(v->value); 10905 } else if (!strcasecmp(v->name, "encryption")) { 10906 peer->encmethods = get_encrypt_methods(v->value); 10907 } else if (!strcasecmp(v->name, "notransfer")) { 10908 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10909 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 10910 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 10911 } else if (!strcasecmp(v->name, "transfer")) { 10912 if (!strcasecmp(v->value, "mediaonly")) { 10913 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10914 } else if (ast_true(v->value)) { 10915 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10916 } else 10917 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10918 } else if (!strcasecmp(v->name, "jitterbuffer")) { 10919 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 10920 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 10921 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 10922 } else if (!strcasecmp(v->name, "host")) { 10923 if (!strcasecmp(v->value, "dynamic")) { 10924 /* They'll register with us */ 10925 ast_set_flag(peer, IAX_DYNAMIC); 10926 if (!found) { 10927 /* Initialize stuff iff we're not found, otherwise 10928 we keep going with what we had */ 10929 memset(&peer->addr.sin_addr, 0, 4); 10930 if (peer->addr.sin_port) { 10931 /* If we've already got a port, make it the default rather than absolute */ 10932 peer->defaddr.sin_port = peer->addr.sin_port; 10933 peer->addr.sin_port = 0; 10934 } 10935 } 10936 } else { 10937 /* Non-dynamic. Make sure we become that way if we're not */ 10938 AST_SCHED_DEL(sched, peer->expire); 10939 ast_clear_flag(peer, IAX_DYNAMIC); 10940 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 10941 return peer_unref(peer); 10942 if (!peer->addr.sin_port) 10943 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10944 } 10945 if (!maskfound) 10946 inet_aton("255.255.255.255", &peer->mask); 10947 } else if (!strcasecmp(v->name, "defaultip")) { 10948 if (ast_get_ip(&peer->defaddr, v->value)) 10949 return peer_unref(peer); 10950 } else if (!strcasecmp(v->name, "sourceaddress")) { 10951 peer_set_srcaddr(peer, v->value); 10952 } else if (!strcasecmp(v->name, "permit") || 10953 !strcasecmp(v->name, "deny")) { 10954 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 10955 } else if (!strcasecmp(v->name, "mask")) { 10956 maskfound++; 10957 inet_aton(v->value, &peer->mask); 10958 } else if (!strcasecmp(v->name, "context")) { 10959 ast_string_field_set(peer, context, v->value); 10960 } else if (!strcasecmp(v->name, "regexten")) { 10961 ast_string_field_set(peer, regexten, v->value); 10962 } else if (!strcasecmp(v->name, "peercontext")) { 10963 ast_string_field_set(peer, peercontext, v->value); 10964 } else if (!strcasecmp(v->name, "port")) { 10965 if (ast_test_flag(peer, IAX_DYNAMIC)) 10966 peer->defaddr.sin_port = htons(atoi(v->value)); 10967 else 10968 peer->addr.sin_port = htons(atoi(v->value)); 10969 } else if (!strcasecmp(v->name, "username")) { 10970 ast_string_field_set(peer, username, v->value); 10971 } else if (!strcasecmp(v->name, "allow")) { 10972 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 10973 } else if (!strcasecmp(v->name, "disallow")) { 10974 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 10975 } else if (!strcasecmp(v->name, "callerid")) { 10976 if (!ast_strlen_zero(v->value)) { 10977 char name2[80]; 10978 char num2[80]; 10979 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 10980 ast_string_field_set(peer, cid_name, name2); 10981 ast_string_field_set(peer, cid_num, num2); 10982 } else { 10983 ast_string_field_set(peer, cid_name, ""); 10984 ast_string_field_set(peer, cid_num, ""); 10985 } 10986 ast_set_flag(peer, IAX_HASCALLERID); 10987 } else if (!strcasecmp(v->name, "fullname")) { 10988 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 10989 ast_set_flag(peer, IAX_HASCALLERID); 10990 } else if (!strcasecmp(v->name, "cid_number")) { 10991 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 10992 ast_set_flag(peer, IAX_HASCALLERID); 10993 } else if (!strcasecmp(v->name, "sendani")) { 10994 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 10995 } else if (!strcasecmp(v->name, "inkeys")) { 10996 ast_string_field_set(peer, inkeys, v->value); 10997 } else if (!strcasecmp(v->name, "outkey")) { 10998 ast_string_field_set(peer, outkey, v->value); 10999 } else if (!strcasecmp(v->name, "qualify")) { 11000 if (!strcasecmp(v->value, "no")) { 11001 peer->maxms = 0; 11002 } else if (!strcasecmp(v->value, "yes")) { 11003 peer->maxms = DEFAULT_MAXMS; 11004 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 11005 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); 11006 peer->maxms = 0; 11007 } 11008 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 11009 peer->smoothing = ast_true(v->value); 11010 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 11011 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 11012 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); 11013 } 11014 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 11015 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 11016 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); 11017 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 11018 } else if (!strcasecmp(v->name, "timezone")) { 11019 ast_string_field_set(peer, zonetag, v->value); 11020 } else if (!strcasecmp(v->name, "adsi")) { 11021 peer->adsi = ast_true(v->value); 11022 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11023 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 11024 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 11025 } else { 11026 peercnt_modify(1, peer->maxcallno, &peer->addr); 11027 } 11028 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11029 /* default is required unless in optional ip list */ 11030 if (ast_false(v->value)) { 11031 peer->calltoken_required = CALLTOKEN_NO; 11032 } else if (!strcasecmp(v->value, "auto")) { 11033 peer->calltoken_required = CALLTOKEN_AUTO; 11034 } else if (ast_true(v->value)) { 11035 peer->calltoken_required = CALLTOKEN_YES; 11036 } else { 11037 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11038 } 11039 } /* else if (strcasecmp(v->name,"type")) */ 11040 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11041 v = v->next; 11042 if (!v) { 11043 v = alt; 11044 alt = NULL; 11045 } 11046 } 11047 if (!peer->authmethods) 11048 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11049 ast_clear_flag(peer, IAX_DELME); 11050 /* Make sure these are IPv4 addresses */ 11051 peer->addr.sin_family = AF_INET; 11052 } 11053 if (oldha) 11054 ast_free_ha(oldha); 11055 return peer; 11056 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 5377 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05378 { 05379 long tmp; 05380 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05381 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05382 buf += sizeof(tmp); 05383 len -= sizeof(tmp); 05384 } 05385 }
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 11072 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.
11073 { 11074 struct iax2_user *user = NULL; 11075 struct iax2_context *con, *conl = NULL; 11076 struct ast_ha *oldha = NULL; 11077 struct iax2_context *oldcon = NULL; 11078 int format; 11079 int firstpass=1; 11080 int oldcurauthreq = 0; 11081 char *varname = NULL, *varval = NULL; 11082 struct ast_variable *tmpvar = NULL; 11083 struct iax2_user tmp_user = { 11084 .name = name, 11085 }; 11086 11087 if (!temponly) { 11088 user = ao2_find(users, &tmp_user, OBJ_POINTER); 11089 if (user && !ast_test_flag(user, IAX_DELME)) 11090 firstpass = 0; 11091 } 11092 11093 if (user) { 11094 if (firstpass) { 11095 oldcurauthreq = user->curauthreq; 11096 oldha = user->ha; 11097 oldcon = user->contexts; 11098 user->ha = NULL; 11099 user->contexts = NULL; 11100 } 11101 /* Already in the list, remove it and it will be added back (or FREE'd) */ 11102 ao2_unlink(users, user); 11103 } else { 11104 user = ao2_alloc(sizeof(*user), user_destructor); 11105 } 11106 11107 if (user) { 11108 if (firstpass) { 11109 ast_string_field_free_memory(user); 11110 memset(user, 0, sizeof(struct iax2_user)); 11111 if (ast_string_field_init(user, 32)) { 11112 user = user_unref(user); 11113 goto cleanup; 11114 } 11115 user->maxauthreq = maxauthreq; 11116 user->curauthreq = oldcurauthreq; 11117 user->prefs = prefs; 11118 user->capability = iax2_capability; 11119 user->encmethods = iax2_encryption; 11120 user->adsi = adsi; 11121 user->calltoken_required = CALLTOKEN_DEFAULT; 11122 ast_string_field_set(user, name, name); 11123 ast_string_field_set(user, language, language); 11124 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 11125 ast_clear_flag(user, IAX_HASCALLERID); 11126 ast_string_field_set(user, cid_name, ""); 11127 ast_string_field_set(user, cid_num, ""); 11128 ast_string_field_set(user, accountcode, accountcode); 11129 ast_string_field_set(user, mohinterpret, mohinterpret); 11130 ast_string_field_set(user, mohsuggest, mohsuggest); 11131 } 11132 if (!v) { 11133 v = alt; 11134 alt = NULL; 11135 } 11136 while(v) { 11137 if (!strcasecmp(v->name, "context")) { 11138 con = build_context(v->value); 11139 if (con) { 11140 if (conl) 11141 conl->next = con; 11142 else 11143 user->contexts = con; 11144 conl = con; 11145 } 11146 } else if (!strcasecmp(v->name, "permit") || 11147 !strcasecmp(v->name, "deny")) { 11148 user->ha = ast_append_ha(v->name, v->value, user->ha); 11149 } else if (!strcasecmp(v->name, "setvar")) { 11150 varname = ast_strdupa(v->value); 11151 if (varname && (varval = strchr(varname,'='))) { 11152 *varval = '\0'; 11153 varval++; 11154 if((tmpvar = ast_variable_new(varname, varval))) { 11155 tmpvar->next = user->vars; 11156 user->vars = tmpvar; 11157 } 11158 } 11159 } else if (!strcasecmp(v->name, "allow")) { 11160 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 11161 } else if (!strcasecmp(v->name, "disallow")) { 11162 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 11163 } else if (!strcasecmp(v->name, "trunk")) { 11164 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 11165 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 11166 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 11167 ast_clear_flag(user, IAX_TRUNK); 11168 } 11169 } else if (!strcasecmp(v->name, "auth")) { 11170 user->authmethods = get_auth_methods(v->value); 11171 } else if (!strcasecmp(v->name, "encryption")) { 11172 user->encmethods = get_encrypt_methods(v->value); 11173 } else if (!strcasecmp(v->name, "notransfer")) { 11174 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11175 ast_clear_flag(user, IAX_TRANSFERMEDIA); 11176 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 11177 } else if (!strcasecmp(v->name, "transfer")) { 11178 if (!strcasecmp(v->value, "mediaonly")) { 11179 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11180 } else if (ast_true(v->value)) { 11181 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11182 } else 11183 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11184 } else if (!strcasecmp(v->name, "codecpriority")) { 11185 if(!strcasecmp(v->value, "caller")) 11186 ast_set_flag(user, IAX_CODEC_USER_FIRST); 11187 else if(!strcasecmp(v->value, "disabled")) 11188 ast_set_flag(user, IAX_CODEC_NOPREFS); 11189 else if(!strcasecmp(v->value, "reqonly")) { 11190 ast_set_flag(user, IAX_CODEC_NOCAP); 11191 ast_set_flag(user, IAX_CODEC_NOPREFS); 11192 } 11193 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11194 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 11195 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11196 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 11197 } else if (!strcasecmp(v->name, "dbsecret")) { 11198 ast_string_field_set(user, dbsecret, v->value); 11199 } else if (!strcasecmp(v->name, "secret")) { 11200 if (!ast_strlen_zero(user->secret)) { 11201 char *old = ast_strdupa(user->secret); 11202 11203 ast_string_field_build(user, secret, "%s;%s", old, v->value); 11204 } else 11205 ast_string_field_set(user, secret, v->value); 11206 } else if (!strcasecmp(v->name, "callerid")) { 11207 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 11208 char name2[80]; 11209 char num2[80]; 11210 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 11211 ast_string_field_set(user, cid_name, name2); 11212 ast_string_field_set(user, cid_num, num2); 11213 ast_set_flag(user, IAX_HASCALLERID); 11214 } else { 11215 ast_clear_flag(user, IAX_HASCALLERID); 11216 ast_string_field_set(user, cid_name, ""); 11217 ast_string_field_set(user, cid_num, ""); 11218 } 11219 } else if (!strcasecmp(v->name, "fullname")) { 11220 if (!ast_strlen_zero(v->value)) { 11221 ast_string_field_set(user, cid_name, v->value); 11222 ast_set_flag(user, IAX_HASCALLERID); 11223 } else { 11224 ast_string_field_set(user, cid_name, ""); 11225 if (ast_strlen_zero(user->cid_num)) 11226 ast_clear_flag(user, IAX_HASCALLERID); 11227 } 11228 } else if (!strcasecmp(v->name, "cid_number")) { 11229 if (!ast_strlen_zero(v->value)) { 11230 ast_string_field_set(user, cid_num, v->value); 11231 ast_set_flag(user, IAX_HASCALLERID); 11232 } else { 11233 ast_string_field_set(user, cid_num, ""); 11234 if (ast_strlen_zero(user->cid_name)) 11235 ast_clear_flag(user, IAX_HASCALLERID); 11236 } 11237 } else if (!strcasecmp(v->name, "accountcode")) { 11238 ast_string_field_set(user, accountcode, v->value); 11239 } else if (!strcasecmp(v->name, "mohinterpret")) { 11240 ast_string_field_set(user, mohinterpret, v->value); 11241 } else if (!strcasecmp(v->name, "mohsuggest")) { 11242 ast_string_field_set(user, mohsuggest, v->value); 11243 } else if (!strcasecmp(v->name, "language")) { 11244 ast_string_field_set(user, language, v->value); 11245 } else if (!strcasecmp(v->name, "amaflags")) { 11246 format = ast_cdr_amaflags2int(v->value); 11247 if (format < 0) { 11248 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11249 } else { 11250 user->amaflags = format; 11251 } 11252 } else if (!strcasecmp(v->name, "inkeys")) { 11253 ast_string_field_set(user, inkeys, v->value); 11254 } else if (!strcasecmp(v->name, "maxauthreq")) { 11255 user->maxauthreq = atoi(v->value); 11256 if (user->maxauthreq < 0) 11257 user->maxauthreq = 0; 11258 } else if (!strcasecmp(v->name, "adsi")) { 11259 user->adsi = ast_true(v->value); 11260 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11261 /* default is required unless in optional ip list */ 11262 if (ast_false(v->value)) { 11263 user->calltoken_required = CALLTOKEN_NO; 11264 } else if (!strcasecmp(v->value, "auto")) { 11265 user->calltoken_required = CALLTOKEN_AUTO; 11266 } else if (ast_true(v->value)) { 11267 user->calltoken_required = CALLTOKEN_YES; 11268 } else { 11269 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11270 } 11271 } /* else if (strcasecmp(v->name,"type")) */ 11272 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11273 v = v->next; 11274 if (!v) { 11275 v = alt; 11276 alt = NULL; 11277 } 11278 } 11279 if (!user->authmethods) { 11280 if (!ast_strlen_zero(user->secret)) { 11281 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11282 if (!ast_strlen_zero(user->inkeys)) 11283 user->authmethods |= IAX_AUTH_RSA; 11284 } else if (!ast_strlen_zero(user->inkeys)) { 11285 user->authmethods = IAX_AUTH_RSA; 11286 } else { 11287 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11288 } 11289 } 11290 ast_clear_flag(user, IAX_DELME); 11291 } 11292 cleanup: 11293 if (oldha) 11294 ast_free_ha(oldha); 11295 if (oldcon) 11296 free_context(oldcon); 11297 return user; 11298 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 11839 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().
11840 { 11841 struct sockaddr_in sin; 11842 int x; 11843 int callno; 11844 struct iax_ie_data ied; 11845 struct create_addr_info cai; 11846 struct parsed_dial_string pds; 11847 char *tmpstr; 11848 11849 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11850 /* Look for an *exact match* call. Once a call is negotiated, it can only 11851 look up entries for a single context */ 11852 if (!ast_mutex_trylock(&iaxsl[x])) { 11853 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 11854 return x; 11855 ast_mutex_unlock(&iaxsl[x]); 11856 } 11857 } 11858 11859 /* No match found, we need to create a new one */ 11860 11861 memset(&cai, 0, sizeof(cai)); 11862 memset(&ied, 0, sizeof(ied)); 11863 memset(&pds, 0, sizeof(pds)); 11864 11865 tmpstr = ast_strdupa(data); 11866 parse_dial_string(tmpstr, &pds); 11867 11868 if (ast_strlen_zero(pds.peer)) { 11869 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 11870 return -1; 11871 } 11872 11873 /* Populate our address from the given */ 11874 if (create_addr(pds.peer, NULL, &sin, &cai)) 11875 return -1; 11876 11877 if (option_debug) 11878 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 11879 pds.peer, pds.username, pds.password, pds.context); 11880 11881 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11882 if (callno < 1) { 11883 ast_log(LOG_WARNING, "Unable to create call\n"); 11884 return -1; 11885 } 11886 11887 ast_string_field_set(iaxs[callno], dproot, data); 11888 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 11889 11890 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 11891 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 11892 /* the string format is slightly different from a standard dial string, 11893 because the context appears in the 'exten' position 11894 */ 11895 if (pds.exten) 11896 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 11897 if (pds.username) 11898 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 11899 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 11900 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 11901 /* Keep password handy */ 11902 if (pds.password) 11903 ast_string_field_set(iaxs[callno], secret, pds.password); 11904 if (pds.key) 11905 ast_string_field_set(iaxs[callno], outkey, pds.key); 11906 /* Start the call going */ 11907 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11908 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 11909 11910 return callno; 11911 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5243 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.
05244 { 05245 /* Returns where in "receive time" we are. That is, how many ms 05246 since we received (or would have received) the frame with timestamp 0 */ 05247 int ms; 05248 #ifdef IAXTESTS 05249 int jit; 05250 #endif /* IAXTESTS */ 05251 /* Setup rxcore if necessary */ 05252 if (ast_tvzero(p->rxcore)) { 05253 p->rxcore = ast_tvnow(); 05254 if (option_debug && iaxdebug) 05255 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05256 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05257 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05258 #if 1 05259 if (option_debug && iaxdebug) 05260 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05261 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05262 #endif 05263 } 05264 05265 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05266 #ifdef IAXTESTS 05267 if (test_jit) { 05268 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05269 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05270 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05271 jit = -jit; 05272 ms += jit; 05273 } 05274 } 05275 if (test_late) { 05276 ms += test_late; 05277 test_late = 0; 05278 } 05279 #endif /* IAXTESTS */ 05280 return ms; 05281 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5110 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().
05111 { 05112 int ms; 05113 int voice = 0; 05114 int genuine = 0; 05115 int adjust; 05116 int rate = ast_format_rate(f->subclass) / 1000; 05117 struct timeval *delivery = NULL; 05118 05119 05120 /* What sort of frame do we have?: voice is self-explanatory 05121 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05122 non-genuine frames are CONTROL frames [ringing etc], DTMF 05123 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05124 the others need a timestamp slaved to the voice frames so that they go in sequence 05125 */ 05126 if (f) { 05127 if (f->frametype == AST_FRAME_VOICE) { 05128 voice = 1; 05129 delivery = &f->delivery; 05130 } else if (f->frametype == AST_FRAME_IAX) { 05131 genuine = 1; 05132 } else if (f->frametype == AST_FRAME_CNG) { 05133 p->notsilenttx = 0; 05134 } 05135 } 05136 if (ast_tvzero(p->offset)) { 05137 gettimeofday(&p->offset, NULL); 05138 /* Round to nearest 20ms for nice looking traces */ 05139 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05140 } 05141 /* If the timestamp is specified, just send it as is */ 05142 if (ts) 05143 return ts; 05144 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05145 if (delivery && !ast_tvzero(*delivery)) { 05146 ms = ast_tvdiff_ms(*delivery, p->offset); 05147 if (ms < 0) { 05148 ms = 0; 05149 } 05150 if (option_debug > 2 && iaxdebug) 05151 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05152 } else { 05153 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05154 if (ms < 0) 05155 ms = 0; 05156 if (voice) { 05157 /* On a voice frame, use predicted values if appropriate */ 05158 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05159 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05160 /* AN EXPLANATION: 05161 When we send voice, we usually send "calculated" timestamps worked out 05162 on the basis of the number of samples sent. When we send other frames, 05163 we usually send timestamps worked out from the real clock. 05164 The problem is that they can tend to drift out of step because the 05165 source channel's clock and our clock may not be exactly at the same rate. 05166 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05167 for this call. Moving it adjusts timestamps for non-voice frames. 05168 We make the adjustment in the style of a moving average. Each time we 05169 adjust p->offset by 10% of the difference between our clock-derived 05170 timestamp and the predicted timestamp. That's why you see "10000" 05171 below even though IAX2 timestamps are in milliseconds. 05172 The use of a moving average avoids offset moving too radically. 05173 Generally, "adjust" roams back and forth around 0, with offset hardly 05174 changing at all. But if a consistent different starts to develop it 05175 will be eliminated over the course of 10 frames (200-300msecs) 05176 */ 05177 adjust = (ms - p->nextpred); 05178 if (adjust < 0) 05179 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05180 else if (adjust > 0) 05181 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05182 05183 if (!p->nextpred) { 05184 p->nextpred = ms; /*f->samples / rate;*/ 05185 if (p->nextpred <= p->lastsent) 05186 p->nextpred = p->lastsent + 3; 05187 } 05188 ms = p->nextpred; 05189 } else { 05190 /* in this case, just use the actual 05191 * time, since we're either way off 05192 * (shouldn't happen), or we're ending a 05193 * silent period -- and seed the next 05194 * predicted time. Also, round ms to the 05195 * next multiple of frame size (so our 05196 * silent periods are multiples of 05197 * frame size too) */ 05198 05199 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05200 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05201 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05202 05203 if (f->samples >= rate) /* check to make sure we dont core dump */ 05204 { 05205 int diff = ms % (f->samples / rate); 05206 if (diff) 05207 ms += f->samples/rate - diff; 05208 } 05209 05210 p->nextpred = ms; 05211 p->notsilenttx = 1; 05212 } 05213 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05214 /* 05215 * IAX2 draft 03 says that timestamps MUST be in order. 05216 * It does not say anything about several frames having the same timestamp 05217 * When transporting video, we can have a frame that spans multiple iax packets 05218 * (so called slices), so it would make sense to use the same timestamp for all of 05219 * them 05220 * We do want to make sure that frames don't go backwards though 05221 */ 05222 if ( (unsigned int)ms < p->lastsent ) 05223 ms = p->lastsent; 05224 } else { 05225 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05226 it's a genuine frame */ 05227 if (genuine) { 05228 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05229 if (ms <= p->lastsent) 05230 ms = p->lastsent + 3; 05231 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05232 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05233 ms = p->lastsent + 3; 05234 } 05235 } 05236 } 05237 p->lastsent = ms; 05238 if (voice) 05239 p->nextpred = p->nextpred + f->samples / rate; 05240 return ms; 05241 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 5066 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().
05067 { 05068 unsigned long int mssincetx; /* unsigned to handle overflows */ 05069 long int ms, pred; 05070 05071 tpeer->trunkact = *tv; 05072 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 05073 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05074 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05075 tpeer->txtrunktime = *tv; 05076 tpeer->lastsent = 999999; 05077 } 05078 /* Update last transmit time now */ 05079 tpeer->lasttxtime = *tv; 05080 05081 /* Calculate ms offset */ 05082 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 05083 /* Predict from last value */ 05084 pred = tpeer->lastsent + sampms; 05085 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05086 ms = pred; 05087 05088 /* We never send the same timestamp twice, so fudge a little if we must */ 05089 if (ms == tpeer->lastsent) 05090 ms = tpeer->lastsent + 1; 05091 tpeer->lastsent = ms; 05092 return ms; 05093 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2309 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02310 { 02311 return abs(ast_random()); 02312 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 1865 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().
01866 { 01867 struct addr_range *addr_range; 01868 struct iax2_peer *peer = NULL; 01869 struct iax2_user *user = NULL; 01870 /* if no username is given, check for guest accounts */ 01871 const char *find = S_OR(name, "guest"); 01872 int res = 1; /* required by default */ 01873 int optional = 0; 01874 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 01875 /* There are only two cases in which calltoken validation is not required. 01876 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 01877 * the peer definition has not set the requirecalltoken option. 01878 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 01879 */ 01880 01881 /* ----- Case 1 ----- */ 01882 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 01883 ao2_ref(addr_range, -1); 01884 optional = 1; 01885 } 01886 01887 /* ----- Case 2 ----- */ 01888 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 01889 calltoken_required = user->calltoken_required; 01890 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 01891 calltoken_required = user->calltoken_required; 01892 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 01893 calltoken_required = peer->calltoken_required; 01894 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 01895 calltoken_required = peer->calltoken_required; 01896 } 01897 01898 if (peer) { 01899 peer_unref(peer); 01900 } 01901 if (user) { 01902 user_unref(user); 01903 } 01904 if (option_debug) { 01905 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); 01906 } 01907 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 01908 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 01909 res = 0; 01910 } 01911 01912 return res; 01913 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6417 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().
06418 { 06419 /* Start pessimistic */ 06420 int res = -1; 06421 int version = 2; 06422 struct iax2_user *user = NULL, *best = NULL; 06423 int bestscore = 0; 06424 int gotcapability = 0; 06425 struct ast_variable *v = NULL, *tmpvar = NULL; 06426 struct ao2_iterator i; 06427 06428 if (!iaxs[callno]) 06429 return res; 06430 if (ies->called_number) 06431 ast_string_field_set(iaxs[callno], exten, ies->called_number); 06432 if (ies->calling_number) { 06433 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 06434 ast_shrink_phone_number(ies->calling_number); 06435 } 06436 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 06437 } 06438 if (ies->calling_name) 06439 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 06440 if (ies->calling_ani) 06441 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 06442 if (ies->dnid) 06443 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 06444 if (ies->rdnis) 06445 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 06446 if (ies->called_context) 06447 ast_string_field_set(iaxs[callno], context, ies->called_context); 06448 if (ies->language) 06449 ast_string_field_set(iaxs[callno], language, ies->language); 06450 if (ies->username) 06451 ast_string_field_set(iaxs[callno], username, ies->username); 06452 if (ies->calling_ton > -1) 06453 iaxs[callno]->calling_ton = ies->calling_ton; 06454 if (ies->calling_tns > -1) 06455 iaxs[callno]->calling_tns = ies->calling_tns; 06456 if (ies->calling_pres > -1) 06457 iaxs[callno]->calling_pres = ies->calling_pres; 06458 if (ies->format) 06459 iaxs[callno]->peerformat = ies->format; 06460 if (ies->adsicpe) 06461 iaxs[callno]->peeradsicpe = ies->adsicpe; 06462 if (ies->capability) { 06463 gotcapability = 1; 06464 iaxs[callno]->peercapability = ies->capability; 06465 } 06466 if (ies->version) 06467 version = ies->version; 06468 06469 /* Use provided preferences until told otherwise for actual preferences */ 06470 if(ies->codec_prefs) { 06471 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 06472 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 06473 } 06474 06475 if (!gotcapability) 06476 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 06477 if (version > IAX_PROTO_VERSION) { 06478 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 06479 ast_inet_ntoa(sin->sin_addr), version); 06480 return res; 06481 } 06482 /* Search the userlist for a compatible entry, and fill in the rest */ 06483 i = ao2_iterator_init(users, 0); 06484 while ((user = ao2_iterator_next(&i))) { 06485 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 06486 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 06487 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 06488 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 06489 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 06490 if (!ast_strlen_zero(iaxs[callno]->username)) { 06491 /* Exact match, stop right now. */ 06492 if (best) 06493 user_unref(best); 06494 best = user; 06495 break; 06496 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 06497 /* No required authentication */ 06498 if (user->ha) { 06499 /* There was host authentication and we passed, bonus! */ 06500 if (bestscore < 4) { 06501 bestscore = 4; 06502 if (best) 06503 user_unref(best); 06504 best = user; 06505 continue; 06506 } 06507 } else { 06508 /* No host access, but no secret, either, not bad */ 06509 if (bestscore < 3) { 06510 bestscore = 3; 06511 if (best) 06512 user_unref(best); 06513 best = user; 06514 continue; 06515 } 06516 } 06517 } else { 06518 if (user->ha) { 06519 /* Authentication, but host access too, eh, it's something.. */ 06520 if (bestscore < 2) { 06521 bestscore = 2; 06522 if (best) 06523 user_unref(best); 06524 best = user; 06525 continue; 06526 } 06527 } else { 06528 /* Authentication and no host access... This is our baseline */ 06529 if (bestscore < 1) { 06530 bestscore = 1; 06531 if (best) 06532 user_unref(best); 06533 best = user; 06534 continue; 06535 } 06536 } 06537 } 06538 } 06539 user_unref(user); 06540 } 06541 ao2_iterator_destroy(&i); 06542 user = best; 06543 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 06544 user = realtime_user(iaxs[callno]->username, sin); 06545 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 06546 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 06547 user = user_unref(user); 06548 } 06549 } 06550 if (user) { 06551 /* We found our match (use the first) */ 06552 /* copy vars */ 06553 for (v = user->vars ; v ; v = v->next) { 06554 if((tmpvar = ast_variable_new(v->name, v->value))) { 06555 tmpvar->next = iaxs[callno]->vars; 06556 iaxs[callno]->vars = tmpvar; 06557 } 06558 } 06559 /* If a max AUTHREQ restriction is in place, activate it */ 06560 if (user->maxauthreq > 0) 06561 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 06562 iaxs[callno]->prefs = user->prefs; 06563 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 06564 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 06565 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 06566 iaxs[callno]->encmethods = user->encmethods; 06567 /* Store the requested username if not specified */ 06568 if (ast_strlen_zero(iaxs[callno]->username)) 06569 ast_string_field_set(iaxs[callno], username, user->name); 06570 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 06571 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 06572 iaxs[callno]->capability = user->capability; 06573 /* And use the default context */ 06574 if (ast_strlen_zero(iaxs[callno]->context)) { 06575 if (user->contexts) 06576 ast_string_field_set(iaxs[callno], context, user->contexts->context); 06577 else 06578 ast_string_field_set(iaxs[callno], context, context); 06579 } 06580 /* And any input keys */ 06581 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 06582 /* And the permitted authentication methods */ 06583 iaxs[callno]->authmethods = user->authmethods; 06584 iaxs[callno]->adsi = user->adsi; 06585 /* If the user has callerid, override the remote caller id. */ 06586 if (ast_test_flag(user, IAX_HASCALLERID)) { 06587 iaxs[callno]->calling_tns = 0; 06588 iaxs[callno]->calling_ton = 0; 06589 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 06590 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 06591 ast_string_field_set(iaxs[callno], ani, user->cid_num); 06592 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 06593 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 06594 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 06595 } /* else user is allowed to set their own CID settings */ 06596 if (!ast_strlen_zero(user->accountcode)) 06597 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 06598 if (!ast_strlen_zero(user->mohinterpret)) 06599 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 06600 if (!ast_strlen_zero(user->mohsuggest)) 06601 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 06602 if (user->amaflags) 06603 iaxs[callno]->amaflags = user->amaflags; 06604 if (!ast_strlen_zero(user->language)) 06605 ast_string_field_set(iaxs[callno], language, user->language); 06606 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 06607 /* Keep this check last */ 06608 if (!ast_strlen_zero(user->dbsecret)) { 06609 char *family, *key=NULL; 06610 char buf[80]; 06611 family = ast_strdupa(user->dbsecret); 06612 key = strchr(family, '/'); 06613 if (key) { 06614 *key = '\0'; 06615 key++; 06616 } 06617 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 06618 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 06619 else 06620 ast_string_field_set(iaxs[callno], secret, buf); 06621 } else 06622 ast_string_field_set(iaxs[callno], secret, user->secret); 06623 res = 0; 06624 user = user_unref(user); 06625 } else { 06626 /* user was not found, but we should still fake an AUTHREQ. 06627 * Set authmethods to the last known authmethod used by the system 06628 * Set a fake secret, it's not looked at, just required to attempt authentication. 06629 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 06630 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06631 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06632 iaxs[callno]->authrej = 1; 06633 if (!ast_strlen_zero(iaxs[callno]->username)) { 06634 /* only send the AUTHREQ if a username was specified. */ 06635 res = 0; 06636 } 06637 } 06638 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 06639 return res; 06640 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 8182 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
08183 { 08184 unsigned int ourver; 08185 char rsi[80]; 08186 snprintf(rsi, sizeof(rsi), "si-%s", si); 08187 if (iax_provision_version(&ourver, rsi, 1)) 08188 return 0; 08189 if (option_debug) 08190 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 08191 if (ourver != ver) 08192 iax2_provision(sin, sockfd, NULL, rsi, 1); 08193 return 0; 08194 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 10697 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
10698 { 10699 int sd; 10700 int res; 10701 10702 sd = socket(AF_INET, SOCK_DGRAM, 0); 10703 if (sd < 0) { 10704 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 10705 return -1; 10706 } 10707 10708 res = bind(sd, sa, salen); 10709 if (res < 0) { 10710 if (option_debug) 10711 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 10712 close(sd); 10713 return 1; 10714 } 10715 10716 close(sd); 10717 return 0; 10718 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7153 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().
07154 { 07155 char exten[256] = ""; 07156 int status = CACHE_FLAG_UNKNOWN; 07157 int expiry = iaxdefaultdpcache; 07158 int x; 07159 int matchmore = 0; 07160 struct iax2_dpcache *dp, *prev; 07161 07162 if (ies->called_number) 07163 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07164 07165 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07166 status = CACHE_FLAG_EXISTS; 07167 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07168 status = CACHE_FLAG_CANEXIST; 07169 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07170 status = CACHE_FLAG_NONEXISTENT; 07171 07172 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 07173 /* Don't really do anything with this */ 07174 } 07175 if (ies->refresh) 07176 expiry = ies->refresh; 07177 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07178 matchmore = CACHE_FLAG_MATCHMORE; 07179 ast_mutex_lock(&dpcache_lock); 07180 prev = NULL; 07181 dp = pvt->dpentries; 07182 while(dp) { 07183 if (!strcmp(dp->exten, exten)) { 07184 /* Let them go */ 07185 if (prev) 07186 prev->peer = dp->peer; 07187 else 07188 pvt->dpentries = dp->peer; 07189 dp->peer = NULL; 07190 dp->callno = 0; 07191 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 07192 if (dp->flags & CACHE_FLAG_PENDING) { 07193 dp->flags &= ~CACHE_FLAG_PENDING; 07194 dp->flags |= status; 07195 dp->flags |= matchmore; 07196 } 07197 /* Wake up waiters */ 07198 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 07199 if (dp->waiters[x] > -1) { 07200 if (write(dp->waiters[x], "asdf", 4) < 0) { 07201 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 07202 } 07203 } 07204 } 07205 } 07206 prev = dp; 07207 dp = dp->peer; 07208 } 07209 ast_mutex_unlock(&dpcache_lock); 07210 return 0; 07211 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3344 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, peer_unref(), and peers.
03345 { 03346 int which = 0; 03347 struct iax2_peer *peer; 03348 char *res = NULL; 03349 int wordlen = strlen(word); 03350 struct ao2_iterator i; 03351 03352 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 03353 if (pos != 3) 03354 return NULL; 03355 03356 i = ao2_iterator_init(peers, 0); 03357 while ((peer = ao2_iterator_next(&i))) { 03358 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 03359 res = ast_strdup(peer->name); 03360 peer_unref(peer); 03361 break; 03362 } 03363 peer_unref(peer); 03364 } 03365 ao2_iterator_destroy(&i); 03366 03367 return res; 03368 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7213 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().
07214 { 07215 int peercallno = 0; 07216 struct chan_iax2_pvt *pvt = iaxs[callno]; 07217 struct iax_frame *cur; 07218 jb_frame frame; 07219 07220 if (ies->callno) 07221 peercallno = ies->callno; 07222 07223 if (peercallno < 1) { 07224 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07225 return -1; 07226 } 07227 remove_by_transfercallno(pvt); 07228 /* since a transfer has taken place, the address will change. 07229 * This must be accounted for in the peercnts table. Remove 07230 * the old address and add the new one */ 07231 peercnt_remove_by_addr(&pvt->addr); 07232 peercnt_add(&pvt->transfer); 07233 /* now copy over the new address */ 07234 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 07235 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 07236 /* Reset sequence numbers */ 07237 pvt->oseqno = 0; 07238 pvt->rseqno = 0; 07239 pvt->iseqno = 0; 07240 pvt->aseqno = 0; 07241 07242 if (pvt->peercallno) { 07243 remove_by_peercallno(pvt); 07244 } 07245 pvt->peercallno = peercallno; 07246 /*this is where the transfering call swiches hash tables */ 07247 store_by_peercallno(pvt); 07248 pvt->transferring = TRANSFER_NONE; 07249 pvt->svoiceformat = -1; 07250 pvt->voiceformat = 0; 07251 pvt->svideoformat = -1; 07252 pvt->videoformat = 0; 07253 pvt->transfercallno = 0; 07254 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 07255 memset(&pvt->offset, 0, sizeof(pvt->offset)); 07256 /* reset jitterbuffer */ 07257 while(jb_getall(pvt->jb,&frame) == JB_OK) 07258 iax2_frame_free(frame.data); 07259 jb_reset(pvt->jb); 07260 pvt->lag = 0; 07261 pvt->last = 0; 07262 pvt->lastsent = 0; 07263 pvt->nextpred = 0; 07264 pvt->pingtime = DEFAULT_RETRY_TIME; 07265 AST_LIST_LOCK(&iaxq.queue); 07266 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07267 /* We must cancel any packets that would have been transmitted 07268 because now we're talking to someone new. It's okay, they 07269 were transmitted to someone that didn't care anyway. */ 07270 if (callno == cur->callno) 07271 cur->retries = -1; 07272 } 07273 AST_LIST_UNLOCK(&iaxq.queue); 07274 return 0; 07275 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1233 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().
01234 { 01235 int x; 01236 int power=-1; 01237 /* If it's 128 or smaller, just return it */ 01238 if (subclass < IAX_FLAG_SC_LOG) 01239 return subclass; 01240 /* Otherwise find its power */ 01241 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01242 if (subclass & (1 << x)) { 01243 if (power > -1) { 01244 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01245 return 0; 01246 } else 01247 power = x; 01248 } 01249 } 01250 return power | IAX_FLAG_SC_LOG; 01251 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 8196 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().
08197 { 08198 jb_info stats; 08199 jb_getinfo(pvt->jb, &stats); 08200 08201 memset(iep, 0, sizeof(*iep)); 08202 08203 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 08204 if(stats.frames_in == 0) stats.frames_in = 1; 08205 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 08206 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 08207 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 08208 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 08209 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 08210 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3979 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.
03980 { 03981 struct ast_hostent ahp; 03982 struct hostent *hp; 03983 struct iax2_peer *peer; 03984 int res = -1; 03985 struct ast_codec_pref ourprefs; 03986 03987 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03988 cai->sockfd = defaultsockfd; 03989 cai->maxtime = 0; 03990 sin->sin_family = AF_INET; 03991 03992 if (!(peer = find_peer(peername, 1))) { 03993 cai->found = 0; 03994 03995 hp = ast_gethostbyname(peername, &ahp); 03996 if (hp) { 03997 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03998 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03999 /* use global iax prefs for unknown peer/user */ 04000 /* But move the calling channel's native codec to the top of the preference list */ 04001 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04002 if (c) 04003 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04004 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04005 return 0; 04006 } else { 04007 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04008 return -1; 04009 } 04010 } 04011 04012 cai->found = 1; 04013 04014 /* if the peer has no address (current or default), return failure */ 04015 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 04016 goto return_unref; 04017 04018 /* if the peer is being monitored and is currently unreachable, return failure */ 04019 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04020 goto return_unref; 04021 04022 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04023 cai->maxtime = peer->maxms; 04024 cai->capability = peer->capability; 04025 cai->encmethods = peer->encmethods; 04026 cai->sockfd = peer->sockfd; 04027 cai->adsi = peer->adsi; 04028 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04029 /* Move the calling channel's native codec to the top of the preference list */ 04030 if (c) { 04031 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 04032 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04033 } 04034 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04035 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04036 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04037 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04038 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04039 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04040 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04041 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04042 if (ast_strlen_zero(peer->dbsecret)) { 04043 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04044 } else { 04045 char *family; 04046 char *key = NULL; 04047 04048 family = ast_strdupa(peer->dbsecret); 04049 key = strchr(family, '/'); 04050 if (key) 04051 *key++ = '\0'; 04052 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04053 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04054 goto return_unref; 04055 } 04056 } 04057 04058 if (peer->addr.sin_addr.s_addr) { 04059 sin->sin_addr = peer->addr.sin_addr; 04060 sin->sin_port = peer->addr.sin_port; 04061 } else { 04062 sin->sin_addr = peer->defaddr.sin_addr; 04063 sin->sin_port = peer->defaddr.sin_port; 04064 } 04065 04066 res = 0; 04067 04068 return_unref: 04069 peer_unref(peer); 04070 04071 return res; 04072 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2314 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().
02315 { 02316 uint16_t i; 02317 02318 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02319 return -1; 02320 } 02321 02322 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02323 return -1; 02324 } 02325 02326 /* start at 2, 0 and 1 are reserved */ 02327 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02328 struct callno_entry *callno_entry; 02329 02330 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02331 return -1; 02332 } 02333 02334 callno_entry->callno = i; 02335 02336 if (i < TRUNK_CALL_START) { 02337 ao2_link(callno_pool, callno_entry); 02338 } else { 02339 ao2_link(callno_pool_trunk, callno_entry); 02340 } 02341 02342 ao2_ref(callno_entry, -1); 02343 } 02344 02345 return 0; 02346 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5451 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().
05452 { 05453 int padding; 05454 unsigned char *workspace; 05455 05456 workspace = alloca(*datalen); 05457 memset(f, 0, sizeof(*f)); 05458 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05459 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05460 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05461 return -1; 05462 /* Decrypt */ 05463 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05464 05465 padding = 16 + (workspace[15] & 0x0f); 05466 if (option_debug && iaxdebug) 05467 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05468 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05469 return -1; 05470 05471 *datalen -= padding; 05472 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05473 f->frametype = fh->type; 05474 if (f->frametype == AST_FRAME_VIDEO) { 05475 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05476 } else { 05477 f->subclass = uncompress_subclass(fh->csub); 05478 } 05479 } else { 05480 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05481 if (option_debug && iaxdebug) 05482 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 05483 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05484 return -1; 05485 /* Decrypt */ 05486 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05487 padding = 16 + (workspace[15] & 0x0f); 05488 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05489 return -1; 05490 *datalen -= padding; 05491 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05492 } 05493 return 0; 05494 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5537 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().
05538 { 05539 int res=-1; 05540 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 05541 /* Search for possible keys, given secrets */ 05542 struct MD5Context md5; 05543 unsigned char digest[16]; 05544 char *tmppw, *stringp; 05545 05546 tmppw = ast_strdupa(iaxs[callno]->secret); 05547 stringp = tmppw; 05548 while ((tmppw = strsep(&stringp, ";"))) { 05549 MD5Init(&md5); 05550 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05551 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05552 MD5Final(digest, &md5); 05553 build_encryption_keys(digest, iaxs[callno]); 05554 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05555 if (!res) { 05556 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 05557 break; 05558 } 05559 } 05560 } else 05561 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05562 return res; 05563 }
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 8258 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().
08259 { 08260 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 08261 struct ast_iax2_full_hdr *fh, *cur_fh; 08262 08263 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 08264 return; 08265 08266 pkt_buf->len = from_here->buf_len; 08267 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 08268 08269 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 08270 ast_mutex_lock(&to_here->lock); 08271 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 08272 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 08273 if (fh->oseqno < cur_fh->oseqno) { 08274 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 08275 break; 08276 } 08277 } 08278 AST_LIST_TRAVERSE_SAFE_END 08279 08280 if (!cur_pkt_buf) 08281 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 08282 08283 ast_mutex_unlock(&to_here->lock); 08284 }
static void delete_users | ( | void | ) | [static] |
Definition at line 11318 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.
11319 { 11320 struct iax2_registry *reg; 11321 11322 ao2_callback(users, 0, user_delme_cb, NULL); 11323 11324 AST_LIST_LOCK(®istrations); 11325 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 11326 ast_sched_del(sched, reg->expire); 11327 if (reg->callno) { 11328 int callno = reg->callno; 11329 ast_mutex_lock(&iaxsl[callno]); 11330 if (iaxs[callno]) { 11331 iaxs[callno]->reg = NULL; 11332 iax2_destroy(callno); 11333 } 11334 ast_mutex_unlock(&iaxsl[callno]); 11335 } 11336 if (reg->dnsmgr) 11337 ast_dnsmgr_release(reg->dnsmgr); 11338 free(reg); 11339 } 11340 AST_LIST_UNLOCK(®istrations); 11341 11342 ao2_callback(peers, 0, peer_delme_cb, NULL); 11343 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2658 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
02659 { 02660 /* Close firmware */ 02661 if (cur->fwh) { 02662 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02663 } 02664 close(cur->fd); 02665 free(cur); 02666 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 8030 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().
08031 { 08032 unsigned short dpstatus = 0; 08033 struct iax_ie_data ied1; 08034 int mm; 08035 08036 memset(&ied1, 0, sizeof(ied1)); 08037 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 08038 /* Must be started */ 08039 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 08040 dpstatus = IAX_DPSTATUS_EXISTS; 08041 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 08042 dpstatus = IAX_DPSTATUS_CANEXIST; 08043 } else { 08044 dpstatus = IAX_DPSTATUS_NONEXISTENT; 08045 } 08046 if (ast_ignore_pattern(context, callednum)) 08047 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 08048 if (mm) 08049 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08050 if (!skiplock) 08051 ast_mutex_lock(&iaxsl[callno]); 08052 if (iaxs[callno]) { 08053 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08054 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08055 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08056 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08057 } 08058 if (!skiplock) 08059 ast_mutex_unlock(&iaxsl[callno]); 08060 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8062 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().
08063 { 08064 /* Look up for dpreq */ 08065 struct dpreq_data *dpr = data; 08066 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 08067 if (dpr->callerid) 08068 free(dpr->callerid); 08069 free(dpr); 08070 return NULL; 08071 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 5496 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().
05497 { 05498 int padding; 05499 unsigned char *workspace; 05500 workspace = alloca(*datalen + 32); 05501 if (!workspace) 05502 return -1; 05503 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05504 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05505 if (option_debug && iaxdebug) 05506 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05507 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05508 padding = 16 + (padding & 0xf); 05509 memcpy(workspace, poo, padding); 05510 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05511 workspace[15] &= 0xf0; 05512 workspace[15] |= (padding & 0xf); 05513 if (option_debug && iaxdebug) 05514 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]); 05515 *datalen += padding; 05516 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05517 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05518 memcpy(poo, workspace + *datalen - 32, 32); 05519 } else { 05520 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05521 if (option_debug && iaxdebug) 05522 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 05523 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 05524 padding = 16 + (padding & 0xf); 05525 memcpy(workspace, poo, padding); 05526 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05527 workspace[15] &= 0xf0; 05528 workspace[15] |= (padding & 0x0f); 05529 *datalen += padding; 05530 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 05531 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 05532 memcpy(poo, workspace + *datalen - 32, 32); 05533 } 05534 return 0; 05535 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7459 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
07460 { 07461 #ifdef SCHED_MULTITHREADED 07462 if (schedule_action(__expire_registry, data)) 07463 #endif 07464 __expire_registry(data); 07465 return 0; 07466 }
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 11913 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().
11914 { 11915 struct iax2_dpcache *dp, *prev = NULL, *next; 11916 struct timeval tv; 11917 int x; 11918 int com[2]; 11919 int timeout; 11920 int old=0; 11921 int outfd; 11922 int abort; 11923 int callno; 11924 struct ast_channel *c; 11925 struct ast_frame *f; 11926 gettimeofday(&tv, NULL); 11927 dp = dpcache; 11928 while(dp) { 11929 next = dp->next; 11930 /* Expire old caches */ 11931 if (ast_tvcmp(tv, dp->expiry) > 0) { 11932 /* It's expired, let it disappear */ 11933 if (prev) 11934 prev->next = dp->next; 11935 else 11936 dpcache = dp->next; 11937 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 11938 /* Free memory and go again */ 11939 free(dp); 11940 } else { 11941 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); 11942 } 11943 dp = next; 11944 continue; 11945 } 11946 /* We found an entry that matches us! */ 11947 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 11948 break; 11949 prev = dp; 11950 dp = next; 11951 } 11952 if (!dp) { 11953 /* No matching entry. Create a new one. */ 11954 /* First, can we make a callno? */ 11955 callno = cache_get_callno_locked(data); 11956 if (callno < 0) { 11957 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 11958 return NULL; 11959 } 11960 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 11961 ast_mutex_unlock(&iaxsl[callno]); 11962 return NULL; 11963 } 11964 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 11965 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 11966 gettimeofday(&dp->expiry, NULL); 11967 dp->orig = dp->expiry; 11968 /* Expires in 30 mins by default */ 11969 dp->expiry.tv_sec += iaxdefaultdpcache; 11970 dp->next = dpcache; 11971 dp->flags = CACHE_FLAG_PENDING; 11972 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 11973 dp->waiters[x] = -1; 11974 dpcache = dp; 11975 dp->peer = iaxs[callno]->dpentries; 11976 iaxs[callno]->dpentries = dp; 11977 /* Send the request if we're already up */ 11978 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 11979 iax2_dprequest(dp, callno); 11980 ast_mutex_unlock(&iaxsl[callno]); 11981 } 11982 /* By here we must have a dp */ 11983 if (dp->flags & CACHE_FLAG_PENDING) { 11984 /* Okay, here it starts to get nasty. We need a pipe now to wait 11985 for a reply to come back so long as it's pending */ 11986 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 11987 /* Find an empty slot */ 11988 if (dp->waiters[x] < 0) 11989 break; 11990 } 11991 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 11992 ast_log(LOG_WARNING, "No more waiter positions available\n"); 11993 return NULL; 11994 } 11995 if (pipe(com)) { 11996 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 11997 return NULL; 11998 } 11999 dp->waiters[x] = com[1]; 12000 /* Okay, now we wait */ 12001 timeout = iaxdefaulttimeout * 1000; 12002 /* Temporarily unlock */ 12003 ast_mutex_unlock(&dpcache_lock); 12004 /* Defer any dtmf */ 12005 if (chan) 12006 old = ast_channel_defer_dtmf(chan); 12007 abort = 0; 12008 while(timeout) { 12009 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 12010 if (outfd > -1) { 12011 break; 12012 } 12013 if (c) { 12014 f = ast_read(c); 12015 if (f) 12016 ast_frfree(f); 12017 else { 12018 /* Got hung up on, abort! */ 12019 break; 12020 abort = 1; 12021 } 12022 } 12023 } 12024 if (!timeout) { 12025 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 12026 } 12027 ast_mutex_lock(&dpcache_lock); 12028 dp->waiters[x] = -1; 12029 close(com[1]); 12030 close(com[0]); 12031 if (abort) { 12032 /* Don't interpret anything, just abort. Not sure what th epoint 12033 of undeferring dtmf on a hung up channel is but hey whatever */ 12034 if (!old && chan) 12035 ast_channel_undefer_dtmf(chan); 12036 return NULL; 12037 } 12038 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 12039 /* Now to do non-independent analysis the results of our wait */ 12040 if (dp->flags & CACHE_FLAG_PENDING) { 12041 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 12042 pending. Don't let it take as long to timeout. */ 12043 dp->flags &= ~CACHE_FLAG_PENDING; 12044 dp->flags |= CACHE_FLAG_TIMEOUT; 12045 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 12046 systems without leaving it unavailable once the server comes back online */ 12047 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 12048 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 12049 if (dp->waiters[x] > -1) { 12050 if (write(dp->waiters[x], "asdf", 4) < 0) { 12051 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 12052 } 12053 } 12054 } 12055 } 12056 } 12057 /* Our caller will obtain the rest */ 12058 if (!old && chan) 12059 ast_channel_undefer_dtmf(chan); 12060 } 12061 return dp; 12062 }
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 2582 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02582 { 02583 02584 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02585 }
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 2587 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
02587 { 02588 02589 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02590 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1066 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().
01067 { 01068 pthread_attr_t attr; 01069 struct iax2_thread *thread = NULL; 01070 01071 /* Pop the head of the list off */ 01072 AST_LIST_LOCK(&idle_list); 01073 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01074 AST_LIST_UNLOCK(&idle_list); 01075 01076 /* If no idle thread is available from the regular list, try dynamic */ 01077 if (thread == NULL) { 01078 AST_LIST_LOCK(&dynamic_list); 01079 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01080 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 01081 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 01082 /* We need to MAKE a thread! */ 01083 if ((thread = ast_calloc(1, sizeof(*thread)))) { 01084 thread->threadnum = iaxdynamicthreadnum++; 01085 thread->type = IAX_TYPE_DYNAMIC; 01086 ast_mutex_init(&thread->lock); 01087 ast_cond_init(&thread->cond, NULL); 01088 pthread_attr_init(&attr); 01089 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01090 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 01091 free(thread); 01092 thread = NULL; 01093 } else { 01094 /* All went well and the thread is up, so increment our count */ 01095 iaxdynamicthreadcount++; 01096 01097 /* Wait for the thread to be ready before returning it to the caller */ 01098 while (!thread->ready_for_signal) 01099 usleep(1); 01100 } 01101 } 01102 } 01103 AST_LIST_UNLOCK(&dynamic_list); 01104 } 01105 01106 /* this thread is not processing a full frame (since it is idle), 01107 so ensure that the field for the full frame call number is empty */ 01108 if (thread) 01109 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01110 01111 return thread; 01112 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1311 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, peers, and realtime_peer().
01312 { 01313 struct iax2_peer *peer = NULL; 01314 struct iax2_peer tmp_peer = { 01315 .name = name, 01316 }; 01317 01318 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01319 01320 /* Now go for realtime if applicable */ 01321 if(!peer && realtime) 01322 peer = realtime_peer(name, NULL); 01323 01324 return peer; 01325 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 5283 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().
05284 { 05285 struct iax2_trunk_peer *tpeer; 05286 05287 /* Finds and locks trunk peer */ 05288 ast_mutex_lock(&tpeerlock); 05289 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 05290 /* We don't lock here because tpeer->addr *never* changes */ 05291 if (!inaddrcmp(&tpeer->addr, sin)) { 05292 ast_mutex_lock(&tpeer->lock); 05293 break; 05294 } 05295 } 05296 if (!tpeer) { 05297 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05298 ast_mutex_init(&tpeer->lock); 05299 tpeer->lastsent = 9999; 05300 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05301 tpeer->trunkact = ast_tvnow(); 05302 ast_mutex_lock(&tpeer->lock); 05303 tpeer->next = tpeers; 05304 tpeer->sockfd = fd; 05305 tpeers = tpeer; 05306 #ifdef SO_NO_CHECK 05307 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05308 #endif 05309 if (option_debug) 05310 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05311 } 05312 } 05313 ast_mutex_unlock(&tpeerlock); 05314 return tpeer; 05315 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1339 of file chan_iax2.c.
References ao2_find(), iax2_user::name, and users.
01340 { 01341 struct iax2_user tmp_user = { 01342 .name = name, 01343 }; 01344 01345 return ao2_find(users, &tmp_user, OBJ_POINTER); 01346 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5095 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
05096 { 05097 long ms; /* NOT unsigned */ 05098 if (ast_tvzero(iaxs[callno]->rxcore)) { 05099 /* Initialize rxcore time if appropriate */ 05100 gettimeofday(&iaxs[callno]->rxcore, NULL); 05101 /* Round to nearest 20ms so traces look pretty */ 05102 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05103 } 05104 /* Calculate difference between trunk and channel */ 05105 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 05106 /* Return as the sum of trunk time and the difference between trunk and real time */ 05107 return ms + ts; 05108 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 10449 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
10450 { 10451 struct iax2_context *conl; 10452 while(con) { 10453 conl = con; 10454 con = con->next; 10455 free(conl); 10456 } 10457 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1561 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 12186 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.
12187 { 12188 struct iax2_peer *peer; 12189 char *peername, *colname; 12190 12191 peername = ast_strdupa(data); 12192 12193 /* if our channel, return the IP address of the endpoint of current channel */ 12194 if (!strcmp(peername,"CURRENTCHANNEL")) { 12195 unsigned short callno; 12196 if (chan->tech != &iax2_tech) 12197 return -1; 12198 callno = PTR_TO_CALLNO(chan->tech_pvt); 12199 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 12200 return 0; 12201 } 12202 12203 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 12204 *colname++ = '\0'; 12205 else if ((colname = strchr(peername, '|'))) 12206 *colname++ = '\0'; 12207 else 12208 colname = "ip"; 12209 12210 if (!(peer = find_peer(peername, 1))) 12211 return -1; 12212 12213 if (!strcasecmp(colname, "ip")) { 12214 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12215 } else if (!strcasecmp(colname, "status")) { 12216 peer_status(peer, buf, len); 12217 } else if (!strcasecmp(colname, "mailbox")) { 12218 ast_copy_string(buf, peer->mailbox, len); 12219 } else if (!strcasecmp(colname, "context")) { 12220 ast_copy_string(buf, peer->context, len); 12221 } else if (!strcasecmp(colname, "expire")) { 12222 snprintf(buf, len, "%d", peer->expire); 12223 } else if (!strcasecmp(colname, "dynamic")) { 12224 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 12225 } else if (!strcasecmp(colname, "callerid_name")) { 12226 ast_copy_string(buf, peer->cid_name, len); 12227 } else if (!strcasecmp(colname, "callerid_num")) { 12228 ast_copy_string(buf, peer->cid_num, len); 12229 } else if (!strcasecmp(colname, "codecs")) { 12230 ast_getformatname_multiple(buf, len -1, peer->capability); 12231 } else if (!strncasecmp(colname, "codec[", 6)) { 12232 char *codecnum, *ptr; 12233 int index = 0, codec = 0; 12234 12235 codecnum = strchr(colname, '['); 12236 *codecnum = '\0'; 12237 codecnum++; 12238 if ((ptr = strchr(codecnum, ']'))) { 12239 *ptr = '\0'; 12240 } 12241 index = atoi(codecnum); 12242 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12243 ast_copy_string(buf, ast_getformatname(codec), len); 12244 } else { 12245 buf[0] = '\0'; 12246 } 12247 } else { 12248 buf[0] = '\0'; 12249 } 12250 12251 peer_unref(peer); 12252 12253 return 0; 12254 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 10681 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
10682 { 10683 int methods = 0; 10684 if (strstr(value, "rsa")) 10685 methods |= IAX_AUTH_RSA; 10686 if (strstr(value, "md5")) 10687 methods |= IAX_AUTH_MD5; 10688 if (strstr(value, "plaintext")) 10689 methods |= IAX_AUTH_PLAINTEXT; 10690 return methods; 10691 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1188 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01189 { 01190 int e; 01191 if (!strcasecmp(s, "aes128")) 01192 e = IAX_ENCRYPT_AES128; 01193 else if (ast_true(s)) 01194 e = IAX_ENCRYPT_AES128; 01195 else 01196 e = 0; 01197 return e; 01198 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3582 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03583 { 03584 #ifdef SCHED_MULTITHREADED 03585 if (schedule_action(__get_from_jb, data)) 03586 #endif 03587 __get_from_jb(data); 03588 return 0; 03589 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2247 of file chan_iax2.c.
References ao2_container_count(), ao2_find(), ao2_lock(), ao2_unlock(), ast_log(), LOG_WARNING, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02248 { 02249 struct callno_entry *callno_entry = NULL; 02250 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02251 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02252 /* Minor optimization for the extreme case. */ 02253 return NULL; 02254 } 02255 02256 /* the callno_pool container is locked here primarily to ensure thread 02257 * safety of the total_nonval_callno_used check and increment */ 02258 ao2_lock(callno_pool); 02259 02260 /* only a certain number of nonvalidated call numbers should be allocated. 02261 * If there ever is an attack, this separates the calltoken validating 02262 * users from the non calltoken validating users. */ 02263 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02264 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02265 ao2_unlock(callno_pool); 02266 return NULL; 02267 } 02268 02269 /* unlink the object from the container, taking over ownership 02270 * of the reference the container had to the object */ 02271 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02272 02273 if (callno_entry) { 02274 callno_entry->validated = validated; 02275 if (!validated) { 02276 total_nonval_callno_used++; 02277 } 02278 } 02279 02280 ao2_unlock(callno_pool); 02281 return callno_entry; 02282 }
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 4286 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().
04288 { 04289 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04290 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04291 char buf[256] = { 0 }; 04292 time_t t = time(NULL); 04293 char hash[41]; /* 40 char sha1 hash */ 04294 int subclass = uncompress_subclass(fh->csub); 04295 04296 /* ----- Case 1 ----- */ 04297 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04298 struct iax_ie_data ied = { 04299 .buf = { 0 }, 04300 .pos = 0, 04301 }; 04302 04303 /* create the hash with their address data and our timestamp */ 04304 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04305 ast_sha1_hash(hash, buf); 04306 04307 snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04308 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf); 04309 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04310 04311 return 1; 04312 04313 /* ----- Case 2 ----- */ 04314 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04315 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04316 char *rec_ts = NULL; /* received timestamp */ 04317 unsigned int rec_time; /* received time_t */ 04318 04319 /* split the timestamp from the hash data */ 04320 rec_hash = strchr((char *) ies->calltokendata, '?'); 04321 if (rec_hash) { 04322 *rec_hash++ = '\0'; 04323 rec_ts = (char *) ies->calltokendata; 04324 } 04325 04326 /* check that we have valid data before we do any comparisons */ 04327 if (!rec_hash || !rec_ts) { 04328 goto reject; 04329 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04330 goto reject; 04331 } 04332 04333 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04334 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04335 ast_sha1_hash(hash, buf); 04336 04337 /* compare hashes and then check timestamp delay */ 04338 if (strcmp(hash, rec_hash)) { 04339 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04340 goto reject; /* received hash does not match ours, reject */ 04341 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04342 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04343 goto reject; /* too much delay, reject */ 04344 } 04345 04346 /* at this point the call token is valid, returning 0 04347 * will allow socket_process to continue as usual */ 04348 requirecalltoken_mark_auto(ies->username, subclass); 04349 return 0; 04350 04351 /* ----- Case 3 ----- */ 04352 } else { /* calltokens are not supported for this client, how do we respond? */ 04353 if (calltoken_required(sin, ies->username, subclass)) { 04354 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest")); 04355 goto reject; 04356 } 04357 return 0; /* calltoken is not required for this addr, so permit it. */ 04358 } 04359 04360 reject: 04361 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04362 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04363 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04364 } else { 04365 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04366 } 04367 04368 return 1; 04369 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 8228 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.
Referenced by iax2_process_thread().
08229 { 08230 struct iax2_pkt_buf *pkt_buf; 08231 08232 ast_mutex_lock(&thread->lock); 08233 08234 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 08235 ast_mutex_unlock(&thread->lock); 08236 08237 thread->buf = pkt_buf->buf; 08238 thread->buf_len = pkt_buf->len; 08239 thread->buf_size = pkt_buf->len + 1; 08240 08241 socket_process(thread); 08242 08243 thread->buf = NULL; 08244 ast_free(pkt_buf); 08245 08246 ast_mutex_lock(&thread->lock); 08247 } 08248 08249 ast_mutex_unlock(&thread->lock); 08250 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2946 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().
02947 { 02948 /* XXX Ideally we should figure out why an error occured and then abort those 02949 rather than continuing to try. Unfortunately, the published interface does 02950 not seem to work XXX */ 02951 #if 0 02952 struct sockaddr_in *sin; 02953 int res; 02954 struct msghdr m; 02955 struct sock_extended_err e; 02956 m.msg_name = NULL; 02957 m.msg_namelen = 0; 02958 m.msg_iov = NULL; 02959 m.msg_control = &e; 02960 m.msg_controllen = sizeof(e); 02961 m.msg_flags = 0; 02962 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02963 if (res < 0) 02964 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02965 else { 02966 if (m.msg_controllen) { 02967 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02968 if (sin) 02969 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02970 else 02971 ast_log(LOG_WARNING, "No address detected??\n"); 02972 } else { 02973 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02974 } 02975 } 02976 #endif 02977 return 0; 02978 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 7278 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().
07279 { 07280 struct iax2_registry *reg; 07281 /* Start pessimistic */ 07282 char peer[256] = ""; 07283 char msgstatus[60]; 07284 int refresh = 60; 07285 char ourip[256] = "<Unspecified>"; 07286 struct sockaddr_in oldus; 07287 struct sockaddr_in us; 07288 int oldmsgs; 07289 07290 memset(&us, 0, sizeof(us)); 07291 if (ies->apparent_addr) 07292 bcopy(ies->apparent_addr, &us, sizeof(us)); 07293 if (ies->username) 07294 ast_copy_string(peer, ies->username, sizeof(peer)); 07295 if (ies->refresh) 07296 refresh = ies->refresh; 07297 if (ies->calling_number) { 07298 /* We don't do anything with it really, but maybe we should */ 07299 } 07300 reg = iaxs[callno]->reg; 07301 if (!reg) { 07302 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 07303 return -1; 07304 } 07305 memcpy(&oldus, ®->us, sizeof(oldus)); 07306 oldmsgs = reg->messages; 07307 if (inaddrcmp(®->addr, sin)) { 07308 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07309 return -1; 07310 } 07311 memcpy(®->us, &us, sizeof(reg->us)); 07312 if (ies->msgcount >= 0) 07313 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 07314 /* always refresh the registration at the interval requested by the server 07315 we are registering to 07316 */ 07317 reg->refresh = refresh; 07318 AST_SCHED_DEL(sched, reg->expire); 07319 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07320 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 07321 if (option_verbose > 2) { 07322 if (reg->messages > 255) 07323 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 07324 else if (reg->messages > 1) 07325 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 07326 else if (reg->messages > 0) 07327 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 07328 else 07329 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 07330 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07331 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 07332 } 07333 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 07334 } 07335 reg->regstate = REG_STATE_REGISTERED; 07336 return 0; 07337 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2391 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().
02392 { 02393 if (frametype != AST_FRAME_IAX) { 02394 return 0; 02395 } 02396 switch (subclass) { 02397 case IAX_COMMAND_NEW: 02398 case IAX_COMMAND_REGREQ: 02399 case IAX_COMMAND_FWDOWNL: 02400 case IAX_COMMAND_REGREL: 02401 return 1; 02402 case IAX_COMMAND_POKE: 02403 if (!inbound) { 02404 return 1; 02405 } 02406 break; 02407 } 02408 return 0; 02409 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4900 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.
04901 { 04902 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04903 if (option_debug) 04904 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 04905 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 04906 }
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 4745 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.
04746 { 04747 struct ast_channel *cs[3]; 04748 struct ast_channel *who, *other; 04749 int to = -1; 04750 int res = -1; 04751 int transferstarted=0; 04752 struct ast_frame *f; 04753 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 04754 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 04755 struct timeval waittimer = {0, 0}, tv; 04756 04757 lock_both(callno0, callno1); 04758 if (!iaxs[callno0] || !iaxs[callno1]) { 04759 unlock_both(callno0, callno1); 04760 return AST_BRIDGE_FAILED; 04761 } 04762 /* Put them in native bridge mode */ 04763 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 04764 iaxs[callno0]->bridgecallno = callno1; 04765 iaxs[callno1]->bridgecallno = callno0; 04766 } 04767 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 04768 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 04769 transferstarted = 1; 04770 } 04771 unlock_both(callno0, callno1); 04772 04773 /* If not, try to bridge until we can execute a transfer, if we can */ 04774 cs[0] = c0; 04775 cs[1] = c1; 04776 for (/* ever */;;) { 04777 /* Check in case we got masqueraded into */ 04778 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 04779 if (option_verbose > 2) 04780 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 04781 /* Remove from native mode */ 04782 if (c0->tech == &iax2_tech) { 04783 ast_mutex_lock(&iaxsl[callno0]); 04784 iaxs[callno0]->bridgecallno = 0; 04785 ast_mutex_unlock(&iaxsl[callno0]); 04786 } 04787 if (c1->tech == &iax2_tech) { 04788 ast_mutex_lock(&iaxsl[callno1]); 04789 iaxs[callno1]->bridgecallno = 0; 04790 ast_mutex_unlock(&iaxsl[callno1]); 04791 } 04792 return AST_BRIDGE_FAILED_NOWARN; 04793 } 04794 if (c0->nativeformats != c1->nativeformats) { 04795 if (option_verbose > 2) { 04796 char buf0[255]; 04797 char buf1[255]; 04798 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 04799 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 04800 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 04801 } 04802 /* Remove from native mode */ 04803 lock_both(callno0, callno1); 04804 if (iaxs[callno0]) 04805 iaxs[callno0]->bridgecallno = 0; 04806 if (iaxs[callno1]) 04807 iaxs[callno1]->bridgecallno = 0; 04808 unlock_both(callno0, callno1); 04809 return AST_BRIDGE_FAILED_NOWARN; 04810 } 04811 /* check if transfered and if we really want native bridging */ 04812 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 04813 /* Try the transfer */ 04814 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 04815 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 04816 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 04817 transferstarted = 1; 04818 } 04819 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 04820 /* Call has been transferred. We're no longer involved */ 04821 gettimeofday(&tv, NULL); 04822 if (ast_tvzero(waittimer)) { 04823 waittimer = tv; 04824 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 04825 c0->_softhangup |= AST_SOFTHANGUP_DEV; 04826 c1->_softhangup |= AST_SOFTHANGUP_DEV; 04827 *fo = NULL; 04828 *rc = c0; 04829 res = AST_BRIDGE_COMPLETE; 04830 break; 04831 } 04832 } 04833 to = 1000; 04834 who = ast_waitfor_n(cs, 2, &to); 04835 if (timeoutms > -1) { 04836 timeoutms -= (1000 - to); 04837 if (timeoutms < 0) 04838 timeoutms = 0; 04839 } 04840 if (!who) { 04841 if (!timeoutms) { 04842 res = AST_BRIDGE_RETRY; 04843 break; 04844 } 04845 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 04846 res = AST_BRIDGE_FAILED; 04847 break; 04848 } 04849 continue; 04850 } 04851 f = ast_read(who); 04852 if (!f) { 04853 *fo = NULL; 04854 *rc = who; 04855 res = AST_BRIDGE_COMPLETE; 04856 break; 04857 } 04858 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 04859 *fo = f; 04860 *rc = who; 04861 res = AST_BRIDGE_COMPLETE; 04862 break; 04863 } 04864 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 04865 if ((f->frametype == AST_FRAME_VOICE) || 04866 (f->frametype == AST_FRAME_TEXT) || 04867 (f->frametype == AST_FRAME_VIDEO) || 04868 (f->frametype == AST_FRAME_IMAGE) || 04869 (f->frametype == AST_FRAME_DTMF) || 04870 (f->frametype == AST_FRAME_CONTROL)) { 04871 /* monitored dtmf take out of the bridge. 04872 * check if we monitor the specific source. 04873 */ 04874 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 04875 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 04876 *rc = who; 04877 *fo = f; 04878 res = AST_BRIDGE_COMPLETE; 04879 /* Remove from native mode */ 04880 break; 04881 } 04882 /* everything else goes to the other side */ 04883 ast_write(other, f); 04884 } 04885 ast_frfree(f); 04886 /* Swap who gets priority */ 04887 cs[2] = cs[0]; 04888 cs[0] = cs[1]; 04889 cs[1] = cs[2]; 04890 } 04891 lock_both(callno0, callno1); 04892 if(iaxs[callno0]) 04893 iaxs[callno0]->bridgecallno = 0; 04894 if(iaxs[callno1]) 04895 iaxs[callno1]->bridgecallno = 0; 04896 unlock_both(callno0, callno1); 04897 return res; 04898 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4429 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.
04430 { 04431 struct sockaddr_in sin; 04432 char *l=NULL, *n=NULL, *tmpstr; 04433 struct iax_ie_data ied; 04434 char *defaultrdest = "s"; 04435 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04436 struct parsed_dial_string pds; 04437 struct create_addr_info cai; 04438 04439 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04440 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04441 return -1; 04442 } 04443 04444 memset(&cai, 0, sizeof(cai)); 04445 cai.encmethods = iax2_encryption; 04446 04447 memset(&pds, 0, sizeof(pds)); 04448 tmpstr = ast_strdupa(dest); 04449 parse_dial_string(tmpstr, &pds); 04450 04451 if (ast_strlen_zero(pds.peer)) { 04452 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04453 return -1; 04454 } 04455 04456 if (!pds.exten) { 04457 pds.exten = defaultrdest; 04458 } 04459 04460 if (create_addr(pds.peer, c, &sin, &cai)) { 04461 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04462 return -1; 04463 } 04464 04465 if (!pds.username && !ast_strlen_zero(cai.username)) 04466 pds.username = cai.username; 04467 if (!pds.password && !ast_strlen_zero(cai.secret)) 04468 pds.password = cai.secret; 04469 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04470 pds.key = cai.outkey; 04471 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04472 pds.context = cai.peercontext; 04473 04474 /* Keep track of the context for outgoing calls too */ 04475 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04476 04477 if (pds.port) 04478 sin.sin_port = htons(atoi(pds.port)); 04479 04480 l = c->cid.cid_num; 04481 n = c->cid.cid_name; 04482 04483 /* Now build request */ 04484 memset(&ied, 0, sizeof(ied)); 04485 04486 /* On new call, first IE MUST be IAX version of caller */ 04487 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04488 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04489 if (pds.options && strchr(pds.options, 'a')) { 04490 /* Request auto answer */ 04491 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04492 } 04493 04494 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04495 04496 if (l) { 04497 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04498 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04499 } else { 04500 if (n) 04501 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04502 else 04503 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04504 } 04505 04506 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04507 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04508 04509 if (n) 04510 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04511 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04512 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04513 04514 if (!ast_strlen_zero(c->language)) 04515 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04516 if (!ast_strlen_zero(c->cid.cid_dnid)) 04517 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04518 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04519 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04520 04521 if (pds.context) 04522 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04523 04524 if (pds.username) 04525 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04526 04527 if (cai.encmethods) 04528 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04529 04530 ast_mutex_lock(&iaxsl[callno]); 04531 04532 if (!ast_strlen_zero(c->context)) 04533 ast_string_field_set(iaxs[callno], context, c->context); 04534 04535 if (pds.username) 04536 ast_string_field_set(iaxs[callno], username, pds.username); 04537 04538 iaxs[callno]->encmethods = cai.encmethods; 04539 04540 iaxs[callno]->adsi = cai.adsi; 04541 04542 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04543 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04544 04545 if (pds.key) 04546 ast_string_field_set(iaxs[callno], outkey, pds.key); 04547 if (pds.password) 04548 ast_string_field_set(iaxs[callno], secret, pds.password); 04549 04550 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04551 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04552 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04553 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04554 04555 if (iaxs[callno]->maxtime) { 04556 /* Initialize pingtime and auto-congest time */ 04557 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04558 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04559 } else if (autokill) { 04560 iaxs[callno]->pingtime = autokill / 2; 04561 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04562 } 04563 04564 /* send the command using the appropriate socket for this peer */ 04565 iaxs[callno]->sockfd = cai.sockfd; 04566 04567 /* Transmit the string in a "NEW" request */ 04568 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04569 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04570 04571 ast_mutex_unlock(&iaxsl[callno]); 04572 ast_setstate(c, AST_STATE_RINGING); 04573 04574 return 0; 04575 }
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 12088 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.
12089 { 12090 int res = 0; 12091 struct iax2_dpcache *dp; 12092 #if 0 12093 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12094 #endif 12095 if ((priority != 1) && (priority != 2)) 12096 return 0; 12097 ast_mutex_lock(&dpcache_lock); 12098 dp = find_cache(chan, data, context, exten, priority); 12099 if (dp) { 12100 if (dp->flags & CACHE_FLAG_CANEXIST) 12101 res= 1; 12102 } 12103 ast_mutex_unlock(&dpcache_lock); 12104 if (!dp) { 12105 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12106 } 12107 return res; 12108 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4096 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
04097 { 04098 time_t t; 04099 struct tm tm; 04100 unsigned int tmp; 04101 time(&t); 04102 if (!ast_strlen_zero(tz)) 04103 ast_localtime(&t, &tm, tz); 04104 else 04105 ast_localtime(&t, &tm, NULL); 04106 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04107 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04108 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04109 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04110 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04111 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04112 return tmp; 04113 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1480 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().
01481 { 01482 struct chan_iax2_pvt *pvt; 01483 struct ast_channel *owner; 01484 01485 retry: 01486 pvt = iaxs[callno]; 01487 01488 owner = pvt ? pvt->owner : NULL; 01489 01490 if (owner) { 01491 if (ast_mutex_trylock(&owner->lock)) { 01492 if (option_debug > 2) 01493 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01494 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01495 goto retry; 01496 } 01497 } 01498 01499 /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we 01500 * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee 01501 * the pvt stays around, a ref count is added to it. */ 01502 if (!owner && pvt) { 01503 ao2_ref(pvt, +1); 01504 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01505 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01506 ao2_ref(pvt, -1); 01507 if (iaxs[callno]) { 01508 iaxs[callno] = NULL; 01509 } else { 01510 pvt = NULL; 01511 } 01512 } 01513 01514 if (pvt) { 01515 if (!owner) { 01516 pvt->owner = NULL; 01517 } else { 01518 /* If there's an owner, prod it to give up */ 01519 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01520 * because we already hold the owner channel lock. */ 01521 ast_queue_hangup(owner); 01522 } 01523 01524 if (pvt->peercallno) { 01525 remove_by_peercallno(pvt); 01526 } 01527 01528 if (pvt->transfercallno) { 01529 remove_by_transfercallno(pvt); 01530 } 01531 01532 if (!owner) { 01533 ao2_ref(pvt, -1); 01534 pvt = NULL; 01535 } 01536 } 01537 01538 if (owner) { 01539 ast_mutex_unlock(&owner->lock); 01540 } 01541 01542 if (callno & 0x4000) { 01543 update_max_trunk(); 01544 } 01545 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1391 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().
01392 { 01393 /* Decrement AUTHREQ count if needed */ 01394 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01395 struct iax2_user *user; 01396 struct iax2_user tmp_user = { 01397 .name = pvt->username, 01398 }; 01399 01400 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01401 if (user) { 01402 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01403 user = user_unref(user); 01404 } 01405 01406 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01407 } 01408 01409 /* No more pings or lagrq's */ 01410 AST_SCHED_DEL(sched, pvt->pingid); 01411 AST_SCHED_DEL(sched, pvt->lagid); 01412 AST_SCHED_DEL(sched, pvt->autoid); 01413 AST_SCHED_DEL(sched, pvt->authid); 01414 AST_SCHED_DEL(sched, pvt->initid); 01415 AST_SCHED_DEL(sched, pvt->jbid); 01416 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 12279 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().
12280 { 12281 struct parsed_dial_string pds; 12282 char *tmp = ast_strdupa(data); 12283 struct iax2_peer *p; 12284 int res = AST_DEVICE_INVALID; 12285 12286 memset(&pds, 0, sizeof(pds)); 12287 parse_dial_string(tmp, &pds); 12288 12289 if (ast_strlen_zero(pds.peer)) { 12290 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12291 return res; 12292 } 12293 12294 if (option_debug > 2) 12295 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 12296 12297 /* SLD: FIXME: second call to find_peer during registration */ 12298 if (!(p = find_peer(pds.peer, 1))) 12299 return res; 12300 12301 res = AST_DEVICE_UNAVAILABLE; 12302 if (option_debug > 2) 12303 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 12304 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 12305 12306 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 12307 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 12308 /* Peer is registered, or have default IP address 12309 and a valid registration */ 12310 if (p->historicms == 0 || p->historicms <= p->maxms) 12311 /* let the core figure out whether it is in use or not */ 12312 res = AST_DEVICE_UNKNOWN; 12313 } 12314 12315 peer_unref(p); 12316 12317 return res; 12318 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 3712 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03713 { 03714 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 03715 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 3717 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03718 { 03719 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 03720 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6265 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06266 { 06267 if (argc < 2 || argc > 3) 06268 return RESULT_SHOWUSAGE; 06269 iaxdebug = 1; 06270 ast_cli(fd, "IAX2 Debugging Enabled\n"); 06271 return RESULT_SUCCESS; 06272 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6283 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06284 { 06285 if (argc < 3 || argc > 4) 06286 return RESULT_SHOWUSAGE; 06287 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 06288 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 06289 return RESULT_SUCCESS; 06290 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 10161 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().
10162 { 10163 struct iax_ie_data ied; 10164 if (option_debug && iaxdebug) 10165 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 10166 10167 if (reg->dnsmgr && 10168 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 10169 /* Maybe the IP has changed, force DNS refresh */ 10170 ast_dnsmgr_refresh(reg->dnsmgr); 10171 } 10172 10173 /* 10174 * if IP has Changed, free allocated call to create a new one with new IP 10175 * call has the pointer to IP and must be updated to the new one 10176 */ 10177 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 10178 int callno = reg->callno; 10179 ast_mutex_lock(&iaxsl[callno]); 10180 iax2_destroy(callno); 10181 ast_mutex_unlock(&iaxsl[callno]); 10182 reg->callno = 0; 10183 } 10184 if (!reg->addr.sin_addr.s_addr) { 10185 if (option_debug && iaxdebug) 10186 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 10187 /* Setup the next registration attempt */ 10188 AST_SCHED_DEL(sched, reg->expire); 10189 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10190 return -1; 10191 } 10192 10193 if (!reg->callno) { 10194 if (option_debug) 10195 ast_log(LOG_DEBUG, "Allocate call number\n"); 10196 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 10197 if (reg->callno < 1) { 10198 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 10199 return -1; 10200 } else if (option_debug) 10201 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 10202 iaxs[reg->callno]->reg = reg; 10203 ast_mutex_unlock(&iaxsl[reg->callno]); 10204 } 10205 /* Schedule the next registration attempt */ 10206 AST_SCHED_DEL(sched, reg->expire); 10207 /* Setup the next registration a little early */ 10208 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10209 /* Send the request */ 10210 memset(&ied, 0, sizeof(ied)); 10211 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 10212 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 10213 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 10214 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 10215 reg->regstate = REG_STATE_REGSENT; 10216 return 0; 10217 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7109 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
07110 { 07111 #ifdef SCHED_MULTITHREADED 07112 if (schedule_action(__iax2_do_register_s, data)) 07113 #endif 07114 __iax2_do_register_s(data); 07115 return 0; 07116 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6274 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06275 { 06276 if (argc < 3 || argc > 4) 06277 return RESULT_SHOWUSAGE; 06278 iaxtrunkdebug = 1; 06279 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 06280 return RESULT_SUCCESS; 06281 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 7839 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().
07840 { 07841 struct iax_ie_data ied; 07842 /* Auto-hangup with 30 seconds of inactivity */ 07843 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 07844 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 07845 memset(&ied, 0, sizeof(ied)); 07846 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 07847 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 07848 dp->flags |= CACHE_FLAG_TRANSMITTED; 07849 }
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 12134 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.
12135 { 12136 char odata[256]; 12137 char req[256]; 12138 char *ncontext; 12139 struct iax2_dpcache *dp; 12140 struct ast_app *dial; 12141 #if 0 12142 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); 12143 #endif 12144 if (priority == 2) { 12145 /* Indicate status, can be overridden in dialplan */ 12146 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 12147 if (dialstatus) { 12148 dial = pbx_findapp(dialstatus); 12149 if (dial) 12150 pbx_exec(chan, dial, ""); 12151 } 12152 return -1; 12153 } else if (priority != 1) 12154 return -1; 12155 ast_mutex_lock(&dpcache_lock); 12156 dp = find_cache(chan, data, context, exten, priority); 12157 if (dp) { 12158 if (dp->flags & CACHE_FLAG_EXISTS) { 12159 ast_copy_string(odata, data, sizeof(odata)); 12160 ncontext = strchr(odata, '/'); 12161 if (ncontext) { 12162 *ncontext = '\0'; 12163 ncontext++; 12164 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 12165 } else { 12166 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 12167 } 12168 if (option_verbose > 2) 12169 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 12170 } else { 12171 ast_mutex_unlock(&dpcache_lock); 12172 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 12173 return -1; 12174 } 12175 } 12176 ast_mutex_unlock(&dpcache_lock); 12177 dial = pbx_findapp("Dial"); 12178 if (dial) { 12179 return pbx_exec(chan, dial, req); 12180 } else { 12181 ast_log(LOG_WARNING, "No dial application registered\n"); 12182 } 12183 return -1; 12184 }
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 12065 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.
12066 { 12067 struct iax2_dpcache *dp; 12068 int res = 0; 12069 #if 0 12070 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12071 #endif 12072 if ((priority != 1) && (priority != 2)) 12073 return 0; 12074 ast_mutex_lock(&dpcache_lock); 12075 dp = find_cache(chan, data, context, exten, priority); 12076 if (dp) { 12077 if (dp->flags & CACHE_FLAG_EXISTS) 12078 res= 1; 12079 } 12080 ast_mutex_unlock(&dpcache_lock); 12081 if (!dp) { 12082 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12083 } 12084 return res; 12085 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3739 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.
03740 { 03741 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 03742 ast_mutex_lock(&iaxsl[callno]); 03743 if (iaxs[callno]) 03744 iaxs[callno]->owner = newchan; 03745 else 03746 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 03747 ast_mutex_unlock(&iaxsl[callno]); 03748 return 0; 03749 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1474 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().
01475 { 01476 AST_SCHED_DEL(sched, fr->retrans); 01477 iax_frame_free(fr); 01478 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1360 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().
01361 { 01362 struct iax2_peer *peer = NULL; 01363 int res = 0; 01364 struct ao2_iterator i; 01365 01366 i = ao2_iterator_init(peers, 0); 01367 while ((peer = ao2_iterator_next(&i))) { 01368 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01369 (peer->addr.sin_port == sin.sin_port)) { 01370 ast_copy_string(host, peer->name, len); 01371 peer_unref(peer); 01372 res = 1; 01373 break; 01374 } 01375 peer_unref(peer); 01376 } 01377 ao2_iterator_destroy(&i); 01378 01379 if (!peer) { 01380 peer = realtime_peer(NULL, &sin); 01381 if (peer) { 01382 ast_copy_string(host, peer->name, len); 01383 peer_unref(peer); 01384 res = 1; 01385 } 01386 } 01387 01388 return res; 01389 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 4967 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().
04968 { 04969 struct iax2_peer *peer; 04970 int res = 0; 04971 struct ao2_iterator i; 04972 04973 i = ao2_iterator_init(peers, 0); 04974 while ((peer = ao2_iterator_next(&i))) { 04975 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 04976 (peer->addr.sin_port == sin.sin_port)) { 04977 res = ast_test_flag(peer, IAX_TRUNK); 04978 peer_unref(peer); 04979 break; 04980 } 04981 peer_unref(peer); 04982 } 04983 ao2_iterator_destroy(&i); 04984 04985 return res; 04986 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4577 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.
04578 { 04579 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04580 struct iax_ie_data ied; 04581 int alreadygone; 04582 memset(&ied, 0, sizeof(ied)); 04583 ast_mutex_lock(&iaxsl[callno]); 04584 if (callno && iaxs[callno]) { 04585 if (option_debug) 04586 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 04587 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04588 /* Send the hangup unless we have had a transmission error or are already gone */ 04589 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04590 if (!iaxs[callno]->error && !alreadygone) { 04591 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04592 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04593 } 04594 if (!iaxs[callno]) { 04595 ast_mutex_unlock(&iaxsl[callno]); 04596 return 0; 04597 } 04598 } 04599 /* Explicitly predestroy it */ 04600 iax2_predestroy(callno); 04601 /* If we were already gone to begin with, destroy us now */ 04602 if (iaxs[callno] && alreadygone) { 04603 if (option_debug) 04604 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 04605 iax2_destroy(callno); 04606 } else if (iaxs[callno]) { 04607 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 04608 } 04609 } else if (c->tech_pvt) { 04610 /* If this call no longer exists, but the channel still 04611 * references it we need to set the channel's tech_pvt to null 04612 * to avoid ast_channel_free() trying to free it. 04613 */ 04614 c->tech_pvt = NULL; 04615 } 04616 ast_mutex_unlock(&iaxsl[callno]); 04617 if (option_verbose > 2) 04618 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 04619 return 0; 04620 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 4908 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().
04909 { 04910 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04911 struct chan_iax2_pvt *pvt; 04912 int res = 0; 04913 04914 if (option_debug && iaxdebug) 04915 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 04916 04917 ast_mutex_lock(&iaxsl[callno]); 04918 pvt = iaxs[callno]; 04919 04920 if (wait_for_peercallno(pvt)) { 04921 res = -1; 04922 goto done; 04923 } 04924 04925 switch (condition) { 04926 case AST_CONTROL_HOLD: 04927 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04928 ast_moh_start(c, data, pvt->mohinterpret); 04929 goto done; 04930 } 04931 break; 04932 case AST_CONTROL_UNHOLD: 04933 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04934 ast_moh_stop(c); 04935 goto done; 04936 } 04937 } 04938 04939 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 04940 04941 done: 04942 ast_mutex_unlock(&iaxsl[callno]); 04943 04944 return res; 04945 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1032 of file chan_iax2.c.
References ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxs.
Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), and socket_process().
01033 { 01034 for (;;) { 01035 if (!iaxs[callno] || !iaxs[callno]->owner) { 01036 /* There is no owner lock to get. */ 01037 break; 01038 } 01039 if (!ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01040 /* We got the lock */ 01041 break; 01042 } 01043 /* Avoid deadlock by pausing and trying again */ 01044 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01045 } 01046 }
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 12111 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.
12112 { 12113 int res = 0; 12114 struct iax2_dpcache *dp; 12115 #if 0 12116 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 12117 #endif 12118 if ((priority != 1) && (priority != 2)) 12119 return 0; 12120 ast_mutex_lock(&dpcache_lock); 12121 dp = find_cache(chan, data, context, exten, priority); 12122 if (dp) { 12123 if (dp->flags & CACHE_FLAG_MATCHMORE) 12124 res= 1; 12125 } 12126 ast_mutex_unlock(&dpcache_lock); 12127 if (!dp) { 12128 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 12129 } 12130 return res; 12131 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6292 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06293 { 06294 if (argc < 3 || argc > 4) 06295 return RESULT_SHOWUSAGE; 06296 iaxdebug = 0; 06297 ast_cli(fd, "IAX2 Debugging Disabled\n"); 06298 return RESULT_SUCCESS; 06299 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6310 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06311 { 06312 if (argc < 4 || argc > 5) 06313 return RESULT_SHOWUSAGE; 06314 jb_setoutput(jb_error_output, jb_warning_output, NULL); 06315 jb_debug_output("\n"); 06316 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 06317 return RESULT_SUCCESS; 06318 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6301 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06302 { 06303 if (argc < 4 || argc > 5) 06304 return RESULT_SHOWUSAGE; 06305 iaxtrunkdebug = 0; 06306 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 06307 return RESULT_SUCCESS; 06308 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10361 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
10362 { 10363 struct iax2_peer *peer = (struct iax2_peer *)data; 10364 peer->pokeexpire = -1; 10365 #ifdef SCHED_MULTITHREADED 10366 if (schedule_action(__iax2_poke_noanswer, data)) 10367 #endif 10368 __iax2_poke_noanswer(data); 10369 peer_unref(peer); 10370 return 0; 10371 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 10382 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().
10383 { 10384 int callno; 10385 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 10386 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 10387 immediately after clearing things out */ 10388 peer->lastms = 0; 10389 peer->historicms = 0; 10390 peer->pokeexpire = -1; 10391 peer->callno = 0; 10392 return 0; 10393 } 10394 10395 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 10396 if ((callno = peer->callno) > 0) { 10397 ast_log(LOG_NOTICE, "Still have a callno...\n"); 10398 ast_mutex_lock(&iaxsl[callno]); 10399 iax2_destroy(callno); 10400 ast_mutex_unlock(&iaxsl[callno]); 10401 } 10402 if (heldcall) 10403 ast_mutex_unlock(&iaxsl[heldcall]); 10404 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 10405 if (heldcall) 10406 ast_mutex_lock(&iaxsl[heldcall]); 10407 if (peer->callno < 1) { 10408 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 10409 return -1; 10410 } 10411 10412 /* Speed up retransmission times for this qualify call */ 10413 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 10414 iaxs[peer->callno]->peerpoke = peer; 10415 10416 /* Remove any pending pokeexpire task */ 10417 if (peer->pokeexpire > -1) { 10418 if (!ast_sched_del(sched, peer->pokeexpire)) { 10419 peer->pokeexpire = -1; 10420 peer_unref(peer); 10421 } 10422 } 10423 10424 /* Queue up a new task to handle no reply */ 10425 /* If the host is already unreachable then use the unreachable interval instead */ 10426 if (peer->lastms < 0) { 10427 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 10428 } else 10429 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 10430 10431 if (peer->pokeexpire == -1) 10432 peer_unref(peer); 10433 10434 /* And send the poke */ 10435 ast_mutex_lock(&iaxsl[callno]); 10436 if (iaxs[callno]) { 10437 struct iax_ie_data ied = { 10438 .buf = { 0 }, 10439 .pos = 0, 10440 }; 10441 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 10442 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 10443 } 10444 ast_mutex_unlock(&iaxsl[callno]); 10445 10446 return 0; 10447 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10373 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
10374 { 10375 struct iax2_peer *peer = obj; 10376 10377 iax2_poke_peer(peer, 0); 10378 10379 return 0; 10380 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7879 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
07880 { 07881 struct iax2_peer *peer = (struct iax2_peer *)data; 07882 peer->pokeexpire = -1; 07883 #ifdef SCHED_MULTITHREADED 07884 if (schedule_action(__iax2_poke_peer_s, data)) 07885 #endif 07886 __iax2_poke_peer_s(data); 07887 return 0; 07888 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3030 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().
03031 { 03032 struct ast_channel *c; 03033 struct chan_iax2_pvt *pvt = iaxs[callno]; 03034 03035 if (!pvt) 03036 return -1; 03037 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 03038 iax2_destroy_helper(pvt); 03039 ast_set_flag(pvt, IAX_ALREADYGONE); 03040 } 03041 c = pvt->owner; 03042 if (c) { 03043 c->tech_pvt = NULL; 03044 iax2_queue_hangup(callno); 03045 pvt->owner = NULL; 03046 ast_module_unref(ast_module_info->self); 03047 } 03048 return 0; 03049 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 10037 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait(), ast_cond_wait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), iax2_thread::list, socket_process(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
10038 { 10039 struct iax2_thread *thread = data; 10040 struct timeval tv; 10041 struct timespec ts; 10042 int put_into_idle = 0; 10043 10044 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 10045 pthread_cleanup_push(iax2_process_thread_cleanup, data); 10046 for(;;) { 10047 pthread_testcancel(); 10048 10049 /* Wait for something to signal us to be awake */ 10050 ast_mutex_lock(&thread->lock); 10051 10052 /* Flag that we're ready to accept signals */ 10053 thread->ready_for_signal = 1; 10054 10055 /* Put into idle list if applicable */ 10056 if (put_into_idle) 10057 insert_idle_thread(thread); 10058 10059 if (thread->type == IAX_TYPE_DYNAMIC) { 10060 struct iax2_thread *t = NULL; 10061 /* Wait to be signalled or time out */ 10062 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 10063 ts.tv_sec = tv.tv_sec; 10064 ts.tv_nsec = tv.tv_usec * 1000; 10065 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 10066 /* This thread was never put back into the available dynamic 10067 * thread list, so just go away. */ 10068 if (!put_into_idle) { 10069 ast_mutex_unlock(&thread->lock); 10070 break; 10071 } 10072 AST_LIST_LOCK(&dynamic_list); 10073 /* Account for the case where this thread is acquired *right* after a timeout */ 10074 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 10075 iaxdynamicthreadcount--; 10076 AST_LIST_UNLOCK(&dynamic_list); 10077 if (t) { 10078 /* This dynamic thread timed out waiting for a task and was 10079 * not acquired immediately after the timeout, 10080 * so it's time to go away. */ 10081 ast_mutex_unlock(&thread->lock); 10082 break; 10083 } 10084 /* Someone grabbed our thread *right* after we timed out. 10085 * Wait for them to set us up with something to do and signal 10086 * us to continue. */ 10087 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 10088 ts.tv_sec = tv.tv_sec; 10089 ts.tv_nsec = tv.tv_usec * 1000; 10090 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 10091 { 10092 ast_mutex_unlock(&thread->lock); 10093 break; 10094 } 10095 } 10096 } else { 10097 ast_cond_wait(&thread->cond, &thread->lock); 10098 } 10099 10100 /* Go back into our respective list */ 10101 put_into_idle = 1; 10102 10103 ast_mutex_unlock(&thread->lock); 10104 10105 if (thread->iostate == IAX_IOSTATE_IDLE) 10106 continue; 10107 10108 /* See what we need to do */ 10109 switch(thread->iostate) { 10110 case IAX_IOSTATE_READY: 10111 thread->actions++; 10112 thread->iostate = IAX_IOSTATE_PROCESSING; 10113 socket_process(thread); 10114 handle_deferred_full_frames(thread); 10115 break; 10116 case IAX_IOSTATE_SCHEDREADY: 10117 thread->actions++; 10118 thread->iostate = IAX_IOSTATE_PROCESSING; 10119 #ifdef SCHED_MULTITHREADED 10120 thread->schedfunc(thread->scheddata); 10121 #endif 10122 break; 10123 } 10124 time(&thread->checktime); 10125 thread->iostate = IAX_IOSTATE_IDLE; 10126 #ifdef DEBUG_SCHED_MULTITHREAD 10127 thread->curfunc[0]='\0'; 10128 #endif 10129 10130 /* The network thread added us to the active_thread list when we were given 10131 * frames to process, Now that we are done, we must remove ourselves from 10132 * the active list, and return to the idle list */ 10133 AST_LIST_LOCK(&active_list); 10134 AST_LIST_REMOVE(&active_list, thread, list); 10135 AST_LIST_UNLOCK(&active_list); 10136 10137 /* Make sure another frame didn't sneak in there after we thought we were done. */ 10138 handle_deferred_full_frames(thread); 10139 } 10140 10141 /*!\note For some reason, idle threads are exiting without being removed 10142 * from an idle list, which is causing memory corruption. Forcibly remove 10143 * it from the list, if it's there. 10144 */ 10145 AST_LIST_LOCK(&idle_list); 10146 AST_LIST_REMOVE(&idle_list, thread, list); 10147 AST_LIST_UNLOCK(&idle_list); 10148 10149 AST_LIST_LOCK(&dynamic_list); 10150 AST_LIST_REMOVE(&dynamic_list, thread, list); 10151 AST_LIST_UNLOCK(&dynamic_list); 10152 10153 /* I am exiting here on my own volition, I need to clean up my own data structures 10154 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 10155 */ 10156 pthread_cleanup_pop(1); 10157 10158 return NULL; 10159 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 10028 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().
10029 { 10030 struct iax2_thread *thread = data; 10031 ast_mutex_destroy(&thread->lock); 10032 ast_cond_destroy(&thread->cond); 10033 free(thread); 10034 ast_atomic_dec_and_test(&iaxactivethreadcount); 10035 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10316 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
10317 { 10318 int force = 0; 10319 int res; 10320 if (argc < 4) 10321 return RESULT_SHOWUSAGE; 10322 if ((argc > 4)) { 10323 if (!strcasecmp(argv[4], "forced")) 10324 force = 1; 10325 else 10326 return RESULT_SHOWUSAGE; 10327 } 10328 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 10329 if (res < 0) 10330 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 10331 else if (res < 1) 10332 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 10333 else 10334 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 10335 return RESULT_SUCCESS; 10336 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10219 of file chan_iax2.c.
References iax_prov_complete_template().
10220 { 10221 if (pos != 3) 10222 return NULL; 10223 return iax_prov_complete_template(line, word, pos, state); 10224 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 10226 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().
10227 { 10228 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 10229 is found for template */ 10230 struct iax_ie_data provdata; 10231 struct iax_ie_data ied; 10232 unsigned int sig; 10233 struct sockaddr_in sin; 10234 int callno; 10235 struct create_addr_info cai; 10236 10237 memset(&cai, 0, sizeof(cai)); 10238 10239 if (option_debug) 10240 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 10241 10242 if (iax_provision_build(&provdata, &sig, template, force)) { 10243 if (option_debug) 10244 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 10245 return 0; 10246 } 10247 10248 if (end) { 10249 memcpy(&sin, end, sizeof(sin)); 10250 cai.sockfd = sockfd; 10251 } else if (create_addr(dest, NULL, &sin, &cai)) 10252 return -1; 10253 10254 /* Build the rest of the message */ 10255 memset(&ied, 0, sizeof(ied)); 10256 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 10257 10258 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10259 if (!callno) 10260 return -1; 10261 10262 if (iaxs[callno]) { 10263 /* Schedule autodestruct in case they don't ever give us anything back */ 10264 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 10265 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 10266 ast_set_flag(iaxs[callno], IAX_PROVISION); 10267 /* Got a call number now, so go ahead and send the provisioning information */ 10268 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 10269 } 10270 ast_mutex_unlock(&iaxsl[callno]); 10271 10272 return 1; 10273 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3168 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.
03169 { 03170 struct iax2_peer *peer = NULL; 03171 struct iax2_user *user = NULL; 03172 03173 if (argc != 4) 03174 return RESULT_SHOWUSAGE; 03175 if (!strcmp(argv[3],"all")) { 03176 prune_users(); 03177 prune_peers(); 03178 ast_cli(fd, "OK cache is flushed.\n"); 03179 return RESULT_SUCCESS; 03180 } 03181 peer = find_peer(argv[3], 0); 03182 user = find_user(argv[3]); 03183 if (peer || user) { 03184 if (peer) { 03185 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03186 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03187 expire_registry(peer_ref(peer)); 03188 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]); 03189 } else { 03190 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]); 03191 } 03192 peer_unref(peer); 03193 } 03194 if (user) { 03195 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03196 ast_set_flag(user, IAX_RTAUTOCLEAR); 03197 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]); 03198 } else { 03199 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]); 03200 } 03201 ao2_unlink(users,user); 03202 user_unref(user); 03203 } 03204 } else { 03205 ast_cli(fd, "%s was not found in the cache.\n", argv[3]); 03206 } 03207 03208 return RESULT_SUCCESS; 03209 }
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 2648 of file chan_iax2.c.
References ast_mutex_unlock(), ast_queue_control_data(), iax2_lock_owner(), iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
02650 { 02651 iax2_lock_owner(callno); 02652 if (iaxs[callno] && iaxs[callno]->owner) { 02653 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02654 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02655 } 02656 return 0; 02657 }
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 2602 of file chan_iax2.c.
References ast_mutex_unlock(), ast_queue_frame(), f, iax2_lock_owner(), iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02603 { 02604 iax2_lock_owner(callno); 02605 if (iaxs[callno] && iaxs[callno]->owner) { 02606 ast_queue_frame(iaxs[callno]->owner, f); 02607 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02608 } 02609 return 0; 02610 }
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 2625 of file chan_iax2.c.
References ast_mutex_unlock(), ast_queue_hangup(), iax2_lock_owner(), iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02626 { 02627 iax2_lock_owner(callno); 02628 if (iaxs[callno] && iaxs[callno]->owner) { 02629 ast_queue_hangup(iaxs[callno]->owner); 02630 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02631 } 02632 return 0; 02633 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4698 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
04699 { 04700 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 04701 return NULL; 04702 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 7339 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().
07340 { 07341 struct iax2_registry *reg; 07342 char copy[256]; 07343 char *username, *hostname, *secret; 07344 char *porta; 07345 char *stringp=NULL; 07346 07347 if (!value) 07348 return -1; 07349 ast_copy_string(copy, value, sizeof(copy)); 07350 stringp=copy; 07351 username = strsep(&stringp, "@"); 07352 hostname = strsep(&stringp, "@"); 07353 if (!hostname) { 07354 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 07355 return -1; 07356 } 07357 stringp=username; 07358 username = strsep(&stringp, ":"); 07359 secret = strsep(&stringp, ":"); 07360 stringp=hostname; 07361 hostname = strsep(&stringp, ":"); 07362 porta = strsep(&stringp, ":"); 07363 07364 if (porta && !atoi(porta)) { 07365 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 07366 return -1; 07367 } 07368 if (!(reg = ast_calloc(1, sizeof(*reg)))) 07369 return -1; 07370 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 07371 free(reg); 07372 return -1; 07373 } 07374 ast_copy_string(reg->username, username, sizeof(reg->username)); 07375 if (secret) 07376 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 07377 reg->expire = -1; 07378 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 07379 reg->addr.sin_family = AF_INET; 07380 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 07381 AST_LIST_LOCK(®istrations); 07382 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 07383 AST_LIST_UNLOCK(®istrations); 07384 07385 return 0; 07386 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11829 of file chan_iax2.c.
References reload_config().
11830 { 11831 return reload_config(); 11832 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 10459 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.
10460 { 10461 int callno; 10462 int res; 10463 int fmt, native; 10464 struct sockaddr_in sin; 10465 struct ast_channel *c; 10466 struct parsed_dial_string pds; 10467 struct create_addr_info cai; 10468 char *tmpstr; 10469 10470 memset(&pds, 0, sizeof(pds)); 10471 tmpstr = ast_strdupa(data); 10472 parse_dial_string(tmpstr, &pds); 10473 10474 if (ast_strlen_zero(pds.peer)) { 10475 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10476 return NULL; 10477 } 10478 10479 memset(&cai, 0, sizeof(cai)); 10480 cai.capability = iax2_capability; 10481 10482 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10483 10484 /* Populate our address from the given */ 10485 if (create_addr(pds.peer, NULL, &sin, &cai)) { 10486 *cause = AST_CAUSE_UNREGISTERED; 10487 return NULL; 10488 } 10489 10490 if (pds.port) 10491 sin.sin_port = htons(atoi(pds.port)); 10492 10493 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10494 if (callno < 1) { 10495 ast_log(LOG_WARNING, "Unable to create call\n"); 10496 *cause = AST_CAUSE_CONGESTION; 10497 return NULL; 10498 } 10499 10500 /* If this is a trunk, update it now */ 10501 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10502 if (ast_test_flag(&cai, IAX_TRUNK)) { 10503 int new_callno; 10504 if ((new_callno = make_trunk(callno, 1)) != -1) 10505 callno = new_callno; 10506 } 10507 iaxs[callno]->maxtime = cai.maxtime; 10508 if (cai.found) 10509 ast_string_field_set(iaxs[callno], host, pds.peer); 10510 10511 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 10512 10513 ast_mutex_unlock(&iaxsl[callno]); 10514 10515 if (c) { 10516 /* Choose a format we can live with */ 10517 if (c->nativeformats & format) 10518 c->nativeformats &= format; 10519 else { 10520 native = c->nativeformats; 10521 fmt = format; 10522 res = ast_translator_best_choice(&fmt, &native); 10523 if (res < 0) { 10524 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 10525 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 10526 ast_hangup(c); 10527 return NULL; 10528 } 10529 c->nativeformats = native; 10530 } 10531 c->readformat = ast_best_codec(c->nativeformats); 10532 c->writeformat = c->readformat; 10533 } 10534 10535 return c; 10536 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1143 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), and ast_sched_add().
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().
01144 { 01145 int res; 01146 01147 ast_mutex_lock(&sched_lock); 01148 res = ast_sched_add(con, when, callback, data); 01149 ast_cond_signal(&sched_cond); 01150 ast_mutex_unlock(&sched_lock); 01151 01152 return res; 01153 }
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 5565 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().
05566 { 05567 /* Queue a packet for delivery on a given private structure. Use "ts" for 05568 timestamp, or calculate if ts is 0. Send immediately without retransmission 05569 or delayed, with retransmission */ 05570 struct ast_iax2_full_hdr *fh; 05571 struct ast_iax2_mini_hdr *mh; 05572 struct ast_iax2_video_hdr *vh; 05573 struct { 05574 struct iax_frame fr2; 05575 unsigned char buffer[4096]; 05576 } frb; 05577 struct iax_frame *fr; 05578 int res; 05579 int sendmini=0; 05580 unsigned int lastsent; 05581 unsigned int fts; 05582 05583 frb.fr2.afdatalen = sizeof(frb.buffer); 05584 05585 if (!pvt) { 05586 ast_log(LOG_WARNING, "No private structure for packet?\n"); 05587 return -1; 05588 } 05589 05590 lastsent = pvt->lastsent; 05591 05592 /* Calculate actual timestamp */ 05593 fts = calc_timestamp(pvt, ts, f); 05594 05595 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 05596 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 05597 * increment the "predicted timestamps" for voice, if we're predecting */ 05598 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 05599 return 0; 05600 05601 05602 if ((ast_test_flag(pvt, IAX_TRUNK) || 05603 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 05604 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 05605 /* High two bytes are the same on timestamp, or sending on a trunk */ && 05606 (f->frametype == AST_FRAME_VOICE) 05607 /* is a voice frame */ && 05608 (f->subclass == pvt->svoiceformat) 05609 /* is the same type */ ) { 05610 /* Force immediate rather than delayed transmission */ 05611 now = 1; 05612 /* Mark that mini-style frame is appropriate */ 05613 sendmini = 1; 05614 } 05615 if ( f->frametype == AST_FRAME_VIDEO ) { 05616 /* 05617 * If the lower 15 bits of the timestamp roll over, or if 05618 * the video format changed then send a full frame. 05619 * Otherwise send a mini video frame 05620 */ 05621 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 05622 ((f->subclass & ~0x1) == pvt->svideoformat) 05623 ) { 05624 now = 1; 05625 sendmini = 1; 05626 } else { 05627 now = 0; 05628 sendmini = 0; 05629 } 05630 pvt->lastvsent = fts; 05631 } 05632 if (f->frametype == AST_FRAME_IAX) { 05633 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 05634 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 05635 if (!pvt->first_iax_message) { 05636 pvt->first_iax_message = pvt->last_iax_message; 05637 } 05638 } 05639 /* Allocate an iax_frame */ 05640 if (now) { 05641 fr = &frb.fr2; 05642 } else 05643 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)); 05644 if (!fr) { 05645 ast_log(LOG_WARNING, "Out of memory\n"); 05646 return -1; 05647 } 05648 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 05649 iax_frame_wrap(fr, f); 05650 05651 fr->ts = fts; 05652 fr->callno = pvt->callno; 05653 fr->transfer = transfer; 05654 fr->final = final; 05655 fr->encmethods = 0; 05656 if (!sendmini) { 05657 /* We need a full frame */ 05658 if (seqno > -1) 05659 fr->oseqno = seqno; 05660 else 05661 fr->oseqno = pvt->oseqno++; 05662 fr->iseqno = pvt->iseqno; 05663 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 05664 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 05665 fh->ts = htonl(fr->ts); 05666 fh->oseqno = fr->oseqno; 05667 if (transfer) { 05668 fh->iseqno = 0; 05669 } else 05670 fh->iseqno = fr->iseqno; 05671 /* Keep track of the last thing we've acknowledged */ 05672 if (!transfer) 05673 pvt->aseqno = fr->iseqno; 05674 fh->type = fr->af.frametype & 0xFF; 05675 if (fr->af.frametype == AST_FRAME_VIDEO) 05676 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 05677 else 05678 fh->csub = compress_subclass(fr->af.subclass); 05679 if (transfer) { 05680 fr->dcallno = pvt->transfercallno; 05681 } else 05682 fr->dcallno = pvt->peercallno; 05683 fh->dcallno = htons(fr->dcallno); 05684 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 05685 fr->data = fh; 05686 fr->retries = 0; 05687 /* Retry after 2x the ping time has passed */ 05688 fr->retrytime = pvt->pingtime * 2; 05689 if (fr->retrytime < MIN_RETRY_TIME) 05690 fr->retrytime = MIN_RETRY_TIME; 05691 if (fr->retrytime > MAX_RETRY_TIME) 05692 fr->retrytime = MAX_RETRY_TIME; 05693 /* Acks' don't get retried */ 05694 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 05695 fr->retries = -1; 05696 else if (f->frametype == AST_FRAME_VOICE) 05697 pvt->svoiceformat = f->subclass; 05698 else if (f->frametype == AST_FRAME_VIDEO) 05699 pvt->svideoformat = f->subclass & ~0x1; 05700 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05701 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05702 if (iaxdebug) { 05703 if (fr->transfer) 05704 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05705 else 05706 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05707 } 05708 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 05709 fr->encmethods = pvt->encmethods; 05710 fr->ecx = pvt->ecx; 05711 fr->mydcx = pvt->mydcx; 05712 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 05713 } else 05714 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05715 } 05716 05717 if (now) { 05718 res = send_packet(fr); 05719 } else 05720 res = iax2_transmit(fr); 05721 } else { 05722 if (ast_test_flag(pvt, IAX_TRUNK)) { 05723 iax2_trunk_queue(pvt, fr); 05724 res = 0; 05725 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 05726 /* Video frame have no sequence number */ 05727 fr->oseqno = -1; 05728 fr->iseqno = -1; 05729 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 05730 vh->zeros = 0; 05731 vh->callno = htons(0x8000 | fr->callno); 05732 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 05733 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 05734 fr->data = vh; 05735 fr->retries = -1; 05736 res = send_packet(fr); 05737 } else { 05738 /* Mini-frames have no sequence number */ 05739 fr->oseqno = -1; 05740 fr->iseqno = -1; 05741 /* Mini frame will do */ 05742 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 05743 mh->callno = htons(fr->callno); 05744 mh->ts = htons(fr->ts & 0xFFFF); 05745 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 05746 fr->data = mh; 05747 fr->retries = -1; 05748 if (pvt->transferring == TRANSFER_MEDIAPASS) 05749 fr->transfer = 1; 05750 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05751 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05752 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 05753 } else 05754 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05755 } 05756 res = send_packet(fr); 05757 } 05758 } 05759 return res; 05760 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3734 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03735 { 03736 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 03737 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 3729 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.
03730 { 03731 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 03732 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 3722 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03723 { 03724 03725 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 03726 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 03727 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4644 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_FLAG_REQUEST, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
04645 { 04646 struct ast_option_header *h; 04647 int res; 04648 04649 switch (option) { 04650 case AST_OPTION_TXGAIN: 04651 case AST_OPTION_RXGAIN: 04652 /* these two cannot be sent, because they require a result */ 04653 errno = ENOSYS; 04654 return -1; 04655 /* These options are sent to the other side across the network where 04656 * they will be passed to whatever channel is bridged there. Don't 04657 * do anything silly like pass an option that transmits pointers to 04658 * memory on this machine to a remote machine to use */ 04659 case AST_OPTION_TONE_VERIFY: 04660 case AST_OPTION_TDD: 04661 case AST_OPTION_RELAXDTMF: 04662 case AST_OPTION_AUDIO_MODE: 04663 { 04664 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04665 struct chan_iax2_pvt *pvt; 04666 04667 ast_mutex_lock(&iaxsl[callno]); 04668 pvt = iaxs[callno]; 04669 04670 if (wait_for_peercallno(pvt)) { 04671 ast_mutex_unlock(&iaxsl[callno]); 04672 return -1; 04673 } 04674 04675 ast_mutex_unlock(&iaxsl[callno]); 04676 04677 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 04678 return -1; 04679 } 04680 04681 h->flag = AST_OPTION_FLAG_REQUEST; 04682 h->option = htons(option); 04683 memcpy(h->data, data, datalen); 04684 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 04685 AST_CONTROL_OPTION, 0, (unsigned char *) h, 04686 datalen + sizeof(*h), -1); 04687 free(h); 04688 return res; 04689 } 04690 default: 04691 return -1; 04692 } 04693 04694 /* Just in case someone does a break instead of a return */ 04695 return -1; 04696 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3396 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.
03397 { 03398 struct iax2_dpcache *dp; 03399 char tmp[1024], *pc; 03400 int s; 03401 int x,y; 03402 struct timeval tv; 03403 gettimeofday(&tv, NULL); 03404 ast_mutex_lock(&dpcache_lock); 03405 dp = dpcache; 03406 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03407 while(dp) { 03408 s = dp->expiry.tv_sec - tv.tv_sec; 03409 tmp[0] = '\0'; 03410 if (dp->flags & CACHE_FLAG_EXISTS) 03411 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03412 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03413 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03414 if (dp->flags & CACHE_FLAG_CANEXIST) 03415 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03416 if (dp->flags & CACHE_FLAG_PENDING) 03417 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03418 if (dp->flags & CACHE_FLAG_TIMEOUT) 03419 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03420 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03421 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03422 if (dp->flags & CACHE_FLAG_MATCHMORE) 03423 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03424 if (dp->flags & CACHE_FLAG_UNKNOWN) 03425 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03426 /* Trim trailing pipe */ 03427 if (!ast_strlen_zero(tmp)) 03428 tmp[strlen(tmp) - 1] = '\0'; 03429 else 03430 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03431 y=0; 03432 pc = strchr(dp->peercontext, '@'); 03433 if (!pc) 03434 pc = dp->peercontext; 03435 else 03436 pc++; 03437 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 03438 if (dp->waiters[x] > -1) 03439 y++; 03440 if (s > 0) 03441 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03442 else 03443 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03444 dp = dp->next; 03445 } 03446 ast_mutex_unlock(&dpcache_lock); 03447 return RESULT_SUCCESS; 03448 }
static int iax2_show_callnumber_usage | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2215 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.
02216 { 02217 struct ao2_iterator i; 02218 struct peercnt *peercnt; 02219 struct sockaddr_in sin; 02220 int found = 0; 02221 02222 if (argc < 4 || argc > 5) 02223 return RESULT_SHOWUSAGE; 02224 02225 ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02226 i = ao2_iterator_init(peercnts, 0); 02227 while ((peercnt = ao2_iterator_next(&i))) { 02228 sin.sin_addr.s_addr = peercnt->addr; 02229 if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02230 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02231 found = 1; 02232 break; 02233 } else { 02234 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02235 } 02236 ao2_ref(peercnt, -1); 02237 } 02238 ao2_iterator_destroy(&i); 02239 if (argc == 4) { 02240 ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02241 } else if (argc == 5 && !found) { 02242 ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] ); 02243 } 02244 return RESULT_SUCCESS; 02245 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6106 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.
06107 { 06108 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 06109 #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" 06110 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 06111 int x; 06112 int numchans = 0; 06113 int usedchans = 0; 06114 char first_message[10] = { 0, }; 06115 char last_message[10] = { 0, }; 06116 06117 if (argc != 3) 06118 return RESULT_SHOWUSAGE; 06119 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06120 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06121 ast_mutex_lock(&iaxsl[x]); 06122 if (iaxs[x]) { 06123 int lag, jitter, localdelay; 06124 jb_info jbinfo; 06125 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06126 jb_getinfo(iaxs[x]->jb, &jbinfo); 06127 jitter = jbinfo.jitter; 06128 localdelay = jbinfo.current - jbinfo.min; 06129 } else { 06130 jitter = -1; 06131 localdelay = 0; 06132 } 06133 06134 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06135 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06136 lag = iaxs[x]->remote_rr.delay; 06137 ast_cli(fd, FORMAT, 06138 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06139 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06140 S_OR(iaxs[x]->username, "(None)"), 06141 iaxs[x]->callno, iaxs[x]->peercallno, 06142 iaxs[x]->oseqno, iaxs[x]->iseqno, 06143 lag, 06144 jitter, 06145 localdelay, 06146 ast_getformatname(iaxs[x]->voiceformat), 06147 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06148 first_message, 06149 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06150 last_message); 06151 numchans++; 06152 if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */ 06153 usedchans++; 06154 } 06155 } 06156 ast_mutex_unlock(&iaxsl[x]); 06157 } 06158 ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 06159 ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 06160 return RESULT_SUCCESS; 06161 #undef FORMAT 06162 #undef FORMAT2 06163 #undef FORMATB 06164 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6017 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.
06018 { 06019 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 06020 #if !defined(__FreeBSD__) 06021 #define FORMAT "%-15.15s %-15d %-15d\n" 06022 #else /* __FreeBSD__ */ 06023 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 06024 #endif /* __FreeBSD__ */ 06025 struct iax_firmware *cur; 06026 if ((argc != 3) && (argc != 4)) 06027 return RESULT_SHOWUSAGE; 06028 ast_mutex_lock(&waresl.lock); 06029 06030 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 06031 for (cur = waresl.wares;cur;cur = cur->next) { 06032 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 06033 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 06034 (int)ntohl(cur->fwh->datalen)); 06035 } 06036 ast_mutex_unlock(&waresl.lock); 06037 return RESULT_SUCCESS; 06038 #undef FORMAT 06039 #undef FORMAT2 06040 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6253 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06254 { 06255 int numchans = 0; 06256 if (argc != 3) 06257 return RESULT_SHOWUSAGE; 06258 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06259 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06260 numchans = ast_cli_netstats(NULL, fd, 1); 06261 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06262 return RESULT_SUCCESS; 06263 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 3280 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.
03281 { 03282 char status[30]; 03283 char cbuf[256]; 03284 struct iax2_peer *peer; 03285 char codec_buf[512]; 03286 int x = 0, codec = 0, load_realtime = 0; 03287 03288 if (argc < 4) 03289 return RESULT_SHOWUSAGE; 03290 03291 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 03292 03293 peer = find_peer(argv[3], load_realtime); 03294 if (peer) { 03295 ast_cli(fd,"\n\n"); 03296 ast_cli(fd, " * Name : %s\n", peer->name); 03297 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 03298 ast_cli(fd, " Context : %s\n", peer->context); 03299 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 03300 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 03301 ast_cli(fd, " Callnum limit: %d\n", peer->maxcallno); 03302 ast_cli(fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03303 03304 03305 ast_cli(fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03306 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03307 ast_cli(fd, " Expire : %d\n", peer->expire); 03308 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 03309 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)); 03310 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03311 ast_cli(fd, " Username : %s\n", peer->username); 03312 ast_cli(fd, " Codecs : "); 03313 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03314 ast_cli(fd, "%s\n", codec_buf); 03315 03316 ast_cli(fd, " Codec Order : ("); 03317 for(x = 0; x < 32 ; x++) { 03318 codec = ast_codec_pref_index(&peer->prefs,x); 03319 if(!codec) 03320 break; 03321 ast_cli(fd, "%s", ast_getformatname(codec)); 03322 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03323 ast_cli(fd, "|"); 03324 } 03325 03326 if (!x) 03327 ast_cli(fd, "none"); 03328 ast_cli(fd, ")\n"); 03329 03330 ast_cli(fd, " Status : "); 03331 peer_status(peer, status, sizeof(status)); 03332 ast_cli(fd, "%s\n",status); 03333 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03334 ast_cli(fd,"\n"); 03335 peer_unref(peer); 03336 } else { 03337 ast_cli(fd,"Peer %s not found.\n", argv[3]); 03338 ast_cli(fd,"\n"); 03339 } 03340 03341 return RESULT_SUCCESS; 03342 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6006 of file chan_iax2.c.
References __iax2_show_peers().
06007 { 06008 return __iax2_show_peers(0, fd, NULL, argc, argv); 06009 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6078 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.
06079 { 06080 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 06081 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 06082 struct iax2_registry *reg = NULL; 06083 06084 char host[80]; 06085 char perceived[80]; 06086 if (argc != 3) 06087 return RESULT_SHOWUSAGE; 06088 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 06089 AST_LIST_LOCK(®istrations); 06090 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06091 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06092 if (reg->us.sin_addr.s_addr) 06093 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06094 else 06095 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06096 ast_cli(fd, FORMAT, host, 06097 (reg->dnsmgr) ? "Y" : "N", 06098 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 06099 } 06100 AST_LIST_UNLOCK(®istrations); 06101 return RESULT_SUCCESS; 06102 #undef FORMAT 06103 #undef FORMAT2 06104 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3370 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.
03371 { 03372 struct iax_frame *cur; 03373 int cnt = 0, dead=0, final=0; 03374 03375 if (argc != 3) 03376 return RESULT_SHOWUSAGE; 03377 03378 AST_LIST_LOCK(&iaxq.queue); 03379 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 03380 if (cur->retries < 0) 03381 dead++; 03382 if (cur->final) 03383 final++; 03384 cnt++; 03385 } 03386 AST_LIST_UNLOCK(&iaxq.queue); 03387 03388 ast_cli(fd, " IAX Statistics\n"); 03389 ast_cli(fd, "---------------------\n"); 03390 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03391 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03392 03393 return RESULT_SUCCESS; 03394 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5947 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.
05948 { 05949 struct iax2_thread *thread = NULL; 05950 time_t t; 05951 int threadcount = 0, dynamiccount = 0; 05952 char type; 05953 05954 if (argc != 3) 05955 return RESULT_SHOWUSAGE; 05956 05957 ast_cli(fd, "IAX2 Thread Information\n"); 05958 time(&t); 05959 ast_cli(fd, "Idle Threads:\n"); 05960 AST_LIST_LOCK(&idle_list); 05961 AST_LIST_TRAVERSE(&idle_list, thread, list) { 05962 #ifdef DEBUG_SCHED_MULTITHREAD 05963 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05964 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05965 #else 05966 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05967 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05968 #endif 05969 threadcount++; 05970 } 05971 AST_LIST_UNLOCK(&idle_list); 05972 ast_cli(fd, "Active Threads:\n"); 05973 AST_LIST_LOCK(&active_list); 05974 AST_LIST_TRAVERSE(&active_list, thread, list) { 05975 if (thread->type == IAX_TYPE_DYNAMIC) 05976 type = 'D'; 05977 else 05978 type = 'P'; 05979 #ifdef DEBUG_SCHED_MULTITHREAD 05980 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 05981 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05982 #else 05983 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 05984 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05985 #endif 05986 threadcount++; 05987 } 05988 AST_LIST_UNLOCK(&active_list); 05989 ast_cli(fd, "Dynamic Threads:\n"); 05990 AST_LIST_LOCK(&dynamic_list); 05991 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 05992 #ifdef DEBUG_SCHED_MULTITHREAD 05993 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05994 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05995 #else 05996 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05997 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05998 #endif 05999 dynamiccount++; 06000 } 06001 AST_LIST_UNLOCK(&dynamic_list); 06002 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06003 return RESULT_SUCCESS; 06004 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5762 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.
05763 { 05764 regex_t regexbuf; 05765 int havepattern = 0; 05766 05767 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 05768 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 05769 05770 struct iax2_user *user = NULL; 05771 char auth[90]; 05772 char *pstr = ""; 05773 struct ao2_iterator i; 05774 05775 switch (argc) { 05776 case 5: 05777 if (!strcasecmp(argv[3], "like")) { 05778 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05779 return RESULT_SHOWUSAGE; 05780 havepattern = 1; 05781 } else 05782 return RESULT_SHOWUSAGE; 05783 case 3: 05784 break; 05785 default: 05786 return RESULT_SHOWUSAGE; 05787 } 05788 05789 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 05790 i = ao2_iterator_init(users, 0); 05791 for (user = ao2_iterator_next(&i); user; 05792 user_unref(user), user = ao2_iterator_next(&i)) { 05793 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 05794 continue; 05795 05796 if (!ast_strlen_zero(user->secret)) { 05797 ast_copy_string(auth,user->secret,sizeof(auth)); 05798 } else if (!ast_strlen_zero(user->inkeys)) { 05799 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 05800 } else 05801 ast_copy_string(auth, "-no secret-", sizeof(auth)); 05802 05803 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 05804 pstr = "REQ Only"; 05805 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 05806 pstr = "Disabled"; 05807 else 05808 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 05809 05810 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 05811 user->contexts ? user->contexts->context : context, 05812 user->ha ? "Yes" : "No", pstr); 05813 } 05814 ao2_iterator_destroy(&i); 05815 05816 if (havepattern) 05817 regfree(®exbuf); 05818 05819 return RESULT_SUCCESS; 05820 #undef FORMAT 05821 #undef FORMAT2 05822 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 4704 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.
04705 { 04706 int res; 04707 struct iax_ie_data ied0; 04708 struct iax_ie_data ied1; 04709 unsigned int transferid = (unsigned int)ast_random(); 04710 memset(&ied0, 0, sizeof(ied0)); 04711 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 04712 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 04713 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 04714 04715 memset(&ied1, 0, sizeof(ied1)); 04716 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 04717 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 04718 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 04719 04720 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 04721 if (res) 04722 return -1; 04723 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 04724 if (res) 04725 return -1; 04726 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04727 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04728 return 0; 04729 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3211 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03212 { 03213 if (argc != 4) 03214 return RESULT_SHOWUSAGE; 03215 03216 test_losspct = atoi(argv[3]); 03217 03218 return RESULT_SUCCESS; 03219 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 4947 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.
04948 { 04949 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04950 struct iax_ie_data ied; 04951 char tmp[256], *context; 04952 ast_copy_string(tmp, dest, sizeof(tmp)); 04953 context = strchr(tmp, '@'); 04954 if (context) { 04955 *context = '\0'; 04956 context++; 04957 } 04958 memset(&ied, 0, sizeof(ied)); 04959 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 04960 if (context) 04961 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 04962 if (option_debug) 04963 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 04964 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 04965 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3693 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, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
03694 { 03695 /* Lock the queue and place this packet at the end */ 03696 /* By setting this to 0, the network thread will send it for us, and 03697 queue retransmission if necessary */ 03698 fr->sentyet = 0; 03699 AST_LIST_LOCK(&iaxq.queue); 03700 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 03701 iaxq.count++; 03702 AST_LIST_UNLOCK(&iaxq.queue); 03703 /* Wake up the network and scheduler thread */ 03704 if (netthreadid != AST_PTHREADT_NULL) 03705 pthread_kill(netthreadid, SIGURG); 03706 signal_condition(&sched_lock, &sched_cond); 03707 return 0; 03708 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 7934 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
07935 { 07936 /* Drop when trunk is about 5 seconds idle */ 07937 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 07938 return 1; 07939 return 0; 07940 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 5317 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().
05318 { 05319 struct ast_frame *f; 05320 struct iax2_trunk_peer *tpeer; 05321 void *tmp, *ptr; 05322 struct ast_iax2_meta_trunk_entry *met; 05323 struct ast_iax2_meta_trunk_mini *mtm; 05324 05325 f = &fr->af; 05326 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05327 if (tpeer) { 05328 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05329 /* Need to reallocate space */ 05330 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 05331 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05332 ast_mutex_unlock(&tpeer->lock); 05333 return -1; 05334 } 05335 05336 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05337 tpeer->trunkdata = tmp; 05338 if (option_debug) 05339 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); 05340 } else { 05341 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)); 05342 ast_mutex_unlock(&tpeer->lock); 05343 return -1; 05344 } 05345 } 05346 05347 /* Append to meta frame */ 05348 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05349 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05350 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05351 mtm->len = htons(f->datalen); 05352 mtm->mini.callno = htons(pvt->callno); 05353 mtm->mini.ts = htons(0xffff & fr->ts); 05354 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05355 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05356 } else { 05357 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05358 /* Store call number and length in meta header */ 05359 met->callno = htons(pvt->callno); 05360 met->len = htons(f->datalen); 05361 /* Advance pointers/decrease length past trunk entry header */ 05362 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05363 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05364 } 05365 /* Copy actual trunk data */ 05366 memcpy(ptr, f->data, f->datalen); 05367 tpeer->trunkdatalen += f->datalen; 05368 05369 tpeer->calls++; 05370 ast_mutex_unlock(&tpeer->lock); 05371 } 05372 return 0; 05373 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 7851 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
07852 { 07853 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 07854 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 6320 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.
06321 { 06322 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 06323 int res = -1; 06324 ast_mutex_lock(&iaxsl[callno]); 06325 if (iaxs[callno]) { 06326 /* If there's an outstanding error, return failure now */ 06327 if (!iaxs[callno]->error) { 06328 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 06329 res = 0; 06330 /* Don't waste bandwidth sending null frames */ 06331 else if (f->frametype == AST_FRAME_NULL) 06332 res = 0; 06333 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 06334 res = 0; 06335 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 06336 res = 0; 06337 else 06338 /* Simple, just queue for transmission */ 06339 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 06340 } else { 06341 if (option_debug) 06342 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 06343 } 06344 } 06345 /* If it's already gone, just return */ 06346 ast_mutex_unlock(&iaxsl[callno]); 06347 return res; 06348 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2813 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().
02814 { 02815 int res = 0; 02816 struct iax_firmware *cur; 02817 if (!ast_strlen_zero(dev)) { 02818 ast_mutex_lock(&waresl.lock); 02819 cur = waresl.wares; 02820 while(cur) { 02821 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02822 res = ntohs(cur->fwh->version); 02823 break; 02824 } 02825 cur = cur->next; 02826 } 02827 ast_mutex_unlock(&waresl.lock); 02828 } 02829 return res; 02830 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 874 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00875 { 00876 if (iaxdebug) 00877 ast_verbose("%s", data); 00878 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 880 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00881 { 00882 ast_log(LOG_WARNING, "%s", data); 00883 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 2832 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().
02833 { 02834 int res = -1; 02835 unsigned int bs = desc & 0xff; 02836 unsigned int start = (desc >> 8) & 0xffffff; 02837 unsigned int bytes; 02838 struct iax_firmware *cur; 02839 if (!ast_strlen_zero((char *)dev) && bs) { 02840 start *= bs; 02841 ast_mutex_lock(&waresl.lock); 02842 cur = waresl.wares; 02843 while(cur) { 02844 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 02845 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02846 if (start < ntohl(cur->fwh->datalen)) { 02847 bytes = ntohl(cur->fwh->datalen) - start; 02848 if (bytes > bs) 02849 bytes = bs; 02850 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02851 } else { 02852 bytes = 0; 02853 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02854 } 02855 if (bytes == bs) 02856 res = 0; 02857 else 02858 res = 1; 02859 break; 02860 } 02861 cur = cur->next; 02862 } 02863 ast_mutex_unlock(&waresl.lock); 02864 } 02865 return res; 02866 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 8122 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().
08123 { 08124 struct iax_dual *d; 08125 struct ast_channel *chan1m, *chan2m; 08126 pthread_t th; 08127 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 08128 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 08129 if (chan2m && chan1m) { 08130 /* Make formats okay */ 08131 chan1m->readformat = chan1->readformat; 08132 chan1m->writeformat = chan1->writeformat; 08133 ast_channel_masquerade(chan1m, chan1); 08134 /* Setup the extensions and such */ 08135 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08136 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08137 chan1m->priority = chan1->priority; 08138 08139 /* We make a clone of the peer channel too, so we can play 08140 back the announcement */ 08141 /* Make formats okay */ 08142 chan2m->readformat = chan2->readformat; 08143 chan2m->writeformat = chan2->writeformat; 08144 ast_channel_masquerade(chan2m, chan2); 08145 /* Setup the extensions and such */ 08146 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08147 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08148 chan2m->priority = chan2->priority; 08149 if (ast_do_masquerade(chan2m)) { 08150 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08151 ast_hangup(chan2m); 08152 return -1; 08153 } 08154 } else { 08155 if (chan1m) 08156 ast_hangup(chan1m); 08157 if (chan2m) 08158 ast_hangup(chan2m); 08159 return -1; 08160 } 08161 if ((d = ast_calloc(1, sizeof(*d)))) { 08162 pthread_attr_t attr; 08163 08164 pthread_attr_init(&attr); 08165 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08166 08167 d->chan1 = chan1m; 08168 d->chan2 = chan2m; 08169 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 08170 pthread_attr_destroy(&attr); 08171 return 0; 08172 } 08173 pthread_attr_destroy(&attr); 08174 free(d); 08175 } 08176 return -1; 08177 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 8102 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().
08103 { 08104 struct ast_channel *chan1, *chan2; 08105 struct iax_dual *d; 08106 struct ast_frame *f; 08107 int ext; 08108 int res; 08109 d = stuff; 08110 chan1 = d->chan1; 08111 chan2 = d->chan2; 08112 free(d); 08113 f = ast_read(chan1); 08114 if (f) 08115 ast_frfree(f); 08116 res = ast_park_call(chan1, chan2, 0, &ext); 08117 ast_hangup(chan2); 08118 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 08119 return NULL; 08120 }
Definition at line 1694 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().
01695 { 01696 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01697 if (new) { 01698 size_t afdatalen = new->afdatalen; 01699 memcpy(new, fr, sizeof(*new)); 01700 iax_frame_wrap(new, &fr->af); 01701 new->afdatalen = afdatalen; 01702 new->data = NULL; 01703 new->datalen = 0; 01704 new->direction = DIRECTION_INGRESS; 01705 new->retrans = -1; 01706 } 01707 return new; 01708 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1051 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().
01052 { 01053 if (thread->type == IAX_TYPE_DYNAMIC) { 01054 AST_LIST_LOCK(&dynamic_list); 01055 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01056 AST_LIST_UNLOCK(&dynamic_list); 01057 } else { 01058 AST_LIST_LOCK(&idle_list); 01059 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01060 AST_LIST_UNLOCK(&idle_list); 01061 } 01062 01063 return; 01064 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 909 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00910 { 00911 va_list args; 00912 char buf[1024]; 00913 00914 va_start(args, fmt); 00915 vsnprintf(buf, 1024, fmt, args); 00916 va_end(args); 00917 00918 ast_verbose("%s", buf); 00919 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 885 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00886 { 00887 va_list args; 00888 char buf[1024]; 00889 00890 va_start(args, fmt); 00891 vsnprintf(buf, 1024, fmt, args); 00892 va_end(args); 00893 00894 ast_log(LOG_ERROR, "%s", buf); 00895 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 897 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00898 { 00899 va_list args; 00900 char buf[1024]; 00901 00902 va_start(args, fmt); 00903 vsnprintf(buf, 1024, fmt, args); 00904 va_end(args); 00905 00906 ast_log(LOG_WARNING, "%s", buf); 00907 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 12771 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.
12772 { 12773 static const char config[] = "iax.conf"; 12774 int res = 0; 12775 int x; 12776 struct iax2_registry *reg = NULL; 12777 12778 if (load_objects()) { 12779 return AST_MODULE_LOAD_FAILURE; 12780 } 12781 12782 #ifdef HAVE_DAHDI 12783 #ifdef DAHDI_TIMERACK 12784 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 12785 if (timingfd < 0) 12786 #endif 12787 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 12788 if (timingfd < 0) 12789 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 12790 #endif 12791 12792 memset(iaxs, 0, sizeof(iaxs)); 12793 12794 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12795 ast_mutex_init(&iaxsl[x]); 12796 } 12797 12798 ast_cond_init(&sched_cond, NULL); 12799 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS 12800 ast_mutex_init(&sched_lock); 12801 #endif 12802 12803 io = io_context_create(); 12804 sched = sched_context_create(); 12805 12806 if (!io || !sched) { 12807 ast_log(LOG_ERROR, "Out of memory\n"); 12808 return -1; 12809 } 12810 12811 netsock = ast_netsock_list_alloc(); 12812 if (!netsock) { 12813 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 12814 return -1; 12815 } 12816 ast_netsock_init(netsock); 12817 12818 outsock = ast_netsock_list_alloc(); 12819 if (!outsock) { 12820 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12821 return -1; 12822 } 12823 ast_netsock_init(outsock); 12824 12825 randomcalltokendata = ast_random(); 12826 12827 iax_set_output(iax_debug_output); 12828 iax_set_error(iax_error_output); 12829 jb_setoutput(jb_error_output, jb_warning_output, NULL); 12830 12831 ast_mutex_init(&waresl.lock); 12832 12833 AST_LIST_HEAD_INIT(&iaxq.queue); 12834 12835 if (set_config(config, 0) == -1) { 12836 return AST_MODULE_LOAD_DECLINE; 12837 } 12838 12839 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12840 12841 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 12842 12843 ast_custom_function_register(&iaxpeer_function); 12844 12845 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 12846 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 12847 12848 if (ast_channel_register(&iax2_tech)) { 12849 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 12850 __unload_module(); 12851 return -1; 12852 } 12853 12854 if (ast_register_switch(&iax2_switch)) { 12855 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 12856 } 12857 12858 res = start_network_thread(); 12859 if (!res) { 12860 if (option_verbose > 1) { 12861 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 12862 } 12863 } else { 12864 ast_log(LOG_ERROR, "Unable to start network thread\n"); 12865 ast_netsock_release(netsock); 12866 ast_netsock_release(outsock); 12867 } 12868 12869 AST_LIST_LOCK(®istrations); 12870 AST_LIST_TRAVERSE(®istrations, reg, entry) 12871 iax2_do_register(reg); 12872 AST_LIST_UNLOCK(®istrations); 12873 12874 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 12875 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 12876 12877 reload_firmware(0); 12878 iax_provision_reload(); 12879 return res; 12880 }
static int load_objects | ( | void | ) | [static] |
Definition at line 12714 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().
12715 { 12716 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 12717 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 12718 12719 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 12720 goto container_fail; 12721 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 12722 goto container_fail; 12723 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 12724 goto container_fail; 12725 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 12726 goto container_fail; 12727 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 12728 goto container_fail; 12729 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12730 goto container_fail; 12731 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12732 goto container_fail; 12733 } else if (create_callno_pools()) { 12734 goto container_fail; 12735 } 12736 12737 return 0; 12738 12739 container_fail: 12740 if (peers) { 12741 ao2_ref(peers, -1); 12742 } 12743 if (users) { 12744 ao2_ref(users, -1); 12745 } 12746 if (iax_peercallno_pvts) { 12747 ao2_ref(iax_peercallno_pvts, -1); 12748 } 12749 if (iax_transfercallno_pvts) { 12750 ao2_ref(iax_transfercallno_pvts, -1); 12751 } 12752 if (peercnts) { 12753 ao2_ref(peercnts, -1); 12754 } 12755 if (callno_limits) { 12756 ao2_ref(callno_limits, -1); 12757 } 12758 if (calltoken_ignores) { 12759 ao2_ref(calltoken_ignores, -1); 12760 } 12761 if (callno_pool) { 12762 ao2_ref(callno_pool, -1); 12763 } 12764 if (callno_pool_trunk) { 12765 ao2_ref(callno_pool_trunk, -1); 12766 } 12767 return AST_MODULE_LOAD_FAILURE; 12768 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4731 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
04732 { 04733 ast_mutex_lock(&iaxsl[callno0]); 04734 while (ast_mutex_trylock(&iaxsl[callno1])) { 04735 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 04736 } 04737 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1758 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().
01759 { 01760 int x; 01761 int res= 0; 01762 struct callno_entry *callno_entry; 01763 if (iaxs[callno]->oseqno) { 01764 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01765 return -1; 01766 } 01767 if (callno & TRUNK_CALL_START) { 01768 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01769 return -1; 01770 } 01771 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01772 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01773 return -1; 01774 } 01775 01776 x = callno_entry->callno; 01777 ast_mutex_lock(&iaxsl[x]); 01778 01779 /*! 01780 * \note We delete these before switching the slot, because if 01781 * they fire in the meantime, they will generate a warning. 01782 */ 01783 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01784 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01785 iaxs[x] = iaxs[callno]; 01786 iaxs[x]->callno = x; 01787 01788 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01789 * before assigning the new one */ 01790 if (iaxs[x]->callno_entry) { 01791 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01792 } 01793 iaxs[x]->callno_entry = callno_entry; 01794 01795 iaxs[callno] = NULL; 01796 /* Update the two timers that should have been started */ 01797 iaxs[x]->pingid = iax2_sched_add(sched, 01798 ping_time * 1000, send_ping, (void *)(long)x); 01799 iaxs[x]->lagid = iax2_sched_add(sched, 01800 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01801 01802 if (locked) 01803 ast_mutex_unlock(&iaxsl[callno]); 01804 res = x; 01805 if (!locked) 01806 ast_mutex_unlock(&iaxsl[x]); 01807 01808 if (option_debug) 01809 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01810 /* We move this call from a non-trunked to a trunked call */ 01811 update_max_trunk(); 01812 update_max_nontrunk(); 01813 return res; 01814 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6010 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
06011 { 06012 ast_cli_netstats(s, -1, 0); 06013 astman_append(s, "\r\n"); 06014 return RESULT_SUCCESS; 06015 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6043 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
06044 { 06045 char *a[] = { "iax2", "show", "users" }; 06046 int ret; 06047 const char *id = astman_get_header(m,"ActionID"); 06048 06049 if (!ast_strlen_zero(id)) 06050 astman_append(s, "ActionID: %s\r\n",id); 06051 ret = __iax2_show_peers(1, -1, s, 3, a ); 06052 astman_append(s, "\r\n\r\n" ); 06053 return ret; 06054 } /* /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 1724 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().
01725 { 01726 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01727 (cur->addr.sin_port == sin->sin_port)) { 01728 /* This is the main host */ 01729 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01730 (check_dcallno ? dcallno == cur->callno : 1) ) { 01731 /* That's us. Be sure we keep track of the peer call number */ 01732 return 1; 01733 } 01734 } 01735 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01736 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01737 /* We're transferring */ 01738 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01739 return 1; 01740 } 01741 return 0; 01742 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5403 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05404 { 05405 #if 0 05406 /* Debug with "fake encryption" */ 05407 int x; 05408 if (len % 16) 05409 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05410 for (x=0;x<len;x++) 05411 dst[x] = src[x] ^ 0xff; 05412 #else 05413 unsigned char lastblock[16] = { 0 }; 05414 int x; 05415 while(len > 0) { 05416 aes_decrypt(src, dst, dcx); 05417 for (x=0;x<16;x++) 05418 dst[x] ^= lastblock[x]; 05419 memcpy(lastblock, src, sizeof(lastblock)); 05420 dst += 16; 05421 src += 16; 05422 len -= 16; 05423 } 05424 #endif 05425 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 5427 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05428 { 05429 #if 0 05430 /* Debug with "fake encryption" */ 05431 int x; 05432 if (len % 16) 05433 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05434 for (x=0;x<len;x++) 05435 dst[x] = src[x] ^ 0xff; 05436 #else 05437 unsigned char curblock[16] = { 0 }; 05438 int x; 05439 while(len > 0) { 05440 for (x=0;x<16;x++) 05441 curblock[x] ^= src[x]; 05442 aes_encrypt(curblock, dst, ecx); 05443 memcpy(curblock, dst, sizeof(curblock)); 05444 dst += 16; 05445 src += 16; 05446 len -= 16; 05447 } 05448 #endif 05449 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 6660 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
06661 { 06662 /* Select exactly one common encryption if there are any */ 06663 p->encmethods &= enc; 06664 if (p->encmethods) { 06665 if (p->encmethods & IAX_ENCRYPT_AES128) 06666 p->encmethods = IAX_ENCRYPT_AES128; 06667 else 06668 p->encmethods = 0; 06669 } 06670 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 10573 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().
10574 { 10575 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 10576 from the network, and queue them for delivery to the channels */ 10577 int res, count, wakeup; 10578 struct iax_frame *f; 10579 10580 if (timingfd > -1) 10581 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 10582 10583 for(;;) { 10584 pthread_testcancel(); 10585 10586 /* Go through the queue, sending messages which have not yet been 10587 sent, and scheduling retransmissions if appropriate */ 10588 AST_LIST_LOCK(&iaxq.queue); 10589 count = 0; 10590 wakeup = -1; 10591 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 10592 if (f->sentyet) 10593 continue; 10594 10595 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 10596 if (ast_mutex_trylock(&iaxsl[f->callno])) { 10597 wakeup = 1; 10598 continue; 10599 } 10600 10601 f->sentyet++; 10602 10603 if (iaxs[f->callno]) { 10604 send_packet(f); 10605 count++; 10606 } 10607 10608 ast_mutex_unlock(&iaxsl[f->callno]); 10609 10610 if (f->retries < 0) { 10611 /* This is not supposed to be retransmitted */ 10612 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 10613 iaxq.count--; 10614 /* Free the iax frame */ 10615 iax_frame_free(f); 10616 } else { 10617 /* We need reliable delivery. Schedule a retransmission */ 10618 f->retries++; 10619 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 10620 } 10621 } 10622 AST_LIST_TRAVERSE_SAFE_END 10623 AST_LIST_UNLOCK(&iaxq.queue); 10624 10625 pthread_testcancel(); 10626 10627 if (option_debug && count >= 20) 10628 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 10629 10630 /* Now do the IO, and run scheduled tasks */ 10631 res = ast_io_wait(io, wakeup); 10632 if (res >= 0) { 10633 if (option_debug && res >= 20) 10634 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 10635 } 10636 } 10637 return NULL; 10638 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1652 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().
01653 { 01654 struct chan_iax2_pvt *tmp; 01655 jb_conf jbconf; 01656 01657 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01658 return NULL; 01659 } 01660 01661 if (ast_string_field_init(tmp, 32)) { 01662 ao2_ref(tmp, -1); 01663 tmp = NULL; 01664 return NULL; 01665 } 01666 01667 tmp->prefs = prefs; 01668 tmp->callno = 0; 01669 tmp->peercallno = 0; 01670 tmp->transfercallno = 0; 01671 tmp->bridgecallno = 0; 01672 tmp->pingid = -1; 01673 tmp->lagid = -1; 01674 tmp->autoid = -1; 01675 tmp->authid = -1; 01676 tmp->initid = -1; 01677 01678 ast_string_field_set(tmp,exten, "s"); 01679 ast_string_field_set(tmp,host, host); 01680 01681 tmp->jb = jb_new(); 01682 tmp->jbid = -1; 01683 jbconf.max_jitterbuf = maxjitterbuffer; 01684 jbconf.resync_threshold = resyncthreshold; 01685 jbconf.max_contig_interp = maxjitterinterps; 01686 jb_setconf(tmp->jb,&jbconf); 01687 01688 tmp->hold_signaling = 1; 01689 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01690 01691 return tmp; 01692 }
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 4389 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().
04390 { 04391 if (ast_strlen_zero(data)) 04392 return; 04393 04394 pds->peer = strsep(&data, "/"); 04395 pds->exten = strsep(&data, "/"); 04396 pds->options = data; 04397 04398 if (pds->exten) { 04399 data = pds->exten; 04400 pds->exten = strsep(&data, "@"); 04401 pds->context = data; 04402 } 04403 04404 if (strchr(pds->peer, '@')) { 04405 data = pds->peer; 04406 pds->username = strsep(&data, "@"); 04407 pds->peer = data; 04408 } 04409 04410 if (pds->username) { 04411 data = pds->username; 04412 pds->username = strsep(&data, ":"); 04413 pds->password = data; 04414 } 04415 04416 data = pds->peer; 04417 pds->peer = strsep(&data, ":"); 04418 pds->port = data; 04419 04420 /* check for a key name wrapped in [] in the secret position, if found, 04421 move it to the key field instead 04422 */ 04423 if (pds->password && (pds->password[0] == '[')) { 04424 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04425 pds->password = NULL; 04426 } 04427 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1280 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_objects().
01281 { 01282 struct iax2_peer *peer = obj, *peer2 = arg; 01283 01284 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01285 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11300 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11301 { 11302 struct iax2_peer *peer = obj; 11303 11304 ast_set_flag(peer, IAX_DELME); 11305 11306 return 0; 11307 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 10796 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().
10797 { 10798 struct iax2_peer *peer = obj; 10799 int callno = peer->callno; 10800 10801 ast_free_ha(peer->ha); 10802 10803 if (callno > 0) { 10804 ast_mutex_lock(&iaxsl[callno]); 10805 iax2_destroy(callno); 10806 ast_mutex_unlock(&iaxsl[callno]); 10807 } 10808 10809 register_peer_exten(peer, 0); 10810 10811 if (peer->dnsmgr) 10812 ast_dnsmgr_release(peer->dnsmgr); 10813 10814 ast_string_field_free_memory(peer); 10815 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1270 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_objects().
01271 { 01272 const struct iax2_peer *peer = obj; 01273 01274 return ast_str_hash(peer->name); 01275 }
Definition at line 1327 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().
01328 { 01329 ao2_ref(peer, +1); 01330 return peer; 01331 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12667 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
12668 { 12669 struct iax2_peer *peer = obj; 12670 12671 if (peer->sockfd < 0) 12672 peer->sockfd = defaultsockfd; 12673 12674 return 0; 12675 }
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 10723 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().
10724 { 10725 struct sockaddr_in sin; 10726 int nonlocal = 1; 10727 int port = IAX_DEFAULT_PORTNO; 10728 int sockfd = defaultsockfd; 10729 char *tmp; 10730 char *addr; 10731 char *portstr; 10732 10733 if (!(tmp = ast_strdupa(srcaddr))) 10734 return -1; 10735 10736 addr = strsep(&tmp, ":"); 10737 portstr = tmp; 10738 10739 if (portstr) { 10740 port = atoi(portstr); 10741 if (port < 1) 10742 port = IAX_DEFAULT_PORTNO; 10743 } 10744 10745 if (!ast_get_ip(&sin, addr)) { 10746 struct ast_netsock *sock; 10747 int res; 10748 10749 sin.sin_port = 0; 10750 sin.sin_family = AF_INET; 10751 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 10752 if (res == 0) { 10753 /* ip address valid. */ 10754 sin.sin_port = htons(port); 10755 if (!(sock = ast_netsock_find(netsock, &sin))) 10756 sock = ast_netsock_find(outsock, &sin); 10757 if (sock) { 10758 sockfd = ast_netsock_sockfd(sock); 10759 nonlocal = 0; 10760 } else { 10761 unsigned int orig_saddr = sin.sin_addr.s_addr; 10762 /* INADDR_ANY matches anyway! */ 10763 sin.sin_addr.s_addr = INADDR_ANY; 10764 if (ast_netsock_find(netsock, &sin)) { 10765 sin.sin_addr.s_addr = orig_saddr; 10766 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 10767 if (sock) { 10768 sockfd = ast_netsock_sockfd(sock); 10769 ast_netsock_unref(sock); 10770 nonlocal = 0; 10771 } else { 10772 nonlocal = 2; 10773 } 10774 } 10775 } 10776 } 10777 } 10778 10779 peer->sockfd = sockfd; 10780 10781 if (nonlocal == 1) { 10782 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 10783 srcaddr, peer->name); 10784 return -1; 10785 } else if (nonlocal == 2) { 10786 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 10787 srcaddr, peer->name); 10788 return -1; 10789 } else { 10790 if (option_debug) 10791 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 10792 return 0; 10793 } 10794 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3257 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().
03258 { 03259 int res = 0; 03260 if (peer->maxms) { 03261 if (peer->lastms < 0) { 03262 ast_copy_string(status, "UNREACHABLE", statuslen); 03263 } else if (peer->lastms > peer->maxms) { 03264 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03265 res = 1; 03266 } else if (peer->lastms) { 03267 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03268 res = 1; 03269 } else { 03270 ast_copy_string(status, "UNKNOWN", statuslen); 03271 } 03272 } else { 03273 ast_copy_string(status, "Unmonitored", statuslen); 03274 res = -1; 03275 } 03276 return res; 03277 }
Definition at line 1333 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().
01334 { 01335 ao2_ref(peer, -1); 01336 return NULL; 01337 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2009 of file chan_iax2.c.
References peercnt::addr, ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_inet_ntoa(), ast_log(), LOG_DEBUG, LOG_ERROR, option_debug, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02010 { 02011 struct peercnt *peercnt; 02012 unsigned long addr = sin->sin_addr.s_addr; 02013 int res = 0; 02014 struct peercnt tmp = { 02015 .addr = addr, 02016 }; 02017 02018 /* Reasoning for peercnts container lock: Two identical ip addresses 02019 * could be added by different threads at the "same time". Without the container 02020 * lock, both threads could alloc space for the same object and attempt 02021 * to link to table. With the lock, one would create the object and link 02022 * to table while the other would find the already created peercnt object 02023 * rather than creating a new one. */ 02024 ao2_lock(peercnts); 02025 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02026 ao2_lock(peercnt); 02027 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02028 ao2_lock(peercnt); 02029 /* create and set defaults */ 02030 peercnt->addr = addr; 02031 set_peercnt_limit(peercnt); 02032 /* guarantees it does not go away after unlocking table 02033 * ao2_find automatically adds this */ 02034 ao2_link(peercnts, peercnt); 02035 } else { 02036 ao2_unlock(peercnts); 02037 return -1; 02038 } 02039 02040 /* check to see if the address has hit its callno limit. If not increment cur. */ 02041 if (peercnt->limit > peercnt->cur) { 02042 peercnt->cur++; 02043 if (option_debug) { 02044 ast_log(LOG_DEBUG, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02045 } 02046 } else { /* max num call numbers for this peer has been reached! */ 02047 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02048 res = -1; 02049 } 02050 02051 /* clean up locks and ref count */ 02052 ao2_unlock(peercnt); 02053 ao2_unlock(peercnts); 02054 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02055 02056 return res; 02057 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1843 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
01844 { 01845 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 01846 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 01847 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1837 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 1979 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().
01980 { 01981 /* this function turns off and on custom callno limits set by peer registration */ 01982 struct peercnt *peercnt; 01983 struct peercnt tmp = { 01984 .addr = sin->sin_addr.s_addr, 01985 }; 01986 01987 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 01988 peercnt->reg = reg; 01989 if (limit) { 01990 peercnt->limit = limit; 01991 } else { 01992 set_peercnt_limit(peercnt); 01993 } 01994 if (option_debug) { 01995 ast_log(LOG_DEBUG, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 01996 } 01997 ao2_ref(peercnt, -1); /* decrement ref from find */ 01998 } 01999 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2063 of file chan_iax2.c.
References peercnt::addr, ao2_lock(), ao2_unlink(), ao2_unlock(), ast_inet_ntoa(), ast_log(), peercnt::cur, LOG_DEBUG, option_debug, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02064 { 02065 struct sockaddr_in sin = { 02066 .sin_addr.s_addr = peercnt->addr, 02067 }; 02068 02069 if (peercnt) { 02070 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02071 * peercnt_add could try and grab this entry from the table and modify it at the 02072 * "same time" this thread attemps to unlink it.*/ 02073 ao2_lock(peercnts); 02074 peercnt->cur--; 02075 if (option_debug) { 02076 ast_log(LOG_DEBUG, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02077 } 02078 /* if this was the last connection from the peer remove it from table */ 02079 if (peercnt->cur == 0) { 02080 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02081 } 02082 ao2_unlock(peercnts); 02083 } 02084 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2104 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
02105 { 02106 struct peercnt *peercnt; 02107 struct peercnt tmp = { 02108 .addr = sin->sin_addr.s_addr, 02109 }; 02110 02111 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02112 peercnt_remove(peercnt); 02113 ao2_ref(peercnt, -1); /* decrement ref from find */ 02114 } 02115 return 0; 02116 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2090 of file chan_iax2.c.
References ao2_ref(), and peercnt_remove().
Referenced by sched_delay_remove().
02091 { 02092 struct peercnt *peercnt = (struct peercnt *) obj; 02093 02094 peercnt_remove(peercnt); 02095 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02096 02097 return 0; 02098 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 11793 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().
11794 { 11795 struct ao2_iterator i; 11796 struct iax2_peer *peer; 11797 11798 i = ao2_iterator_init(peers, 0); 11799 while ((peer = ao2_iterator_next(&i))) { 11800 iax2_poke_peer(peer, 0); 11801 peer_unref(peer); 11802 } 11803 ao2_iterator_destroy(&i); 11804 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1968 of file chan_iax2.c.
References addr_range::delme.
Referenced by reload_config().
01969 { 01970 struct addr_range *addr_range = obj; 01971 01972 return addr_range->delme ? CMP_MATCH : 0; 01973 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 11361 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().
11362 { 11363 struct iax2_peer *peer; 11364 struct ao2_iterator i; 11365 11366 i = ao2_iterator_init(peers, 0); 11367 while ((peer = ao2_iterator_next(&i))) { 11368 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 11369 unlink_peer(peer); 11370 } 11371 peer_unref(peer); 11372 } 11373 ao2_iterator_destroy(&i); 11374 }
static void prune_users | ( | void | ) | [static] |
Definition at line 11345 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().
11346 { 11347 struct iax2_user *user; 11348 struct ao2_iterator i; 11349 11350 i = ao2_iterator_init(users, 0); 11351 while ((user = ao2_iterator_next(&i))) { 11352 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 11353 ao2_unlink(users, user); 11354 } 11355 user_unref(user); 11356 } 11357 ao2_iterator_destroy(&i); 11358 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12684 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12685 { 12686 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12687 12688 /* The frames_received field is used to hold whether we're matching 12689 * against a full frame or not ... */ 12690 12691 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 12692 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12693 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1606 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().
01607 { 01608 struct chan_iax2_pvt *pvt = obj; 01609 struct iax_frame *cur = NULL; 01610 struct signaling_queue_entry *s = NULL; 01611 01612 iax2_destroy_helper(pvt); 01613 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01614 pvt->callno_entry = NULL; 01615 01616 /* Already gone */ 01617 ast_set_flag(pvt, IAX_ALREADYGONE); 01618 01619 AST_LIST_LOCK(&iaxq.queue); 01620 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01621 /* Cancel any pending transmissions */ 01622 if (cur->callno == pvt->callno) { 01623 cur->retries = -1; 01624 } 01625 } 01626 AST_LIST_UNLOCK(&iaxq.queue); 01627 01628 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01629 free_signaling_queue_entry(s); 01630 } 01631 01632 if (pvt->reg) { 01633 pvt->reg->callno = 0; 01634 } 01635 01636 if (!pvt->owner) { 01637 jb_frame frame; 01638 if (pvt->vars) { 01639 ast_variables_destroy(pvt->vars); 01640 pvt->vars = NULL; 01641 } 01642 01643 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01644 iax2_frame_free(frame.data); 01645 } 01646 01647 jb_destroy(pvt->jb); 01648 ast_string_field_free_memory(pvt); 01649 } 01650 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12677 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
12678 { 12679 const struct chan_iax2_pvt *pvt = obj; 12680 12681 return pvt->peercallno; 12682 }
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 1582 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().
01583 { 01584 struct signaling_queue_entry *new; 01585 01586 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01587 return 1; /* do not queue this frame */ 01588 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01589 return -1; /* out of memory */ 01590 } 01591 01592 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01593 01594 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01595 if (!(new->f.data = ast_calloc(1, new->f.datalen))) { 01596 free_signaling_queue_entry(new); 01597 return -1; 01598 } 01599 memcpy(new->f.data, f->data, sizeof(*new->f.data)); 01600 } 01601 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01602 01603 return 0; 01604 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 6642 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().
06643 { 06644 struct ast_iax2_full_hdr fh; 06645 fh.scallno = htons(src | IAX_FLAG_FULL); 06646 fh.dcallno = htons(dst); 06647 fh.ts = 0; 06648 fh.oseqno = 0; 06649 fh.iseqno = 0; 06650 fh.type = AST_FRAME_IAX; 06651 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 06652 if (iaxdebug) 06653 iax_showframe(NULL, &fh, 0, sin, 0); 06654 if (option_debug) 06655 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 06656 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 06657 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 06658 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3755 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.
03756 { 03757 struct ast_variable *var = NULL; 03758 struct ast_variable *tmp; 03759 struct iax2_peer *peer=NULL; 03760 time_t regseconds = 0, nowtime; 03761 int dynamic=0; 03762 03763 if (peername) { 03764 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 03765 if (!var && sin) 03766 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03767 } else if (sin) { 03768 char porta[25]; 03769 sprintf(porta, "%d", ntohs(sin->sin_port)); 03770 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03771 if (var) { 03772 /* We'll need the peer name in order to build the structure! */ 03773 for (tmp = var; tmp; tmp = tmp->next) { 03774 if (!strcasecmp(tmp->name, "name")) 03775 peername = tmp->value; 03776 } 03777 } 03778 } 03779 if (!var && peername) { /* Last ditch effort */ 03780 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 03781 /*!\note 03782 * If this one loaded something, then we need to ensure that the host 03783 * field matched. The only reason why we can't have this as a criteria 03784 * is because we only have the IP address and the host field might be 03785 * set as a name (and the reverse PTR might not match). 03786 */ 03787 if (var && sin) { 03788 for (tmp = var; tmp; tmp = tmp->next) { 03789 if (!strcasecmp(tmp->name, "host")) { 03790 struct ast_hostent ahp; 03791 struct hostent *hp; 03792 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03793 /* No match */ 03794 ast_variables_destroy(var); 03795 var = NULL; 03796 } 03797 break; 03798 } 03799 } 03800 } 03801 } 03802 if (!var) 03803 return NULL; 03804 03805 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 03806 03807 if (!peer) { 03808 ast_variables_destroy(var); 03809 return NULL; 03810 } 03811 03812 for (tmp = var; tmp; tmp = tmp->next) { 03813 /* Make sure it's not a user only... */ 03814 if (!strcasecmp(tmp->name, "type")) { 03815 if (strcasecmp(tmp->value, "friend") && 03816 strcasecmp(tmp->value, "peer")) { 03817 /* Whoops, we weren't supposed to exist! */ 03818 peer = peer_unref(peer); 03819 break; 03820 } 03821 } else if (!strcasecmp(tmp->name, "regseconds")) { 03822 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 03823 } else if (!strcasecmp(tmp->name, "ipaddr")) { 03824 inet_aton(tmp->value, &(peer->addr.sin_addr)); 03825 } else if (!strcasecmp(tmp->name, "port")) { 03826 peer->addr.sin_port = htons(atoi(tmp->value)); 03827 } else if (!strcasecmp(tmp->name, "host")) { 03828 if (!strcasecmp(tmp->value, "dynamic")) 03829 dynamic = 1; 03830 } 03831 } 03832 03833 ast_variables_destroy(var); 03834 03835 if (!peer) 03836 return NULL; 03837 03838 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03839 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 03840 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 03841 if (peer->expire > -1) { 03842 if (!ast_sched_del(sched, peer->expire)) { 03843 peer->expire = -1; 03844 peer_unref(peer); 03845 } 03846 } 03847 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 03848 if (peer->expire == -1) 03849 peer_unref(peer); 03850 } 03851 ao2_link(peers, peer); 03852 if (ast_test_flag(peer, IAX_DYNAMIC)) 03853 reg_source_db(peer); 03854 } else { 03855 ast_set_flag(peer, IAX_TEMPONLY); 03856 } 03857 03858 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 03859 time(&nowtime); 03860 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 03861 memset(&peer->addr, 0, sizeof(peer->addr)); 03862 realtime_update_peer(peer->name, &peer->addr, 0); 03863 if (option_debug) 03864 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 03865 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03866 } 03867 else { 03868 if (option_debug) 03869 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 03870 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03871 } 03872 } 03873 03874 return peer; 03875 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3948 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03949 { 03950 char port[10]; 03951 char regseconds[20]; 03952 03953 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03954 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03955 ast_update_realtime("iaxpeers", "name", peername, 03956 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03957 "regseconds", regseconds, NULL); 03958 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3877 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.
03878 { 03879 struct ast_variable *var; 03880 struct ast_variable *tmp; 03881 struct iax2_user *user=NULL; 03882 03883 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 03884 if (!var) 03885 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03886 if (!var && sin) { 03887 char porta[6]; 03888 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 03889 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03890 if (!var) 03891 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03892 } 03893 if (!var) { /* Last ditch effort */ 03894 var = ast_load_realtime("iaxusers", "name", username, NULL); 03895 /*!\note 03896 * If this one loaded something, then we need to ensure that the host 03897 * field matched. The only reason why we can't have this as a criteria 03898 * is because we only have the IP address and the host field might be 03899 * set as a name (and the reverse PTR might not match). 03900 */ 03901 if (var) { 03902 for (tmp = var; tmp; tmp = tmp->next) { 03903 if (!strcasecmp(tmp->name, "host")) { 03904 struct ast_hostent ahp; 03905 struct hostent *hp; 03906 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03907 /* No match */ 03908 ast_variables_destroy(var); 03909 var = NULL; 03910 } 03911 break; 03912 } 03913 } 03914 } 03915 } 03916 if (!var) 03917 return NULL; 03918 03919 tmp = var; 03920 while(tmp) { 03921 /* Make sure it's not a peer only... */ 03922 if (!strcasecmp(tmp->name, "type")) { 03923 if (strcasecmp(tmp->value, "friend") && 03924 strcasecmp(tmp->value, "user")) { 03925 return NULL; 03926 } 03927 } 03928 tmp = tmp->next; 03929 } 03930 03931 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03932 03933 ast_variables_destroy(var); 03934 03935 if (!user) 03936 return NULL; 03937 03938 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03939 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03940 ao2_link(users, user); 03941 } else { 03942 ast_set_flag(user, IAX_TEMPONLY); 03943 } 03944 03945 return user; 03946 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 7470 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().
07471 { 07472 char data[80]; 07473 struct in_addr in; 07474 char *c, *d; 07475 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 07476 c = strchr(data, ':'); 07477 if (c) { 07478 *c = '\0'; 07479 c++; 07480 if (inet_aton(data, &in)) { 07481 d = strchr(c, ':'); 07482 if (d) { 07483 *d = '\0'; 07484 d++; 07485 if (option_verbose > 2) 07486 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 07487 ast_inet_ntoa(in), atoi(c), atoi(d)); 07488 iax2_poke_peer(p, 0); 07489 p->expiry = atoi(d); 07490 memset(&p->addr, 0, sizeof(p->addr)); 07491 p->addr.sin_family = AF_INET; 07492 p->addr.sin_addr = in; 07493 p->addr.sin_port = htons(atoi(c)); 07494 if (p->expire > -1) { 07495 if (!ast_sched_del(sched, p->expire)) { 07496 p->expire = -1; 07497 peer_unref(p); 07498 } 07499 } 07500 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07501 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07502 if (p->expire == -1) 07503 peer_unref(p); 07504 if (iax2_regfunk) 07505 iax2_regfunk(p->name, 1); 07506 register_peer_exten(p, 1); 07507 } 07508 07509 } 07510 } 07511 } 07512 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 7388 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().
07389 { 07390 char multi[256]; 07391 char *stringp, *ext; 07392 if (!ast_strlen_zero(regcontext)) { 07393 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 07394 stringp = multi; 07395 while((ext = strsep(&stringp, "&"))) { 07396 if (onoff) { 07397 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 07398 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 07399 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 07400 } else 07401 ast_context_remove_extension(regcontext, ext, 1, NULL); 07402 } 07403 } 07404 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 6809 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().
06810 { 06811 char requeststr[256] = ""; 06812 char peer[256] = ""; 06813 char md5secret[256] = ""; 06814 char rsasecret[256] = ""; 06815 char secret[256] = ""; 06816 struct iax2_peer *p = NULL; 06817 struct ast_key *key; 06818 char *keyn; 06819 int x; 06820 int expire = 0; 06821 int res = -1; 06822 06823 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06824 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 06825 if (ies->username) 06826 ast_copy_string(peer, ies->username, sizeof(peer)); 06827 if (ies->password) 06828 ast_copy_string(secret, ies->password, sizeof(secret)); 06829 if (ies->md5_result) 06830 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06831 if (ies->rsa_result) 06832 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06833 if (ies->refresh) 06834 expire = ies->refresh; 06835 06836 if (ast_strlen_zero(peer)) { 06837 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 06838 return -1; 06839 } 06840 06841 /* SLD: first call to lookup peer during registration */ 06842 ast_mutex_unlock(&iaxsl[callno]); 06843 p = find_peer(peer, 1); 06844 ast_mutex_lock(&iaxsl[callno]); 06845 if (!p || !iaxs[callno]) { 06846 if (iaxs[callno]) { 06847 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 06848 06849 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06850 06851 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 06852 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 06853 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 06854 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 06855 * to be plaintext, indicating it is an authmethod used by other peers on the system. 06856 * 06857 * If none of these cases exist, res will be returned as 0 without authentication indicating 06858 * an AUTHREQ needs to be sent out. */ 06859 06860 if (ast_strlen_zero(iaxs[callno]->challenge) && 06861 !(!ast_strlen_zero(secret) && plaintext)) { 06862 /* by setting res to 0, an REGAUTH will be sent */ 06863 res = 0; 06864 } 06865 } 06866 if (authdebug && !p) 06867 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06868 06869 goto return_unref; 06870 } 06871 06872 if (!ast_test_flag(p, IAX_DYNAMIC)) { 06873 if (authdebug) 06874 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06875 goto return_unref; 06876 } 06877 06878 if (!ast_apply_ha(p->ha, sin)) { 06879 if (authdebug) 06880 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06881 goto return_unref; 06882 } 06883 ast_string_field_set(iaxs[callno], secret, p->secret); 06884 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 06885 /* Check secret against what we have on file */ 06886 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06887 if (!ast_strlen_zero(p->inkeys)) { 06888 char tmpkeys[256]; 06889 char *stringp=NULL; 06890 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 06891 stringp=tmpkeys; 06892 keyn = strsep(&stringp, ":"); 06893 while(keyn) { 06894 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06895 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 06896 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06897 break; 06898 } else if (!key) 06899 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 06900 keyn = strsep(&stringp, ":"); 06901 } 06902 if (!keyn) { 06903 if (authdebug) 06904 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 06905 goto return_unref; 06906 } 06907 } else { 06908 if (authdebug) 06909 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 06910 goto return_unref; 06911 } 06912 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06913 struct MD5Context md5; 06914 unsigned char digest[16]; 06915 char *tmppw, *stringp; 06916 06917 tmppw = ast_strdupa(p->secret); 06918 stringp = tmppw; 06919 while((tmppw = strsep(&stringp, ";"))) { 06920 MD5Init(&md5); 06921 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06922 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06923 MD5Final(digest, &md5); 06924 for (x=0;x<16;x++) 06925 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06926 if (!strcasecmp(requeststr, md5secret)) 06927 break; 06928 } 06929 if (tmppw) { 06930 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06931 } else { 06932 if (authdebug) 06933 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 06934 goto return_unref; 06935 } 06936 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 06937 /* They've provided a plain text password and we support that */ 06938 if (strcmp(secret, p->secret)) { 06939 if (authdebug) 06940 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06941 goto return_unref; 06942 } else 06943 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06944 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 06945 /* if challenge has been sent, but no challenge response if given, reject. */ 06946 goto return_unref; 06947 } 06948 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06949 06950 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 06951 res = 0; 06952 return_unref: 06953 06954 if (iaxs[callno]) { 06955 ast_string_field_set(iaxs[callno], peer, peer); 06956 06957 /* Choose lowest expiry number */ 06958 if (expire && (expire < iaxs[callno]->expiry)) { 06959 iaxs[callno]->expiry = expire; 06960 } 06961 } 06962 06963 if (p) { 06964 peer_unref(p); 06965 } 06966 return res; 06967 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 7659 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().
07660 { 07661 struct iax_ie_data ied; 07662 struct iax2_peer *p; 07663 char challenge[10]; 07664 const char *peer_name; 07665 int sentauthmethod; 07666 07667 peer_name = ast_strdupa(iaxs[callno]->peer); 07668 07669 /* SLD: third call to find_peer in registration */ 07670 ast_mutex_unlock(&iaxsl[callno]); 07671 if ((p = find_peer(peer_name, 1))) { 07672 last_authmethod = p->authmethods; 07673 } 07674 07675 ast_mutex_lock(&iaxsl[callno]); 07676 if (!iaxs[callno]) 07677 goto return_unref; 07678 07679 memset(&ied, 0, sizeof(ied)); 07680 /* The selection of which delayed reject is sent may leak information, 07681 * if it sets a static response. For example, if a host is known to only 07682 * use MD5 authentication, then an RSA response would indicate that the 07683 * peer does not exist, and vice-versa. 07684 * Therefore, we use whatever the last peer used (which may vary over the 07685 * course of a server, which should leak minimal information). */ 07686 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07687 if (!p) { 07688 iaxs[callno]->authmethods = sentauthmethod; 07689 } 07690 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 07691 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 07692 /* Build the challenge */ 07693 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07694 ast_string_field_set(iaxs[callno], challenge, challenge); 07695 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 07696 } 07697 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 07698 07699 return_unref: 07700 if (p) { 07701 peer_unref(p); 07702 } 07703 07704 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 07705 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 7707 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().
07708 { 07709 struct iax2_registry *reg; 07710 /* Start pessimistic */ 07711 struct iax_ie_data ied; 07712 char peer[256] = ""; 07713 char challenge[256] = ""; 07714 int res; 07715 int authmethods = 0; 07716 if (ies->authmethods) 07717 authmethods = ies->authmethods; 07718 if (ies->username) 07719 ast_copy_string(peer, ies->username, sizeof(peer)); 07720 if (ies->challenge) 07721 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 07722 memset(&ied, 0, sizeof(ied)); 07723 reg = iaxs[callno]->reg; 07724 if (reg) { 07725 if (inaddrcmp(®->addr, sin)) { 07726 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07727 return -1; 07728 } 07729 if (ast_strlen_zero(reg->secret)) { 07730 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 07731 reg->regstate = REG_STATE_NOAUTH; 07732 return -1; 07733 } 07734 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07735 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07736 if (reg->secret[0] == '[') { 07737 char tmpkey[256]; 07738 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 07739 tmpkey[strlen(tmpkey) - 1] = '\0'; 07740 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 07741 } else 07742 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 07743 if (!res) { 07744 reg->regstate = REG_STATE_AUTHSENT; 07745 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 07746 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07747 } else 07748 return -1; 07749 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 07750 } else 07751 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 07752 return -1; 07753 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 6056 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().
06057 { 06058 switch(regstate) { 06059 case REG_STATE_UNREGISTERED: 06060 return "Unregistered"; 06061 case REG_STATE_REGSENT: 06062 return "Request Sent"; 06063 case REG_STATE_AUTHSENT: 06064 return "Auth. Sent"; 06065 case REG_STATE_REGISTERED: 06066 return "Registered"; 06067 case REG_STATE_REJECTED: 06068 return "Rejected"; 06069 case REG_STATE_TIMEOUT: 06070 return "Timeout"; 06071 case REG_STATE_NOAUTH: 06072 return "No Authentication"; 06073 default: 06074 return "Unknown"; 06075 } 06076 }
static int reload | ( | void | ) | [static] |
Definition at line 11834 of file chan_iax2.c.
References reload_config().
11835 { 11836 return reload_config(); 11837 }
static int reload_config | ( | void | ) | [static] |
Definition at line 11805 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().
11806 { 11807 static const char config[] = "iax.conf"; 11808 struct iax2_registry *reg; 11809 11810 if (set_config(config, 1) > 0) { 11811 prune_peers(); 11812 prune_users(); 11813 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11814 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11815 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 11816 AST_LIST_LOCK(®istrations); 11817 AST_LIST_TRAVERSE(®istrations, reg, entry) 11818 iax2_do_register(reg); 11819 AST_LIST_UNLOCK(®istrations); 11820 /* Qualify hosts, too */ 11821 poke_all_peers(); 11822 } 11823 reload_firmware(0); 11824 iax_provision_reload(); 11825 11826 return 0; 11827 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2869 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().
02870 { 02871 struct iax_firmware *cur, *curl, *curp; 02872 DIR *fwd; 02873 struct dirent *de; 02874 char dir[256]; 02875 char fn[256]; 02876 /* Mark all as dead */ 02877 ast_mutex_lock(&waresl.lock); 02878 cur = waresl.wares; 02879 while(cur) { 02880 cur->dead = 1; 02881 cur = cur->next; 02882 } 02883 02884 /* Now that we've freed them, load the new ones */ 02885 if (!unload) { 02886 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02887 fwd = opendir(dir); 02888 if (fwd) { 02889 while((de = readdir(fwd))) { 02890 if (de->d_name[0] != '.') { 02891 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02892 if (!try_firmware(fn)) { 02893 if (option_verbose > 1) 02894 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02895 } 02896 } 02897 } 02898 closedir(fwd); 02899 } else 02900 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02901 } 02902 02903 /* Clean up leftovers */ 02904 cur = waresl.wares; 02905 curp = NULL; 02906 while(cur) { 02907 curl = cur; 02908 cur = cur->next; 02909 if (curl->dead) { 02910 if (curp) { 02911 curp->next = cur; 02912 } else { 02913 waresl.wares = cur; 02914 } 02915 destroy_firmware(curl); 02916 } else { 02917 curp = cur; 02918 } 02919 } 02920 ast_mutex_unlock(&waresl.lock); 02921 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1447 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().
01448 { 01449 if (!pvt->peercallno) { 01450 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01451 return; 01452 } 01453 01454 ao2_unlink(iax_peercallno_pvts, pvt); 01455 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1428 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().
01429 { 01430 if (!pvt->transfercallno) { 01431 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01432 return; 01433 } 01434 01435 ao2_unlink(iax_transfercallno_pvts, pvt); 01436 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2284 of file chan_iax2.c.
References ao2_lock(), ao2_ref(), ao2_unlock(), ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02285 { 02286 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02287 02288 /* the callno_pool container is locked here primarily to ensure thread 02289 * safety of the total_nonval_callno_used check and decrement */ 02290 ao2_lock(callno_pool); 02291 02292 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02293 total_nonval_callno_used--; 02294 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02295 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02296 } 02297 02298 if (callno_entry->callno < TRUNK_CALL_START) { 02299 ao2_link(callno_pool, callno_entry); 02300 } else { 02301 ao2_link(callno_pool_trunk, callno_entry); 02302 } 02303 ao2_ref(callno_entry, -1); /* only container ref remains */ 02304 02305 ao2_unlock(callno_pool); 02306 return 0; 02307 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4246 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().
04247 { 04248 struct iax2_user *user = NULL; 04249 struct iax2_peer *peer = NULL; 04250 04251 if (ast_strlen_zero(name)) { 04252 return; /* no username given */ 04253 } 04254 04255 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04256 user->calltoken_required = CALLTOKEN_YES; 04257 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04258 peer->calltoken_required = CALLTOKEN_YES; 04259 } 04260 04261 if (peer) { 04262 peer_unref(peer); 04263 } 04264 if (user) { 04265 user_unref(user); 04266 } 04267 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4162 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().
04163 { 04164 struct chan_iax2_pvt *pvt = iaxs[callno]; 04165 int frametype = f->af.frametype; 04166 int subclass = f->af.subclass; 04167 struct { 04168 struct ast_iax2_full_hdr fh; 04169 struct iax_ie_data ied; 04170 } data = { 04171 .ied.buf = { 0 }, 04172 .ied.pos = 0, 04173 }; 04174 /* total len - header len gives us the frame's IE len */ 04175 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04176 04177 if (!pvt) { 04178 return; /* this should not be possible if called from socket_process() */ 04179 } 04180 04181 /* 04182 * Check to make sure last frame sent is valid for call token resend 04183 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04184 * 2. Frame should _NOT_ already have a destination callno 04185 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04186 * 4. Pvt must have a calltoken_ie_len which represents the number of 04187 * bytes at the end of the frame used for the previous calltoken ie. 04188 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04189 * 6. Total length of f->data must be _LESS_ than size of our data struct 04190 * because f->data must be able to fit within data. 04191 */ 04192 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04193 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04194 (f->datalen > sizeof(data))) { 04195 04196 return; /* ignore resend, token was not valid for the dialog */ 04197 } 04198 04199 /* token is valid 04200 * 1. Copy frame data over 04201 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04202 * NOTE: Having the ie always be last is not protocol specified, 04203 * it is only an implementation choice. Since we only expect the ie to 04204 * be last for frames we have sent, this can no way be affected by 04205 * another end point. 04206 * 3. Remove frame from queue 04207 * 4. Free old frame 04208 * 5. Clear previous seqnos 04209 * 6. Resend with CALLTOKEN ie. 04210 */ 04211 04212 /* ---1.--- */ 04213 memcpy(&data, f->data, f->datalen); 04214 data.ied.pos = ie_data_pos; 04215 04216 /* ---2.--- */ 04217 /* move to the beginning of the calltoken ie so we can write over it */ 04218 data.ied.pos -= pvt->calltoken_ie_len; 04219 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04220 04221 /* make sure to update token length incase it ever has to be stripped off again */ 04222 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04223 04224 /* ---3.--- */ 04225 AST_LIST_LOCK(&iaxq.queue); 04226 AST_LIST_REMOVE(&iaxq.queue, f, list); 04227 AST_LIST_UNLOCK(&iaxq.queue); 04228 04229 /* ---4.--- */ 04230 iax2_frame_free(f); 04231 04232 /* ---5.--- */ 04233 pvt->oseqno = 0; 04234 pvt->rseqno = 0; 04235 pvt->iseqno = 0; 04236 pvt->aseqno = 0; 04237 if (pvt->peercallno) { 04238 remove_by_peercallno(pvt); 04239 pvt->peercallno = 0; 04240 } 04241 04242 /* ---6.--- */ 04243 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04244 }
Definition at line 8212 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().
08213 { 08214 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 08215 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 08216 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 08217 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 08218 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 08219 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 08220 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 08221 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2356 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().
02357 { 02358 int i; 02359 struct peercnt *peercnt; 02360 struct peercnt tmp = { 02361 .addr = sin->sin_addr.s_addr, 02362 }; 02363 02364 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02365 if (unloading) { 02366 peercnt_remove_cb(peercnt); 02367 replace_callno(callno_entry); 02368 return; 02369 } 02370 02371 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02372 if (option_debug) { 02373 ast_log(LOG_DEBUG, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02374 } 02375 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02376 if (i == -1) { 02377 ao2_ref(peercnt, -1); 02378 } 02379 } 02380 02381 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02382 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 10538 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, and sched.
Referenced by start_network_thread().
10539 { 10540 for (;;) { 10541 int ms, count; 10542 struct timespec ts; 10543 10544 pthread_testcancel(); 10545 10546 ast_mutex_lock(&sched_lock); 10547 10548 ms = ast_sched_wait(sched); 10549 10550 if (ms == -1) { 10551 ast_cond_wait(&sched_cond, &sched_lock); 10552 } else { 10553 struct timeval tv; 10554 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 10555 ts.tv_sec = tv.tv_sec; 10556 ts.tv_nsec = tv.tv_usec * 1000; 10557 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 10558 } 10559 10560 ast_mutex_unlock(&sched_lock); 10561 10562 pthread_testcancel(); 10563 10564 count = ast_sched_runq(sched); 10565 if (option_debug && count >= 20) { 10566 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 10567 } 10568 } 10569 10570 return NULL; 10571 }
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 3597 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_mutex_unlock(), 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(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, ast_channel::lock, 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().
03598 { 03599 int type, len; 03600 int ret; 03601 int needfree = 0; 03602 struct ast_channel *owner = NULL; 03603 struct ast_channel *bridge = NULL; 03604 03605 /* Attempt to recover wrapped timestamps */ 03606 unwrap_timestamp(fr); 03607 03608 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03609 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03610 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03611 else { 03612 #if 0 03613 if (option_debug) 03614 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03615 #endif 03616 fr->af.delivery = ast_tv(0,0); 03617 } 03618 03619 type = JB_TYPE_CONTROL; 03620 len = 0; 03621 03622 if(fr->af.frametype == AST_FRAME_VOICE) { 03623 type = JB_TYPE_VOICE; 03624 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03625 } else if(fr->af.frametype == AST_FRAME_CNG) { 03626 type = JB_TYPE_SILENCE; 03627 } 03628 03629 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 03630 if (tsout) 03631 *tsout = fr->ts; 03632 __do_deliver(fr); 03633 return -1; 03634 } 03635 03636 iax2_lock_owner(fr->callno); 03637 if (!iaxs[fr->callno]) { 03638 /* The call dissappeared so discard this frame that we could not send. */ 03639 iax2_frame_free(fr); 03640 return -1; 03641 } 03642 if ((owner = iaxs[fr->callno]->owner)) 03643 bridge = ast_bridged_channel(owner); 03644 03645 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 03646 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 03647 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 03648 jb_frame frame; 03649 03650 ast_mutex_unlock(&owner->lock); 03651 03652 /* deliver any frames in the jb */ 03653 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 03654 __do_deliver(frame.data); 03655 /* __do_deliver() can make the call disappear */ 03656 if (!iaxs[fr->callno]) 03657 return -1; 03658 } 03659 03660 jb_reset(iaxs[fr->callno]->jb); 03661 03662 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 03663 03664 /* deliver this frame now */ 03665 if (tsout) 03666 *tsout = fr->ts; 03667 __do_deliver(fr); 03668 return -1; 03669 } 03670 if (owner) { 03671 ast_mutex_unlock(&owner->lock); 03672 } 03673 03674 /* insert into jitterbuffer */ 03675 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 03676 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 03677 calc_rxstamp(iaxs[fr->callno],fr->ts)); 03678 if (ret == JB_DROP) { 03679 needfree++; 03680 } else if (ret == JB_SCHED) { 03681 update_jbsched(iaxs[fr->callno]); 03682 } 03683 if (tsout) 03684 *tsout = fr->ts; 03685 if (needfree) { 03686 /* Free our iax frame */ 03687 iax2_frame_free(fr); 03688 return -1; 03689 } 03690 return 0; 03691 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1547 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().
01548 { 01549 unsigned short callno = PTR_TO_CALLNO(vid); 01550 ast_mutex_lock(&iaxsl[callno]); 01551 if (iaxs[callno]) { 01552 if (option_debug) { 01553 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01554 } 01555 iax2_destroy(callno); 01556 } 01557 ast_mutex_unlock(&iaxsl[callno]); 01558 return 0; 01559 }
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 4126 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().
04129 { 04130 struct { 04131 struct ast_iax2_full_hdr f; 04132 struct iax_ie_data ied; 04133 } data; 04134 size_t size = sizeof(struct ast_iax2_full_hdr); 04135 04136 if (ied) { 04137 size += ied->pos; 04138 memcpy(&data.ied, ied->buf, ied->pos); 04139 } 04140 04141 data.f.scallno = htons(0x8000 | callno); 04142 data.f.dcallno = htons(dcallno); 04143 data.f.ts = htonl(ts); 04144 data.f.iseqno = seqno; 04145 data.f.oseqno = 0; 04146 data.f.type = AST_FRAME_IAX; 04147 data.f.csub = compress_subclass(command); 04148 04149 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04150 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6367 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().
06368 { 06369 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 06370 }
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 6386 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().
06387 { 06388 int call_num = i->callno; 06389 /* It is assumed that the callno has already been locked */ 06390 iax2_predestroy(i->callno); 06391 if (!iaxs[call_num]) 06392 return -1; 06393 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 06394 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6396 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
06397 { 06398 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 06399 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6372 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().
06373 { 06374 int res; 06375 ast_mutex_lock(&iaxsl[callno]); 06376 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 06377 ast_mutex_unlock(&iaxsl[callno]); 06378 return res; 06379 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 6401 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
06402 { 06403 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 06404 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1223 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01224 { 01225 #ifdef SCHED_MULTITHREADED 01226 if (schedule_action(__send_lagrq, data)) 01227 #endif 01228 __send_lagrq(data); 01229 01230 return 0; 01231 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2994 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().
02995 { 02996 int res; 02997 int callno = f->callno; 02998 02999 /* Don't send if there was an error, but return error instead */ 03000 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03001 return -1; 03002 03003 /* Called with iaxsl held */ 03004 if (option_debug > 2 && iaxdebug) 03005 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)); 03006 if (f->transfer) { 03007 if (iaxdebug) 03008 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03009 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 03010 sizeof(iaxs[callno]->transfer)); 03011 } else { 03012 if (iaxdebug) 03013 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03014 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 03015 sizeof(iaxs[callno]->addr)); 03016 } 03017 if (res < 0) { 03018 if (option_debug && iaxdebug) 03019 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 03020 handle_error(); 03021 } else 03022 res = 0; 03023 return res; 03024 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1178 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01179 { 01180 #ifdef SCHED_MULTITHREADED 01181 if (schedule_action(__send_ping, data)) 01182 #endif 01183 __send_ping(data); 01184 01185 return 0; 01186 }
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 1569 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().
01570 { 01571 struct signaling_queue_entry *s = NULL; 01572 01573 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01574 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01575 free_signaling_queue_entry(s); 01576 } 01577 pvt->hold_signaling = 0; 01578 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 7890 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().
07891 { 07892 int res = 0; 07893 struct iax_frame *fr; 07894 struct ast_iax2_meta_hdr *meta; 07895 struct ast_iax2_meta_trunk_hdr *mth; 07896 int calls = 0; 07897 07898 /* Point to frame */ 07899 fr = (struct iax_frame *)tpeer->trunkdata; 07900 /* Point to meta data */ 07901 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 07902 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 07903 if (tpeer->trunkdatalen) { 07904 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 07905 meta->zeros = 0; 07906 meta->metacmd = IAX_META_TRUNK; 07907 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 07908 meta->cmddata = IAX_META_TRUNK_MINI; 07909 else 07910 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 07911 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 07912 /* And the rest of the ast_iax2 header */ 07913 fr->direction = DIRECTION_OUTGRESS; 07914 fr->retrans = -1; 07915 fr->transfer = 0; 07916 /* Any appropriate call will do */ 07917 fr->data = fr->afdata; 07918 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 07919 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 07920 calls = tpeer->calls; 07921 #if 0 07922 if (option_debug) 07923 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)); 07924 #endif 07925 /* Reset transmit trunk side data */ 07926 tpeer->trunkdatalen = 0; 07927 tpeer->calls = 0; 07928 } 07929 if (res < 0) 07930 return res; 07931 return calls; 07932 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 11409 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().
11410 { 11411 struct ast_config *cfg, *ucfg; 11412 int capability=iax2_capability; 11413 struct ast_variable *v; 11414 char *cat; 11415 const char *utype; 11416 const char *tosval; 11417 int format; 11418 int portno = IAX_DEFAULT_PORTNO; 11419 int x; 11420 struct iax2_user *user; 11421 struct iax2_peer *peer; 11422 struct ast_netsock *ns; 11423 #if 0 11424 static unsigned short int last_port=0; 11425 #endif 11426 11427 cfg = ast_config_load(config_file); 11428 11429 if (!cfg) { 11430 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 11431 return -1; 11432 } 11433 11434 if (reload) { 11435 set_config_destroy(); 11436 } 11437 11438 /* Reset global codec prefs */ 11439 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 11440 11441 /* Reset Global Flags */ 11442 memset(&globalflags, 0, sizeof(globalflags)); 11443 ast_set_flag(&globalflags, IAX_RTUPDATE); 11444 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 11445 11446 #ifdef SO_NO_CHECK 11447 nochecksums = 0; 11448 #endif 11449 11450 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11451 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11452 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 11453 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 11454 11455 maxauthreq = 3; 11456 11457 v = ast_variable_browse(cfg, "general"); 11458 11459 /* Seed initial tos value */ 11460 tosval = ast_variable_retrieve(cfg, "general", "tos"); 11461 if (tosval) { 11462 if (ast_str2tos(tosval, &tos)) 11463 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 11464 } 11465 while(v) { 11466 if (!strcasecmp(v->name, "bindport")){ 11467 if (reload) 11468 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 11469 else 11470 portno = atoi(v->value); 11471 } else if (!strcasecmp(v->name, "pingtime")) 11472 ping_time = atoi(v->value); 11473 else if (!strcasecmp(v->name, "iaxthreadcount")) { 11474 if (reload) { 11475 if (atoi(v->value) != iaxthreadcount) 11476 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 11477 } else { 11478 iaxthreadcount = atoi(v->value); 11479 if (iaxthreadcount < 1) { 11480 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 11481 iaxthreadcount = 1; 11482 } else if (iaxthreadcount > 256) { 11483 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 11484 iaxthreadcount = 256; 11485 } 11486 } 11487 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 11488 if (reload) { 11489 AST_LIST_LOCK(&dynamic_list); 11490 iaxmaxthreadcount = atoi(v->value); 11491 AST_LIST_UNLOCK(&dynamic_list); 11492 } else { 11493 iaxmaxthreadcount = atoi(v->value); 11494 if (iaxmaxthreadcount < 0) { 11495 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 11496 iaxmaxthreadcount = 0; 11497 } else if (iaxmaxthreadcount > 256) { 11498 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 11499 iaxmaxthreadcount = 256; 11500 } 11501 } 11502 } else if (!strcasecmp(v->name, "nochecksums")) { 11503 #ifdef SO_NO_CHECK 11504 if (ast_true(v->value)) 11505 nochecksums = 1; 11506 else 11507 nochecksums = 0; 11508 #else 11509 if (ast_true(v->value)) 11510 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 11511 #endif 11512 } 11513 else if (!strcasecmp(v->name, "maxjitterbuffer")) 11514 maxjitterbuffer = atoi(v->value); 11515 else if (!strcasecmp(v->name, "resyncthreshold")) 11516 resyncthreshold = atoi(v->value); 11517 else if (!strcasecmp(v->name, "maxjitterinterps")) 11518 maxjitterinterps = atoi(v->value); 11519 else if (!strcasecmp(v->name, "lagrqtime")) 11520 lagrq_time = atoi(v->value); 11521 else if (!strcasecmp(v->name, "maxregexpire")) 11522 max_reg_expire = atoi(v->value); 11523 else if (!strcasecmp(v->name, "minregexpire")) 11524 min_reg_expire = atoi(v->value); 11525 else if (!strcasecmp(v->name, "bindaddr")) { 11526 if (reload) { 11527 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 11528 } else { 11529 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 11530 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 11531 } else { 11532 if (option_verbose > 1) { 11533 if (strchr(v->value, ':')) 11534 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 11535 else 11536 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 11537 } 11538 if (defaultsockfd < 0) 11539 defaultsockfd = ast_netsock_sockfd(ns); 11540 ast_netsock_unref(ns); 11541 } 11542 } 11543 } else if (!strcasecmp(v->name, "authdebug")) 11544 authdebug = ast_true(v->value); 11545 else if (!strcasecmp(v->name, "encryption")) 11546 iax2_encryption = get_encrypt_methods(v->value); 11547 else if (!strcasecmp(v->name, "notransfer")) { 11548 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11549 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11550 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 11551 } else if (!strcasecmp(v->name, "transfer")) { 11552 if (!strcasecmp(v->value, "mediaonly")) { 11553 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11554 } else if (ast_true(v->value)) { 11555 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11556 } else 11557 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11558 } else if (!strcasecmp(v->name, "codecpriority")) { 11559 if(!strcasecmp(v->value, "caller")) 11560 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 11561 else if(!strcasecmp(v->value, "disabled")) 11562 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11563 else if(!strcasecmp(v->value, "reqonly")) { 11564 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 11565 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11566 } 11567 } else if (!strcasecmp(v->name, "jitterbuffer")) 11568 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 11569 else if (!strcasecmp(v->name, "forcejitterbuffer")) 11570 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 11571 else if (!strcasecmp(v->name, "delayreject")) 11572 delayreject = ast_true(v->value); 11573 else if (!strcasecmp(v->name, "allowfwdownload")) 11574 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 11575 else if (!strcasecmp(v->name, "rtcachefriends")) 11576 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 11577 else if (!strcasecmp(v->name, "rtignoreregexpire")) 11578 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 11579 else if (!strcasecmp(v->name, "rtupdate")) 11580 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 11581 else if (!strcasecmp(v->name, "trunktimestamps")) 11582 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 11583 else if (!strcasecmp(v->name, "rtautoclear")) { 11584 int i = atoi(v->value); 11585 if(i > 0) 11586 global_rtautoclear = i; 11587 else 11588 i = 0; 11589 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 11590 } else if (!strcasecmp(v->name, "trunkfreq")) { 11591 trunkfreq = atoi(v->value); 11592 if (trunkfreq < 10) 11593 trunkfreq = 10; 11594 } else if (!strcasecmp(v->name, "autokill")) { 11595 if (sscanf(v->value, "%30d", &x) == 1) { 11596 if (x >= 0) 11597 autokill = x; 11598 else 11599 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 11600 } else if (ast_true(v->value)) { 11601 autokill = DEFAULT_MAXMS; 11602 } else { 11603 autokill = 0; 11604 } 11605 } else if (!strcasecmp(v->name, "bandwidth")) { 11606 if (!strcasecmp(v->value, "low")) { 11607 capability = IAX_CAPABILITY_LOWBANDWIDTH; 11608 } else if (!strcasecmp(v->value, "medium")) { 11609 capability = IAX_CAPABILITY_MEDBANDWIDTH; 11610 } else if (!strcasecmp(v->value, "high")) { 11611 capability = IAX_CAPABILITY_FULLBANDWIDTH; 11612 } else 11613 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 11614 } else if (!strcasecmp(v->name, "allow")) { 11615 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 11616 } else if (!strcasecmp(v->name, "disallow")) { 11617 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 11618 } else if (!strcasecmp(v->name, "register")) { 11619 iax2_register(v->value, v->lineno); 11620 } else if (!strcasecmp(v->name, "iaxcompat")) { 11621 iaxcompat = ast_true(v->value); 11622 } else if (!strcasecmp(v->name, "regcontext")) { 11623 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 11624 /* Create context if it doesn't exist already */ 11625 if (!ast_context_find(regcontext)) 11626 ast_context_create(NULL, regcontext, "IAX2"); 11627 } else if (!strcasecmp(v->name, "tos")) { 11628 if (ast_str2tos(v->value, &tos)) 11629 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 11630 } else if (!strcasecmp(v->name, "accountcode")) { 11631 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 11632 } else if (!strcasecmp(v->name, "mohinterpret")) { 11633 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 11634 } else if (!strcasecmp(v->name, "mohsuggest")) { 11635 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 11636 } else if (!strcasecmp(v->name, "amaflags")) { 11637 format = ast_cdr_amaflags2int(v->value); 11638 if (format < 0) { 11639 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11640 } else { 11641 amaflags = format; 11642 } 11643 } else if (!strcasecmp(v->name, "language")) { 11644 ast_copy_string(language, v->value, sizeof(language)); 11645 } else if (!strcasecmp(v->name, "maxauthreq")) { 11646 maxauthreq = atoi(v->value); 11647 if (maxauthreq < 0) 11648 maxauthreq = 0; 11649 } else if (!strcasecmp(v->name, "adsi")) { 11650 adsi = ast_true(v->value); 11651 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11652 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 11653 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 11654 } 11655 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 11656 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 11657 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); 11658 } 11659 } else if (!strcasecmp(v->name, "calltokenoptional")) { 11660 if (add_calltoken_ignore(v->value)) { 11661 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 11662 } 11663 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 11664 if (ast_true(v->value)) { 11665 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 11666 } else if (ast_false(v->value)) { 11667 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID); 11668 } else { 11669 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 11670 } 11671 }/*else if (strcasecmp(v->name,"type")) */ 11672 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11673 v = v->next; 11674 } 11675 11676 if (defaultsockfd < 0) { 11677 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 11678 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 11679 } else { 11680 if (option_verbose > 1) 11681 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 11682 defaultsockfd = ast_netsock_sockfd(ns); 11683 ast_netsock_unref(ns); 11684 } 11685 } 11686 if (reload) { 11687 ast_netsock_release(outsock); 11688 outsock = ast_netsock_list_alloc(); 11689 if (!outsock) { 11690 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11691 return -1; 11692 } 11693 ast_netsock_init(outsock); 11694 } 11695 11696 if (min_reg_expire > max_reg_expire) { 11697 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 11698 min_reg_expire, max_reg_expire, max_reg_expire); 11699 min_reg_expire = max_reg_expire; 11700 } 11701 iax2_capability = capability; 11702 11703 ucfg = ast_config_load("users.conf"); 11704 if (ucfg) { 11705 struct ast_variable *gen; 11706 int genhasiax; 11707 int genregisteriax; 11708 const char *hasiax, *registeriax; 11709 11710 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 11711 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 11712 gen = ast_variable_browse(ucfg, "general"); 11713 cat = ast_category_browse(ucfg, NULL); 11714 while (cat) { 11715 if (strcasecmp(cat, "general")) { 11716 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 11717 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 11718 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 11719 /* Start with general parameters, then specific parameters, user and peer */ 11720 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 11721 if (user) { 11722 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11723 user = user_unref(user); 11724 } 11725 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 11726 if (peer) { 11727 if (ast_test_flag(peer, IAX_DYNAMIC)) 11728 reg_source_db(peer); 11729 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11730 peer = peer_unref(peer); 11731 } 11732 } 11733 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 11734 char tmp[256]; 11735 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 11736 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 11737 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 11738 if (!host) 11739 host = ast_variable_retrieve(ucfg, "general", "host"); 11740 if (!username) 11741 username = ast_variable_retrieve(ucfg, "general", "username"); 11742 if (!secret) 11743 secret = ast_variable_retrieve(ucfg, "general", "secret"); 11744 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 11745 if (!ast_strlen_zero(secret)) 11746 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 11747 else 11748 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 11749 iax2_register(tmp, 0); 11750 } 11751 } 11752 } 11753 cat = ast_category_browse(ucfg, cat); 11754 } 11755 ast_config_destroy(ucfg); 11756 } 11757 11758 cat = ast_category_browse(cfg, NULL); 11759 while(cat) { 11760 if (strcasecmp(cat, "general")) { 11761 utype = ast_variable_retrieve(cfg, cat, "type"); 11762 if (!strcasecmp(cat, "callnumberlimits")) { 11763 build_callno_limits(ast_variable_browse(cfg, cat)); 11764 } else if (utype) { 11765 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 11766 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 11767 if (user) { 11768 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11769 user = user_unref(user); 11770 } 11771 } 11772 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 11773 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 11774 if (peer) { 11775 if (ast_test_flag(peer, IAX_DYNAMIC)) 11776 reg_source_db(peer); 11777 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11778 peer = peer_unref(peer); 11779 } 11780 } else if (strcasecmp(utype, "user")) { 11781 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 11782 } 11783 } else 11784 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 11785 } 11786 cat = ast_category_browse(cfg, cat); 11787 } 11788 ast_config_destroy(cfg); 11789 set_timing(); 11790 return 1; 11791 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 11391 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().
11392 { 11393 strcpy(accountcode, ""); 11394 strcpy(language, ""); 11395 strcpy(mohinterpret, "default"); 11396 strcpy(mohsuggest, ""); 11397 amaflags = 0; 11398 delayreject = 0; 11399 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 11400 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11401 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 11402 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 11403 delete_users(); 11404 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 11405 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 11406 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1925 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().
01926 { 01927 uint16_t limit = global_maxcallno; 01928 struct addr_range *addr_range; 01929 struct sockaddr_in sin = { 01930 .sin_addr.s_addr = peercnt->addr, 01931 }; 01932 01933 01934 if (peercnt->reg && peercnt->limit) { 01935 return; /* this peercnt has a custom limit set by a registration */ 01936 } 01937 01938 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 01939 limit = addr_range->limit; 01940 if (option_debug) { 01941 ast_log(LOG_DEBUG, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 01942 } 01943 ao2_ref(addr_range, -1); 01944 } 01945 01946 peercnt->limit = limit; 01947 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1953 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, option_debug, and set_peercnt_limit().
Referenced by reload_config().
01954 { 01955 struct peercnt *peercnt = obj; 01956 01957 set_peercnt_limit(peercnt); 01958 if (option_debug) { 01959 ast_log(LOG_DEBUG, "Reset limits for peercnts table\n"); 01960 } 01961 return 0; 01962 }
static void set_timing | ( | void | ) | [static] |
Definition at line 11376 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
11377 { 11378 #ifdef HAVE_DAHDI 11379 int bs = trunkfreq * 8; 11380 if (timingfd > -1) { 11381 if ( 11382 #ifdef DAHDI_TIMERACK 11383 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 11384 #endif 11385 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 11386 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 11387 } 11388 #endif 11389 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 867 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().
00868 { 00869 ast_mutex_lock(lock); 00870 ast_cond_signal(cond); 00871 ast_mutex_unlock(lock); 00872 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 8365 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_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, 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_lock_owner(), 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, ast_channel::lock, 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(), and iax2_process_thread().
08366 { 08367 struct sockaddr_in sin; 08368 int res; 08369 int updatehistory=1; 08370 int new = NEW_PREVENT; 08371 void *ptr; 08372 int dcallno = 0; 08373 char decrypted = 0; 08374 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 08375 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 08376 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 08377 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 08378 struct ast_iax2_meta_trunk_hdr *mth; 08379 struct ast_iax2_meta_trunk_entry *mte; 08380 struct ast_iax2_meta_trunk_mini *mtm; 08381 struct iax_frame *fr; 08382 struct iax_frame *cur; 08383 struct ast_frame f = { 0, }; 08384 struct ast_channel *c; 08385 struct iax2_dpcache *dp; 08386 struct iax2_peer *peer; 08387 struct iax2_trunk_peer *tpeer; 08388 struct timeval rxtrunktime; 08389 struct iax_ies ies; 08390 struct iax_ie_data ied0, ied1; 08391 int format; 08392 int fd; 08393 int exists; 08394 int minivid = 0; 08395 unsigned int ts; 08396 char empty[32]=""; /* Safety measure */ 08397 struct iax_frame *duped_fr; 08398 char host_pref_buf[128]; 08399 char caller_pref_buf[128]; 08400 struct ast_codec_pref pref; 08401 char *using_prefs = "mine"; 08402 08403 /* allocate an iax_frame with 4096 bytes of data buffer */ 08404 fr = alloca(sizeof(*fr) + 4096); 08405 memset(fr, 0, sizeof(*fr)); 08406 fr->afdatalen = 4096; /* From alloca() above */ 08407 08408 /* Copy frequently used parameters to the stack */ 08409 res = thread->buf_len; 08410 fd = thread->iofd; 08411 memcpy(&sin, &thread->iosin, sizeof(sin)); 08412 08413 if (res < sizeof(*mh)) { 08414 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 08415 return 1; 08416 } 08417 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 08418 if (res < sizeof(*vh)) { 08419 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)); 08420 return 1; 08421 } 08422 08423 /* This is a video frame, get call number */ 08424 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 08425 minivid = 1; 08426 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 08427 unsigned char metatype; 08428 08429 if (res < sizeof(*meta)) { 08430 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)); 08431 return 1; 08432 } 08433 08434 /* This is a meta header */ 08435 switch(meta->metacmd) { 08436 case IAX_META_TRUNK: 08437 if (res < (sizeof(*meta) + sizeof(*mth))) { 08438 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 08439 sizeof(*meta) + sizeof(*mth)); 08440 return 1; 08441 } 08442 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 08443 ts = ntohl(mth->ts); 08444 metatype = meta->cmddata; 08445 res -= (sizeof(*meta) + sizeof(*mth)); 08446 ptr = mth->data; 08447 tpeer = find_tpeer(&sin, fd); 08448 if (!tpeer) { 08449 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)); 08450 return 1; 08451 } 08452 tpeer->trunkact = ast_tvnow(); 08453 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 08454 tpeer->rxtrunktime = tpeer->trunkact; 08455 rxtrunktime = tpeer->rxtrunktime; 08456 ast_mutex_unlock(&tpeer->lock); 08457 while(res >= sizeof(*mte)) { 08458 /* Process channels */ 08459 unsigned short callno, trunked_ts, len; 08460 08461 if (metatype == IAX_META_TRUNK_MINI) { 08462 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 08463 ptr += sizeof(*mtm); 08464 res -= sizeof(*mtm); 08465 len = ntohs(mtm->len); 08466 callno = ntohs(mtm->mini.callno); 08467 trunked_ts = ntohs(mtm->mini.ts); 08468 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 08469 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 08470 ptr += sizeof(*mte); 08471 res -= sizeof(*mte); 08472 len = ntohs(mte->len); 08473 callno = ntohs(mte->callno); 08474 trunked_ts = 0; 08475 } else { 08476 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 08477 break; 08478 } 08479 /* Stop if we don't have enough data */ 08480 if (len > res) 08481 break; 08482 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 08483 if (fr->callno) { 08484 /* If it's a valid call, deliver the contents. If not, we 08485 drop it, since we don't have a scallno to use for an INVAL */ 08486 /* Process as a mini frame */ 08487 memset(&f, 0, sizeof(f)); 08488 f.frametype = AST_FRAME_VOICE; 08489 if (iaxs[fr->callno]) { 08490 if (iaxs[fr->callno]->voiceformat > 0) { 08491 f.subclass = iaxs[fr->callno]->voiceformat; 08492 f.datalen = len; 08493 if (f.datalen >= 0) { 08494 if (f.datalen) 08495 f.data = ptr; 08496 if(trunked_ts) { 08497 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 08498 } else 08499 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 08500 /* Don't pass any packets until we're started */ 08501 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08502 /* Common things */ 08503 f.src = "IAX2"; 08504 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 08505 f.samples = ast_codec_get_samples(&f); 08506 iax_frame_wrap(fr, &f); 08507 duped_fr = iaxfrdup2(fr); 08508 if (duped_fr) { 08509 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 08510 } 08511 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 08512 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08513 iaxs[fr->callno]->last = fr->ts; 08514 #if 1 08515 if (option_debug && iaxdebug) 08516 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08517 #endif 08518 } 08519 } 08520 } else { 08521 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08522 } 08523 } else { 08524 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 08525 iax2_vnak(fr->callno); 08526 } 08527 } 08528 ast_mutex_unlock(&iaxsl[fr->callno]); 08529 } 08530 ptr += len; 08531 res -= len; 08532 } 08533 08534 } 08535 return 1; 08536 } 08537 08538 #ifdef DEBUG_SUPPORT 08539 if (iaxdebug && (res >= sizeof(*fh))) 08540 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 08541 #endif 08542 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08543 if (res < sizeof(*fh)) { 08544 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)); 08545 return 1; 08546 } 08547 08548 /* Get the destination call number */ 08549 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 08550 08551 08552 /* check to make sure this full frame isn't encrypted before we attempt 08553 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 08554 * callno is not found here, that just means one hasn't been allocated for 08555 * this connection yet. */ 08556 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 08557 ast_mutex_lock(&iaxsl[fr->callno]); 08558 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 08559 if (decrypt_frame(fr->callno, fh, &f, &res)) { 08560 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 08561 ast_mutex_unlock(&iaxsl[fr->callno]); 08562 return 1; 08563 } 08564 decrypted = 1; 08565 } 08566 ast_mutex_unlock(&iaxsl[fr->callno]); 08567 } 08568 08569 /* Retrieve the type and subclass */ 08570 f.frametype = fh->type; 08571 if (f.frametype == AST_FRAME_VIDEO) { 08572 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 08573 } else { 08574 f.subclass = uncompress_subclass(fh->csub); 08575 } 08576 08577 /* Deal with POKE/PONG without allocating a callno */ 08578 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 08579 /* Reply back with a PONG, but don't care about the result. */ 08580 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08581 return 1; 08582 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 08583 /* Ignore */ 08584 return 1; 08585 } 08586 08587 f.datalen = res - sizeof(*fh); 08588 if (f.datalen) { 08589 if (f.frametype == AST_FRAME_IAX) { 08590 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 08591 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 08592 return 1; 08593 } 08594 f.data = NULL; 08595 f.datalen = 0; 08596 } else { 08597 f.data = thread->buf + sizeof(*fh); 08598 memset(&ies, 0, sizeof(ies)); 08599 } 08600 } else { 08601 if (f.frametype == AST_FRAME_IAX) 08602 f.data = NULL; 08603 else 08604 f.data = empty; 08605 memset(&ies, 0, sizeof(ies)); 08606 } 08607 08608 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 08609 /* only set NEW_ALLOW if calltoken checks out */ 08610 if (handle_call_token(fh, &ies, &sin, fd)) { 08611 return 1; 08612 } 08613 08614 if (ies.calltoken && ies.calltokendata) { 08615 /* if we've gotten this far, and the calltoken ie data exists, 08616 * then calltoken validation _MUST_ have taken place. If calltoken 08617 * data is provided, it is always validated reguardless of any 08618 * calltokenoptional or requirecalltoken options */ 08619 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 08620 } else { 08621 new = NEW_ALLOW; 08622 } 08623 } 08624 } else { 08625 /* Don't know anything about it yet */ 08626 f.frametype = AST_FRAME_NULL; 08627 f.subclass = 0; 08628 } 08629 08630 if (!fr->callno) { 08631 int check_dcallno = 0; 08632 08633 /* 08634 * We enforce accurate destination call numbers for ACKs. This forces the other 08635 * end to know the destination call number before call setup can complete. 08636 * 08637 * Discussed in the following thread: 08638 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 08639 */ 08640 08641 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) { 08642 check_dcallno = 1; 08643 } 08644 08645 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 08646 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 08647 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08648 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 08649 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08650 } 08651 return 1; 08652 } 08653 } 08654 08655 if (fr->callno > 0) 08656 ast_mutex_lock(&iaxsl[fr->callno]); 08657 08658 if (!fr->callno || !iaxs[fr->callno]) { 08659 /* A call arrived for a nonexistent destination. Unless it's an "inval" 08660 frame, reply with an inval */ 08661 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08662 /* We can only raw hangup control frames */ 08663 if (((f.subclass != IAX_COMMAND_INVAL) && 08664 (f.subclass != IAX_COMMAND_TXCNT) && 08665 (f.subclass != IAX_COMMAND_TXACC) && 08666 (f.subclass != IAX_COMMAND_FWDOWNL))|| 08667 (f.frametype != AST_FRAME_IAX)) 08668 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 08669 fd); 08670 } 08671 if (fr->callno > 0) 08672 ast_mutex_unlock(&iaxsl[fr->callno]); 08673 return 1; 08674 } 08675 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 08676 if (decrypt_frame(fr->callno, fh, &f, &res)) { 08677 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 08678 ast_mutex_unlock(&iaxsl[fr->callno]); 08679 return 1; 08680 } 08681 decrypted = 1; 08682 } 08683 #ifdef DEBUG_SUPPORT 08684 if (decrypted && iaxdebug) { 08685 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 08686 } 08687 #endif 08688 08689 /* count this frame */ 08690 iaxs[fr->callno]->frames_received++; 08691 08692 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 08693 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 08694 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 08695 unsigned short new_peercallno; 08696 08697 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 08698 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 08699 if (iaxs[fr->callno]->peercallno) { 08700 remove_by_peercallno(iaxs[fr->callno]); 08701 } 08702 iaxs[fr->callno]->peercallno = new_peercallno; 08703 store_by_peercallno(iaxs[fr->callno]); 08704 } 08705 } 08706 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08707 if (option_debug && iaxdebug) 08708 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 08709 /* Check if it's out of order (and not an ACK or INVAL) */ 08710 fr->oseqno = fh->oseqno; 08711 fr->iseqno = fh->iseqno; 08712 fr->ts = ntohl(fh->ts); 08713 #ifdef IAXTESTS 08714 if (test_resync) { 08715 if (option_debug) 08716 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 08717 fr->ts += test_resync; 08718 } 08719 #endif /* IAXTESTS */ 08720 #if 0 08721 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 08722 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 08723 (f.subclass == IAX_COMMAND_NEW || 08724 f.subclass == IAX_COMMAND_AUTHREQ || 08725 f.subclass == IAX_COMMAND_ACCEPT || 08726 f.subclass == IAX_COMMAND_REJECT)) ) ) 08727 #endif 08728 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 08729 updatehistory = 0; 08730 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 08731 (iaxs[fr->callno]->iseqno || 08732 ((f.subclass != IAX_COMMAND_TXCNT) && 08733 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08734 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08735 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08736 (f.subclass != IAX_COMMAND_TXACC)) || 08737 (f.frametype != AST_FRAME_IAX))) { 08738 if ( 08739 ((f.subclass != IAX_COMMAND_ACK) && 08740 (f.subclass != IAX_COMMAND_INVAL) && 08741 (f.subclass != IAX_COMMAND_TXCNT) && 08742 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08743 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08744 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08745 (f.subclass != IAX_COMMAND_TXACC) && 08746 (f.subclass != IAX_COMMAND_VNAK)) || 08747 (f.frametype != AST_FRAME_IAX)) { 08748 /* If it's not an ACK packet, it's out of order. */ 08749 if (option_debug) 08750 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 08751 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 08752 /* Check to see if we need to request retransmission, 08753 * and take sequence number wraparound into account */ 08754 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 08755 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 08756 if ((f.frametype != AST_FRAME_IAX) || 08757 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 08758 if (option_debug) 08759 ast_log(LOG_DEBUG, "Acking anyway\n"); 08760 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 08761 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 08762 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08763 } 08764 } else { 08765 /* Send a VNAK requesting retransmission */ 08766 iax2_vnak(fr->callno); 08767 } 08768 ast_mutex_unlock(&iaxsl[fr->callno]); 08769 return 1; 08770 } 08771 } else { 08772 /* Increment unless it's an ACK or VNAK */ 08773 if (((f.subclass != IAX_COMMAND_ACK) && 08774 (f.subclass != IAX_COMMAND_INVAL) && 08775 (f.subclass != IAX_COMMAND_TXCNT) && 08776 (f.subclass != IAX_COMMAND_TXACC) && 08777 (f.subclass != IAX_COMMAND_VNAK)) || 08778 (f.frametype != AST_FRAME_IAX)) 08779 iaxs[fr->callno]->iseqno++; 08780 } 08781 /* Ensure text frames are NULL-terminated */ 08782 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 08783 if (res < thread->buf_size) 08784 thread->buf[res++] = '\0'; 08785 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 08786 thread->buf[res - 1] = '\0'; 08787 } 08788 08789 /* Handle implicit ACKing unless this is an INVAL, and only if this is 08790 from the real peer, not the transfer peer */ 08791 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08792 ((f.subclass != IAX_COMMAND_INVAL) || 08793 (f.frametype != AST_FRAME_IAX))) { 08794 unsigned char x; 08795 int call_to_destroy; 08796 /* XXX This code is not very efficient. Surely there is a better way which still 08797 properly handles boundary conditions? XXX */ 08798 /* First we have to qualify that the ACKed value is within our window */ 08799 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 08800 if (fr->iseqno == x) 08801 break; 08802 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 08803 /* The acknowledgement is within our window. Time to acknowledge everything 08804 that it says to */ 08805 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 08806 /* Ack the packet with the given timestamp */ 08807 if (option_debug && iaxdebug) 08808 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 08809 call_to_destroy = 0; 08810 AST_LIST_LOCK(&iaxq.queue); 08811 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08812 /* If it's our call, and our timestamp, mark -1 retries */ 08813 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 08814 cur->retries = -1; 08815 /* Destroy call if this is the end */ 08816 if (cur->final) 08817 call_to_destroy = fr->callno; 08818 } 08819 } 08820 AST_LIST_UNLOCK(&iaxq.queue); 08821 if (call_to_destroy) { 08822 if (iaxdebug && option_debug) 08823 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 08824 ast_mutex_lock(&iaxsl[call_to_destroy]); 08825 iax2_destroy(call_to_destroy); 08826 ast_mutex_unlock(&iaxsl[call_to_destroy]); 08827 } 08828 } 08829 /* Note how much we've received acknowledgement for */ 08830 if (iaxs[fr->callno]) 08831 iaxs[fr->callno]->rseqno = fr->iseqno; 08832 else { 08833 /* Stop processing now */ 08834 ast_mutex_unlock(&iaxsl[fr->callno]); 08835 return 1; 08836 } 08837 } else if (option_debug) 08838 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 08839 } 08840 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08841 ((f.frametype != AST_FRAME_IAX) || 08842 ((f.subclass != IAX_COMMAND_TXACC) && 08843 (f.subclass != IAX_COMMAND_TXCNT)))) { 08844 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 08845 ast_mutex_unlock(&iaxsl[fr->callno]); 08846 return 1; 08847 } 08848 08849 /* when we receive the first full frame for a new incoming channel, 08850 it is safe to start the PBX on the channel because we have now 08851 completed a 3-way handshake with the peer */ 08852 if ((f.frametype == AST_FRAME_VOICE) || 08853 (f.frametype == AST_FRAME_VIDEO) || 08854 (f.frametype == AST_FRAME_IAX)) { 08855 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 08856 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 08857 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 08858 ast_mutex_unlock(&iaxsl[fr->callno]); 08859 return 1; 08860 } 08861 } 08862 } 08863 08864 /* once we receive our first IAX Full Frame that is not CallToken related, send all 08865 * queued signaling frames that were being held. */ 08866 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 08867 send_signaling(iaxs[fr->callno]); 08868 } 08869 08870 if (f.frametype == AST_FRAME_VOICE) { 08871 if (f.subclass != iaxs[fr->callno]->voiceformat) { 08872 iaxs[fr->callno]->voiceformat = f.subclass; 08873 if (option_debug) 08874 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 08875 if (iaxs[fr->callno]->owner) { 08876 iax2_lock_owner(fr->callno); 08877 if (iaxs[fr->callno]) { 08878 if (iaxs[fr->callno]->owner) { 08879 int orignative; 08880 08881 orignative = iaxs[fr->callno]->owner->nativeformats; 08882 iaxs[fr->callno]->owner->nativeformats = f.subclass; 08883 if (iaxs[fr->callno]->owner->readformat) 08884 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08885 iaxs[fr->callno]->owner->nativeformats = orignative; 08886 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08887 } 08888 } else { 08889 if (option_debug) 08890 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 08891 ast_mutex_unlock(&iaxsl[fr->callno]); 08892 return 1; 08893 } 08894 } 08895 } 08896 } 08897 if (f.frametype == AST_FRAME_VIDEO) { 08898 if (f.subclass != iaxs[fr->callno]->videoformat) { 08899 if (option_debug) 08900 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 08901 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 08902 } 08903 } 08904 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 08905 if (f.subclass == AST_CONTROL_BUSY) { 08906 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 08907 } else if (f.subclass == AST_CONTROL_CONGESTION) { 08908 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 08909 } 08910 } 08911 if (f.frametype == AST_FRAME_IAX) { 08912 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 08913 /* Handle the IAX pseudo frame itself */ 08914 if (option_debug && iaxdebug) { 08915 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 08916 } 08917 08918 /* Update last ts unless the frame's timestamp originated with us. */ 08919 if (iaxs[fr->callno]->last < fr->ts && 08920 f.subclass != IAX_COMMAND_ACK && 08921 f.subclass != IAX_COMMAND_PONG && 08922 f.subclass != IAX_COMMAND_LAGRP) { 08923 iaxs[fr->callno]->last = fr->ts; 08924 if (option_debug && iaxdebug) { 08925 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08926 } 08927 } 08928 iaxs[fr->callno]->last_iax_message = f.subclass; 08929 if (!iaxs[fr->callno]->first_iax_message) { 08930 iaxs[fr->callno]->first_iax_message = f.subclass; 08931 } 08932 switch(f.subclass) { 08933 case IAX_COMMAND_ACK: 08934 /* Do nothing */ 08935 break; 08936 case IAX_COMMAND_QUELCH: 08937 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08938 /* Generate Manager Hold event, if necessary*/ 08939 if (iaxs[fr->callno]->owner) { 08940 manager_event(EVENT_FLAG_CALL, "Hold", 08941 "Channel: %s\r\n" 08942 "Uniqueid: %s\r\n", 08943 iaxs[fr->callno]->owner->name, 08944 iaxs[fr->callno]->owner->uniqueid); 08945 } 08946 08947 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 08948 if (ies.musiconhold) { 08949 iax2_lock_owner(fr->callno); 08950 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 08951 break; 08952 } 08953 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 08954 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 08955 08956 /* 08957 * We already hold the owner lock so we do not 08958 * need to check iaxs[fr->callno] after it returns. 08959 */ 08960 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 08961 S_OR(mohsuggest, NULL), 08962 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 08963 } 08964 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08965 } 08966 } 08967 break; 08968 case IAX_COMMAND_UNQUELCH: 08969 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08970 iax2_lock_owner(fr->callno); 08971 if (!iaxs[fr->callno]) { 08972 break; 08973 } 08974 /* Generate Manager Unhold event, if necessary */ 08975 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 08976 manager_event(EVENT_FLAG_CALL, "Unhold", 08977 "Channel: %s\r\n" 08978 "Uniqueid: %s\r\n", 08979 iaxs[fr->callno]->owner->name, 08980 iaxs[fr->callno]->owner->uniqueid); 08981 } 08982 08983 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 08984 if (!iaxs[fr->callno]->owner) { 08985 break; 08986 } 08987 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 08988 /* 08989 * We already hold the owner lock so we do not 08990 * need to check iaxs[fr->callno] after it returns. 08991 */ 08992 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 08993 } 08994 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08995 } 08996 break; 08997 case IAX_COMMAND_TXACC: 08998 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 08999 /* Ack the packet with the given timestamp */ 09000 AST_LIST_LOCK(&iaxq.queue); 09001 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09002 /* Cancel any outstanding txcnt's */ 09003 if ((fr->callno == cur->callno) && (cur->transfer)) 09004 cur->retries = -1; 09005 } 09006 AST_LIST_UNLOCK(&iaxq.queue); 09007 memset(&ied1, 0, sizeof(ied1)); 09008 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 09009 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 09010 iaxs[fr->callno]->transferring = TRANSFER_READY; 09011 } 09012 break; 09013 case IAX_COMMAND_NEW: 09014 /* Ignore if it's already up */ 09015 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 09016 break; 09017 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09018 ast_mutex_unlock(&iaxsl[fr->callno]); 09019 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09020 ast_mutex_lock(&iaxsl[fr->callno]); 09021 if (!iaxs[fr->callno]) { 09022 ast_mutex_unlock(&iaxsl[fr->callno]); 09023 return 1; 09024 } 09025 } 09026 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 09027 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 09028 int new_callno; 09029 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 09030 fr->callno = new_callno; 09031 } 09032 /* For security, always ack immediately */ 09033 if (delayreject) 09034 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09035 if (check_access(fr->callno, &sin, &ies)) { 09036 /* They're not allowed on */ 09037 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09038 if (authdebug) 09039 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); 09040 break; 09041 } 09042 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09043 const char *context, *exten, *cid_num; 09044 09045 context = ast_strdupa(iaxs[fr->callno]->context); 09046 exten = ast_strdupa(iaxs[fr->callno]->exten); 09047 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 09048 09049 /* This might re-enter the IAX code and need the lock */ 09050 ast_mutex_unlock(&iaxsl[fr->callno]); 09051 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 09052 ast_mutex_lock(&iaxsl[fr->callno]); 09053 09054 if (!iaxs[fr->callno]) { 09055 ast_mutex_unlock(&iaxsl[fr->callno]); 09056 return 1; 09057 } 09058 } else 09059 exists = 0; 09060 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 09061 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09062 memset(&ied0, 0, sizeof(ied0)); 09063 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09064 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09065 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09066 if (!iaxs[fr->callno]) { 09067 ast_mutex_unlock(&iaxsl[fr->callno]); 09068 return 1; 09069 } 09070 if (authdebug) 09071 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); 09072 } else { 09073 /* Select an appropriate format */ 09074 09075 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09076 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09077 using_prefs = "reqonly"; 09078 } else { 09079 using_prefs = "disabled"; 09080 } 09081 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09082 memset(&pref, 0, sizeof(pref)); 09083 strcpy(caller_pref_buf, "disabled"); 09084 strcpy(host_pref_buf, "disabled"); 09085 } else { 09086 using_prefs = "mine"; 09087 /* If the information elements are in here... use them */ 09088 if (ies.codec_prefs) 09089 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09090 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09091 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 09092 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09093 pref = iaxs[fr->callno]->rprefs; 09094 using_prefs = "caller"; 09095 } else { 09096 pref = iaxs[fr->callno]->prefs; 09097 } 09098 } else 09099 pref = iaxs[fr->callno]->prefs; 09100 09101 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09102 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09103 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09104 } 09105 if (!format) { 09106 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09107 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09108 if (!format) { 09109 memset(&ied0, 0, sizeof(ied0)); 09110 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09111 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09112 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09113 if (!iaxs[fr->callno]) { 09114 ast_mutex_unlock(&iaxsl[fr->callno]); 09115 return 1; 09116 } 09117 if (authdebug) { 09118 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09119 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); 09120 else 09121 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); 09122 } 09123 } else { 09124 /* Pick one... */ 09125 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09126 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09127 format = 0; 09128 } else { 09129 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09130 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09131 memset(&pref, 0, sizeof(pref)); 09132 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09133 strcpy(caller_pref_buf,"disabled"); 09134 strcpy(host_pref_buf,"disabled"); 09135 } else { 09136 using_prefs = "mine"; 09137 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09138 /* Do the opposite of what we tried above. */ 09139 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09140 pref = iaxs[fr->callno]->prefs; 09141 } else { 09142 pref = iaxs[fr->callno]->rprefs; 09143 using_prefs = "caller"; 09144 } 09145 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 09146 09147 } else /* if no codec_prefs IE do it the old way */ 09148 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09149 } 09150 } 09151 09152 if (!format) { 09153 memset(&ied0, 0, sizeof(ied0)); 09154 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09155 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09156 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09157 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09158 if (!iaxs[fr->callno]) { 09159 ast_mutex_unlock(&iaxsl[fr->callno]); 09160 return 1; 09161 } 09162 if (authdebug) 09163 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); 09164 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09165 break; 09166 } 09167 } 09168 } 09169 if (format) { 09170 /* No authentication required, let them in */ 09171 memset(&ied1, 0, sizeof(ied1)); 09172 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09173 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09174 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09175 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09176 if (option_verbose > 2) 09177 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 09178 "%srequested format = %s,\n" 09179 "%srequested prefs = %s,\n" 09180 "%sactual format = %s,\n" 09181 "%shost prefs = %s,\n" 09182 "%spriority = %s\n", 09183 ast_inet_ntoa(sin.sin_addr), 09184 VERBOSE_PREFIX_4, 09185 ast_getformatname(iaxs[fr->callno]->peerformat), 09186 VERBOSE_PREFIX_4, 09187 caller_pref_buf, 09188 VERBOSE_PREFIX_4, 09189 ast_getformatname(format), 09190 VERBOSE_PREFIX_4, 09191 host_pref_buf, 09192 VERBOSE_PREFIX_4, 09193 using_prefs); 09194 09195 iaxs[fr->callno]->chosenformat = format; 09196 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09197 } else { 09198 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09199 /* If this is a TBD call, we're ready but now what... */ 09200 if (option_verbose > 2) 09201 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09202 } 09203 } 09204 } 09205 break; 09206 } 09207 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 09208 merge_encryption(iaxs[fr->callno],ies.encmethods); 09209 else 09210 iaxs[fr->callno]->encmethods = 0; 09211 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 09212 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 09213 if (!iaxs[fr->callno]) { 09214 ast_mutex_unlock(&iaxsl[fr->callno]); 09215 return 1; 09216 } 09217 break; 09218 case IAX_COMMAND_DPREQ: 09219 /* Request status in the dialplan */ 09220 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 09221 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 09222 if (iaxcompat) { 09223 /* Spawn a thread for the lookup */ 09224 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 09225 } else { 09226 /* Just look it up */ 09227 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 09228 } 09229 } 09230 break; 09231 case IAX_COMMAND_HANGUP: 09232 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09233 if (option_debug) 09234 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 09235 /* Set hangup cause according to remote */ 09236 if (ies.causecode && iaxs[fr->callno]->owner) 09237 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09238 /* Send ack immediately, before we destroy */ 09239 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09240 iax2_destroy(fr->callno); 09241 break; 09242 case IAX_COMMAND_REJECT: 09243 /* Set hangup cause according to remote */ 09244 if (ies.causecode && iaxs[fr->callno]->owner) 09245 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09246 09247 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09248 if (iaxs[fr->callno]->owner && authdebug) 09249 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 09250 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 09251 ies.cause ? ies.cause : "<Unknown>"); 09252 if (option_debug) 09253 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 09254 fr->callno); 09255 } 09256 /* Send ack immediately, before we destroy */ 09257 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 09258 fr->ts, NULL, 0, fr->iseqno); 09259 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 09260 iaxs[fr->callno]->error = EPERM; 09261 iax2_destroy(fr->callno); 09262 break; 09263 case IAX_COMMAND_TRANSFER: 09264 { 09265 struct ast_channel *bridged_chan; 09266 struct ast_channel *owner; 09267 09268 iax2_lock_owner(fr->callno); 09269 if (!iaxs[fr->callno]) { 09270 /* Initiating call went away before we could transfer. */ 09271 break; 09272 } 09273 owner = iaxs[fr->callno]->owner; 09274 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 09275 if (bridged_chan && ies.called_number) { 09276 ast_mutex_unlock(&iaxsl[fr->callno]); 09277 09278 /* Set BLINDTRANSFER channel variables */ 09279 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 09280 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 09281 09282 if (!strcmp(ies.called_number, ast_parking_ext())) { 09283 ast_log(LOG_DEBUG, "Parking call '%s'\n", bridged_chan->name); 09284 if (iax_park(bridged_chan, owner)) { 09285 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 09286 bridged_chan->name); 09287 } 09288 ast_mutex_lock(&iaxsl[fr->callno]); 09289 } else { 09290 ast_mutex_lock(&iaxsl[fr->callno]); 09291 09292 if (iaxs[fr->callno]) { 09293 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, 09294 ies.called_number, 1)) { 09295 ast_log(LOG_WARNING, 09296 "Async goto of '%s' to '%s@%s' failed\n", 09297 bridged_chan->name, ies.called_number, 09298 iaxs[fr->callno]->context); 09299 } else { 09300 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", 09301 bridged_chan->name, ies.called_number, 09302 iaxs[fr->callno]->context); 09303 } 09304 } else { 09305 /* Initiating call went away before we could transfer. */ 09306 } 09307 } 09308 } else 09309 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 09310 if (owner) { 09311 ast_mutex_unlock(&owner->lock); 09312 } 09313 09314 break; 09315 } 09316 case IAX_COMMAND_ACCEPT: 09317 /* Ignore if call is already up or needs authentication or is a TBD */ 09318 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 09319 break; 09320 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09321 /* Send ack immediately, before we destroy */ 09322 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09323 iax2_destroy(fr->callno); 09324 break; 09325 } 09326 if (ies.format) { 09327 iaxs[fr->callno]->peerformat = ies.format; 09328 } else { 09329 if (iaxs[fr->callno]->owner) 09330 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 09331 else 09332 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 09333 } 09334 if (option_verbose > 2) 09335 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)); 09336 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 09337 memset(&ied0, 0, sizeof(ied0)); 09338 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09339 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09340 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09341 if (!iaxs[fr->callno]) { 09342 ast_mutex_unlock(&iaxsl[fr->callno]); 09343 return 1; 09344 } 09345 if (authdebug) 09346 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); 09347 } else { 09348 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09349 iax2_lock_owner(fr->callno); 09350 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 09351 /* Switch us to use a compatible format */ 09352 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 09353 if (option_verbose > 2) 09354 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 09355 09356 /* Setup read/write formats properly. */ 09357 if (iaxs[fr->callno]->owner->writeformat) 09358 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 09359 if (iaxs[fr->callno]->owner->readformat) 09360 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09361 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 09362 } 09363 } 09364 if (iaxs[fr->callno]) { 09365 ast_mutex_lock(&dpcache_lock); 09366 dp = iaxs[fr->callno]->dpentries; 09367 while(dp) { 09368 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 09369 iax2_dprequest(dp, fr->callno); 09370 } 09371 dp = dp->peer; 09372 } 09373 ast_mutex_unlock(&dpcache_lock); 09374 } 09375 break; 09376 case IAX_COMMAND_POKE: 09377 /* Send back a pong packet with the original timestamp */ 09378 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 09379 if (!iaxs[fr->callno]) { 09380 ast_mutex_unlock(&iaxsl[fr->callno]); 09381 return 1; 09382 } 09383 break; 09384 case IAX_COMMAND_PING: 09385 { 09386 struct iax_ie_data pingied; 09387 construct_rr(iaxs[fr->callno], &pingied); 09388 /* Send back a pong packet with the original timestamp */ 09389 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 09390 } 09391 break; 09392 case IAX_COMMAND_PONG: 09393 /* Calculate ping time */ 09394 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 09395 /* save RR info */ 09396 save_rr(fr, &ies); 09397 09398 if (iaxs[fr->callno]->peerpoke) { 09399 peer = iaxs[fr->callno]->peerpoke; 09400 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 09401 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 09402 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 09403 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09404 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09405 } 09406 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 09407 if (iaxs[fr->callno]->pingtime > peer->maxms) { 09408 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 09409 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09410 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09411 } 09412 } 09413 peer->lastms = iaxs[fr->callno]->pingtime; 09414 if (peer->smoothing && (peer->lastms > -1)) 09415 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 09416 else if (peer->smoothing && peer->lastms < 0) 09417 peer->historicms = (0 + peer->historicms) / 2; 09418 else 09419 peer->historicms = iaxs[fr->callno]->pingtime; 09420 09421 /* Remove scheduled iax2_poke_noanswer */ 09422 if (peer->pokeexpire > -1) { 09423 if (!ast_sched_del(sched, peer->pokeexpire)) { 09424 peer_unref(peer); 09425 peer->pokeexpire = -1; 09426 } 09427 } 09428 /* Schedule the next cycle */ 09429 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 09430 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 09431 else 09432 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 09433 if (peer->pokeexpire == -1) 09434 peer_unref(peer); 09435 /* and finally send the ack */ 09436 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09437 /* And wrap up the qualify call */ 09438 iax2_destroy(fr->callno); 09439 peer->callno = 0; 09440 if (option_debug) 09441 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 09442 } 09443 break; 09444 case IAX_COMMAND_LAGRQ: 09445 case IAX_COMMAND_LAGRP: 09446 f.src = "LAGRQ"; 09447 f.mallocd = 0; 09448 f.offset = 0; 09449 f.samples = 0; 09450 iax_frame_wrap(fr, &f); 09451 if(f.subclass == IAX_COMMAND_LAGRQ) { 09452 /* Received a LAGRQ - echo back a LAGRP */ 09453 fr->af.subclass = IAX_COMMAND_LAGRP; 09454 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 09455 } else { 09456 /* Received LAGRP in response to our LAGRQ */ 09457 unsigned int ts; 09458 /* This is a reply we've been given, actually measure the difference */ 09459 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 09460 iaxs[fr->callno]->lag = ts - fr->ts; 09461 if (option_debug && iaxdebug) 09462 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 09463 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 09464 } 09465 break; 09466 case IAX_COMMAND_AUTHREQ: 09467 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09468 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>"); 09469 break; 09470 } 09471 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 09472 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 09473 .subclass = AST_CONTROL_HANGUP, 09474 }; 09475 ast_log(LOG_WARNING, 09476 "I don't know how to authenticate %s to %s\n", 09477 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 09478 iax2_queue_frame(fr->callno, &hangup_fr); 09479 } 09480 if (!iaxs[fr->callno]) { 09481 ast_mutex_unlock(&iaxsl[fr->callno]); 09482 return 1; 09483 } 09484 break; 09485 case IAX_COMMAND_AUTHREP: 09486 /* For security, always ack immediately */ 09487 if (delayreject) 09488 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09489 /* Ignore once we've started */ 09490 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09491 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>"); 09492 break; 09493 } 09494 if (authenticate_verify(iaxs[fr->callno], &ies)) { 09495 if (authdebug) 09496 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); 09497 memset(&ied0, 0, sizeof(ied0)); 09498 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09499 break; 09500 } 09501 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09502 /* This might re-enter the IAX code and need the lock */ 09503 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 09504 } else 09505 exists = 0; 09506 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09507 if (authdebug) 09508 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); 09509 memset(&ied0, 0, sizeof(ied0)); 09510 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09511 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09512 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09513 if (!iaxs[fr->callno]) { 09514 ast_mutex_unlock(&iaxsl[fr->callno]); 09515 return 1; 09516 } 09517 } else { 09518 /* Select an appropriate format */ 09519 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09520 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09521 using_prefs = "reqonly"; 09522 } else { 09523 using_prefs = "disabled"; 09524 } 09525 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09526 memset(&pref, 0, sizeof(pref)); 09527 strcpy(caller_pref_buf, "disabled"); 09528 strcpy(host_pref_buf, "disabled"); 09529 } else { 09530 using_prefs = "mine"; 09531 if (ies.codec_prefs) 09532 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09533 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09534 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09535 pref = iaxs[fr->callno]->rprefs; 09536 using_prefs = "caller"; 09537 } else { 09538 pref = iaxs[fr->callno]->prefs; 09539 } 09540 } else /* if no codec_prefs IE do it the old way */ 09541 pref = iaxs[fr->callno]->prefs; 09542 09543 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09544 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09545 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09546 } 09547 if (!format) { 09548 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09549 if (option_debug) 09550 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); 09551 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09552 } 09553 if (!format) { 09554 if (authdebug) { 09555 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09556 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); 09557 else 09558 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); 09559 } 09560 memset(&ied0, 0, sizeof(ied0)); 09561 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09562 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09563 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09564 if (!iaxs[fr->callno]) { 09565 ast_mutex_unlock(&iaxsl[fr->callno]); 09566 return 1; 09567 } 09568 } else { 09569 /* Pick one... */ 09570 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09571 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09572 format = 0; 09573 } else { 09574 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09575 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09576 memset(&pref, 0, sizeof(pref)); 09577 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 09578 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09579 strcpy(caller_pref_buf,"disabled"); 09580 strcpy(host_pref_buf,"disabled"); 09581 } else { 09582 using_prefs = "mine"; 09583 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09584 /* Do the opposite of what we tried above. */ 09585 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09586 pref = iaxs[fr->callno]->prefs; 09587 } else { 09588 pref = iaxs[fr->callno]->rprefs; 09589 using_prefs = "caller"; 09590 } 09591 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 09592 } else /* if no codec_prefs IE do it the old way */ 09593 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09594 } 09595 } 09596 if (!format) { 09597 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09598 if (authdebug) { 09599 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09600 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); 09601 else 09602 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); 09603 } 09604 memset(&ied0, 0, sizeof(ied0)); 09605 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09606 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09607 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09608 if (!iaxs[fr->callno]) { 09609 ast_mutex_unlock(&iaxsl[fr->callno]); 09610 return 1; 09611 } 09612 } 09613 } 09614 } 09615 if (format) { 09616 /* Authentication received */ 09617 memset(&ied1, 0, sizeof(ied1)); 09618 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09619 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09620 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09621 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09622 if (option_verbose > 2) 09623 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 09624 "%srequested format = %s,\n" 09625 "%srequested prefs = %s,\n" 09626 "%sactual format = %s,\n" 09627 "%shost prefs = %s,\n" 09628 "%spriority = %s\n", 09629 ast_inet_ntoa(sin.sin_addr), 09630 VERBOSE_PREFIX_4, 09631 ast_getformatname(iaxs[fr->callno]->peerformat), 09632 VERBOSE_PREFIX_4, 09633 caller_pref_buf, 09634 VERBOSE_PREFIX_4, 09635 ast_getformatname(format), 09636 VERBOSE_PREFIX_4, 09637 host_pref_buf, 09638 VERBOSE_PREFIX_4, 09639 using_prefs); 09640 09641 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09642 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 09643 iax2_destroy(fr->callno); 09644 } else { 09645 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09646 /* If this is a TBD call, we're ready but now what... */ 09647 if (option_verbose > 2) 09648 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09649 } 09650 } 09651 } 09652 break; 09653 case IAX_COMMAND_DIAL: 09654 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 09655 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09656 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 09657 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 09658 if (authdebug) 09659 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); 09660 memset(&ied0, 0, sizeof(ied0)); 09661 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09662 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09663 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09664 if (!iaxs[fr->callno]) { 09665 ast_mutex_unlock(&iaxsl[fr->callno]); 09666 return 1; 09667 } 09668 } else { 09669 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09670 if (option_verbose > 2) 09671 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 09672 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09673 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 09674 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 09675 iax2_destroy(fr->callno); 09676 } 09677 } 09678 break; 09679 case IAX_COMMAND_INVAL: 09680 iaxs[fr->callno]->error = ENOTCONN; 09681 if (option_debug) 09682 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 09683 iax2_destroy(fr->callno); 09684 if (option_debug) 09685 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 09686 break; 09687 case IAX_COMMAND_VNAK: 09688 if (option_debug) 09689 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 09690 /* Force retransmission */ 09691 vnak_retransmit(fr->callno, fr->iseqno); 09692 break; 09693 case IAX_COMMAND_REGREQ: 09694 case IAX_COMMAND_REGREL: 09695 /* For security, always ack immediately */ 09696 if (delayreject) 09697 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09698 if (register_verify(fr->callno, &sin, &ies)) { 09699 if (!iaxs[fr->callno]) { 09700 ast_mutex_unlock(&iaxsl[fr->callno]); 09701 return 1; 09702 } 09703 /* Send delayed failure */ 09704 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 09705 break; 09706 } 09707 if (!iaxs[fr->callno]) { 09708 ast_mutex_unlock(&iaxsl[fr->callno]); 09709 return 1; 09710 } 09711 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 09712 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 09713 09714 if (f.subclass == IAX_COMMAND_REGREL) 09715 memset(&sin, 0, sizeof(sin)); 09716 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 09717 ast_log(LOG_WARNING, "Registry error\n"); 09718 if (!iaxs[fr->callno]) { 09719 ast_mutex_unlock(&iaxsl[fr->callno]); 09720 return 1; 09721 } 09722 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09723 ast_mutex_unlock(&iaxsl[fr->callno]); 09724 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09725 ast_mutex_lock(&iaxsl[fr->callno]); 09726 if (!iaxs[fr->callno]) { 09727 ast_mutex_unlock(&iaxsl[fr->callno]); 09728 return 1; 09729 } 09730 } 09731 break; 09732 } 09733 registry_authrequest(fr->callno); 09734 if (!iaxs[fr->callno]) { 09735 ast_mutex_unlock(&iaxsl[fr->callno]); 09736 return 1; 09737 } 09738 break; 09739 case IAX_COMMAND_REGACK: 09740 if (iax2_ack_registry(&ies, &sin, fr->callno)) 09741 ast_log(LOG_WARNING, "Registration failure\n"); 09742 /* Send ack immediately, before we destroy */ 09743 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09744 iax2_destroy(fr->callno); 09745 break; 09746 case IAX_COMMAND_REGREJ: 09747 if (iaxs[fr->callno]->reg) { 09748 if (authdebug) { 09749 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)); 09750 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>"); 09751 } 09752 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 09753 } 09754 /* Send ack immediately, before we destroy */ 09755 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09756 iax2_destroy(fr->callno); 09757 break; 09758 case IAX_COMMAND_REGAUTH: 09759 /* Authentication request */ 09760 if (registry_rerequest(&ies, fr->callno, &sin)) { 09761 memset(&ied0, 0, sizeof(ied0)); 09762 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 09763 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09764 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09765 if (!iaxs[fr->callno]) { 09766 ast_mutex_unlock(&iaxsl[fr->callno]); 09767 return 1; 09768 } 09769 } 09770 break; 09771 case IAX_COMMAND_TXREJ: 09772 iaxs[fr->callno]->transferring = 0; 09773 if (option_verbose > 2) 09774 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09775 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 09776 if (iaxs[fr->callno]->bridgecallno) { 09777 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 09778 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 09779 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 09780 } 09781 } 09782 break; 09783 case IAX_COMMAND_TXREADY: 09784 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 09785 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 09786 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 09787 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 09788 else 09789 iaxs[fr->callno]->transferring = TRANSFER_READY; 09790 if (option_verbose > 2) 09791 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09792 if (iaxs[fr->callno]->bridgecallno) { 09793 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 09794 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 09795 /* They're both ready, now release them. */ 09796 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 09797 if (option_verbose > 2) 09798 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09799 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09800 09801 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 09802 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 09803 09804 memset(&ied0, 0, sizeof(ied0)); 09805 memset(&ied1, 0, sizeof(ied1)); 09806 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09807 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09808 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 09809 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 09810 } else { 09811 if (option_verbose > 2) 09812 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09813 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09814 09815 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 09816 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 09817 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 09818 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09819 09820 /* Stop doing lag & ping requests */ 09821 stop_stuff(fr->callno); 09822 stop_stuff(iaxs[fr->callno]->bridgecallno); 09823 09824 memset(&ied0, 0, sizeof(ied0)); 09825 memset(&ied1, 0, sizeof(ied1)); 09826 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09827 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09828 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 09829 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 09830 } 09831 09832 } 09833 } 09834 } 09835 break; 09836 case IAX_COMMAND_TXREQ: 09837 try_transfer(iaxs[fr->callno], &ies); 09838 break; 09839 case IAX_COMMAND_TXCNT: 09840 if (iaxs[fr->callno]->transferring) 09841 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 09842 break; 09843 case IAX_COMMAND_TXREL: 09844 /* Send ack immediately, rather than waiting until we've changed addresses */ 09845 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09846 complete_transfer(fr->callno, &ies); 09847 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 09848 break; 09849 case IAX_COMMAND_TXMEDIA: 09850 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 09851 AST_LIST_LOCK(&iaxq.queue); 09852 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09853 /* Cancel any outstanding frames and start anew */ 09854 if ((fr->callno == cur->callno) && (cur->transfer)) { 09855 cur->retries = -1; 09856 } 09857 } 09858 AST_LIST_UNLOCK(&iaxq.queue); 09859 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 09860 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 09861 } 09862 break; 09863 case IAX_COMMAND_DPREP: 09864 complete_dpreply(iaxs[fr->callno], &ies); 09865 break; 09866 case IAX_COMMAND_UNSUPPORT: 09867 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 09868 break; 09869 case IAX_COMMAND_FWDOWNL: 09870 /* Firmware download */ 09871 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 09872 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 09873 break; 09874 } 09875 memset(&ied0, 0, sizeof(ied0)); 09876 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 09877 if (res < 0) 09878 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09879 else if (res > 0) 09880 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09881 else 09882 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09883 if (!iaxs[fr->callno]) { 09884 ast_mutex_unlock(&iaxsl[fr->callno]); 09885 return 1; 09886 } 09887 break; 09888 case IAX_COMMAND_CALLTOKEN: 09889 { 09890 struct iax_frame *cur; 09891 AST_LIST_LOCK(&iaxq.queue); 09892 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09893 /* find the last sent frame in our frame queue for this callno. 09894 * There are many things to take into account before resending this frame. 09895 * All of these are taken care of in resend_with_token() */ 09896 if (cur->callno == fr->callno) { 09897 break; 09898 } 09899 } 09900 AST_LIST_UNLOCK(&iaxq.queue); 09901 09902 /* find last sent frame */ 09903 if (cur && ies.calltoken && ies.calltokendata) { 09904 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 09905 } 09906 break; 09907 } 09908 default: 09909 if (option_debug) 09910 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 09911 memset(&ied0, 0, sizeof(ied0)); 09912 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 09913 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 09914 } 09915 /* Don't actually pass these frames along */ 09916 if ((f.subclass != IAX_COMMAND_ACK) && 09917 (f.subclass != IAX_COMMAND_TXCNT) && 09918 (f.subclass != IAX_COMMAND_TXACC) && 09919 (f.subclass != IAX_COMMAND_INVAL) && 09920 (f.subclass != IAX_COMMAND_VNAK)) { 09921 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09922 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09923 } 09924 ast_mutex_unlock(&iaxsl[fr->callno]); 09925 return 1; 09926 } 09927 /* Unless this is an ACK or INVAL frame, ack it */ 09928 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09929 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09930 } else if (minivid) { 09931 f.frametype = AST_FRAME_VIDEO; 09932 if (iaxs[fr->callno]->videoformat > 0) 09933 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 09934 else { 09935 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 09936 iax2_vnak(fr->callno); 09937 ast_mutex_unlock(&iaxsl[fr->callno]); 09938 return 1; 09939 } 09940 f.datalen = res - sizeof(*vh); 09941 if (f.datalen) 09942 f.data = thread->buf + sizeof(*vh); 09943 else 09944 f.data = NULL; 09945 #ifdef IAXTESTS 09946 if (test_resync) { 09947 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 09948 } else 09949 #endif /* IAXTESTS */ 09950 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 09951 } else { 09952 /* A mini frame */ 09953 f.frametype = AST_FRAME_VOICE; 09954 if (iaxs[fr->callno]->voiceformat > 0) 09955 f.subclass = iaxs[fr->callno]->voiceformat; 09956 else { 09957 if (option_debug) 09958 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 09959 iax2_vnak(fr->callno); 09960 ast_mutex_unlock(&iaxsl[fr->callno]); 09961 return 1; 09962 } 09963 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 09964 if (f.datalen < 0) { 09965 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09966 ast_mutex_unlock(&iaxsl[fr->callno]); 09967 return 1; 09968 } 09969 if (f.datalen) 09970 f.data = thread->buf + sizeof(*mh); 09971 else 09972 f.data = NULL; 09973 #ifdef IAXTESTS 09974 if (test_resync) { 09975 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 09976 } else 09977 #endif /* IAXTESTS */ 09978 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 09979 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 09980 } 09981 /* Don't pass any packets until we're started */ 09982 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09983 ast_mutex_unlock(&iaxsl[fr->callno]); 09984 return 1; 09985 } 09986 /* Common things */ 09987 f.src = "IAX2"; 09988 f.mallocd = 0; 09989 f.offset = 0; 09990 f.len = 0; 09991 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 09992 f.samples = ast_codec_get_samples(&f); 09993 /* We need to byteswap incoming slinear samples from network byte order */ 09994 if (f.subclass == AST_FORMAT_SLINEAR) 09995 ast_frame_byteswap_be(&f); 09996 } else 09997 f.samples = 0; 09998 iax_frame_wrap(fr, &f); 09999 10000 /* If this is our most recent packet, use it as our basis for timestamping */ 10001 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10002 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 10003 fr->outoforder = 0; 10004 } else { 10005 if (option_debug && iaxdebug && iaxs[fr->callno]) 10006 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); 10007 fr->outoforder = -1; 10008 } 10009 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 10010 duped_fr = iaxfrdup2(fr); 10011 if (duped_fr) { 10012 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 10013 } 10014 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10015 iaxs[fr->callno]->last = fr->ts; 10016 #if 1 10017 if (option_debug && iaxdebug) 10018 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10019 #endif 10020 } 10021 10022 /* Always run again */ 10023 ast_mutex_unlock(&iaxsl[fr->callno]); 10024 return 1; 10025 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 8286 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, 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().
08287 { 08288 struct iax2_thread *thread; 08289 socklen_t len; 08290 time_t t; 08291 static time_t last_errtime = 0; 08292 struct ast_iax2_full_hdr *fh; 08293 08294 if (!(thread = find_idle_thread())) { 08295 time(&t); 08296 if (t != last_errtime && option_debug) 08297 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 08298 last_errtime = t; 08299 usleep(1); 08300 return 1; 08301 } 08302 08303 len = sizeof(thread->iosin); 08304 thread->iofd = fd; 08305 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 08306 thread->buf_size = sizeof(thread->readbuf); 08307 thread->buf = thread->readbuf; 08308 if (thread->buf_len < 0) { 08309 if (errno != ECONNREFUSED && errno != EAGAIN) 08310 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 08311 handle_error(); 08312 thread->iostate = IAX_IOSTATE_IDLE; 08313 signal_condition(&thread->lock, &thread->cond); 08314 return 1; 08315 } 08316 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 08317 thread->iostate = IAX_IOSTATE_IDLE; 08318 signal_condition(&thread->lock, &thread->cond); 08319 return 1; 08320 } 08321 08322 /* Determine if this frame is a full frame; if so, and any thread is currently 08323 processing a full frame for the same callno from this peer, then drop this 08324 frame (and the peer will retransmit it) */ 08325 fh = (struct ast_iax2_full_hdr *) thread->buf; 08326 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 08327 struct iax2_thread *cur = NULL; 08328 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 08329 08330 AST_LIST_LOCK(&active_list); 08331 AST_LIST_TRAVERSE(&active_list, cur, list) { 08332 if ((cur->ffinfo.callno == callno) && 08333 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 08334 break; 08335 } 08336 if (cur) { 08337 /* we found another thread processing a full frame for this call, 08338 so queue it up for processing later. */ 08339 defer_full_frame(thread, cur); 08340 AST_LIST_UNLOCK(&active_list); 08341 thread->iostate = IAX_IOSTATE_IDLE; 08342 signal_condition(&thread->lock, &thread->cond); 08343 return 1; 08344 } else { 08345 /* this thread is going to process this frame, so mark it */ 08346 thread->ffinfo.callno = callno; 08347 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 08348 thread->ffinfo.type = fh->type; 08349 thread->ffinfo.csub = fh->csub; 08350 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08351 } 08352 AST_LIST_UNLOCK(&active_list); 08353 } 08354 08355 /* Mark as ready and send on its way */ 08356 thread->iostate = IAX_IOSTATE_READY; 08357 #ifdef DEBUG_SCHED_MULTITHREAD 08358 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 08359 #endif 08360 signal_condition(&thread->lock, &thread->cond); 08361 08362 return 1; 08363 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 8073 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().
08074 { 08075 pthread_t newthread; 08076 struct dpreq_data *dpr; 08077 pthread_attr_t attr; 08078 08079 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 08080 return; 08081 08082 pthread_attr_init(&attr); 08083 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08084 08085 dpr->callno = callno; 08086 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 08087 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 08088 if (callerid) 08089 dpr->callerid = ast_strdup(callerid); 08090 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 08091 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 08092 } 08093 08094 pthread_attr_destroy(&attr); 08095 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 10640 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().
10641 { 10642 pthread_attr_t attr; 10643 int threadcount = 0; 10644 int x; 10645 for (x = 0; x < iaxthreadcount; x++) { 10646 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 10647 if (thread) { 10648 thread->type = IAX_TYPE_POOL; 10649 thread->threadnum = ++threadcount; 10650 ast_mutex_init(&thread->lock); 10651 ast_cond_init(&thread->cond, NULL); 10652 pthread_attr_init(&attr); 10653 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10654 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 10655 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 10656 free(thread); 10657 thread = NULL; 10658 } 10659 AST_LIST_LOCK(&idle_list); 10660 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 10661 AST_LIST_UNLOCK(&idle_list); 10662 } 10663 } 10664 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 10665 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 10666 if (option_verbose > 1) 10667 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 10668 return 0; 10669 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 7755 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
07756 { 07757 iax2_destroy_helper(iaxs[callno]); 07758 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1437 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().
01438 { 01439 if (!pvt->peercallno) { 01440 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01441 return; 01442 } 01443 01444 ao2_link(iax_peercallno_pvts, pvt); 01445 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1418 of file chan_iax2.c.
References ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01419 { 01420 if (!pvt->transfercallno) { 01421 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01422 return; 01423 } 01424 01425 ao2_link(iax_transfercallno_pvts, pvt); 01426 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7942 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().
07943 { 07944 char buf[1024]; 07945 int res; 07946 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 07947 int processed = 0; 07948 int totalcalls = 0; 07949 #ifdef DAHDI_TIMERACK 07950 int x = 1; 07951 #endif 07952 struct timeval now; 07953 if (iaxtrunkdebug) 07954 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 07955 gettimeofday(&now, NULL); 07956 if (events & AST_IO_PRI) { 07957 #ifdef DAHDI_TIMERACK 07958 /* Great, this is a timing interface, just call the ioctl */ 07959 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 07960 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 07961 usleep(1); 07962 return -1; 07963 } 07964 #endif 07965 } else { 07966 /* Read and ignore from the pseudo channel for timing */ 07967 res = read(fd, buf, sizeof(buf)); 07968 if (res < 1) { 07969 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 07970 return 1; 07971 } 07972 } 07973 /* For each peer that supports trunking... */ 07974 ast_mutex_lock(&tpeerlock); 07975 tpeer = tpeers; 07976 while(tpeer) { 07977 processed++; 07978 res = 0; 07979 ast_mutex_lock(&tpeer->lock); 07980 /* We can drop a single tpeer per pass. That makes all this logic 07981 substantially easier */ 07982 if (!drop && iax2_trunk_expired(tpeer, &now)) { 07983 /* Take it out of the list, but don't free it yet, because it 07984 could be in use */ 07985 if (prev) 07986 prev->next = tpeer->next; 07987 else 07988 tpeers = tpeer->next; 07989 drop = tpeer; 07990 } else { 07991 res = send_trunk(tpeer, &now); 07992 if (iaxtrunkdebug) 07993 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); 07994 } 07995 totalcalls += res; 07996 res = 0; 07997 ast_mutex_unlock(&tpeer->lock); 07998 prev = tpeer; 07999 tpeer = tpeer->next; 08000 } 08001 ast_mutex_unlock(&tpeerlock); 08002 if (drop) { 08003 ast_mutex_lock(&drop->lock); 08004 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 08005 because by the time they could get tpeerlock, we've already grabbed it */ 08006 if (option_debug) 08007 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 08008 if (drop->trunkdata) { 08009 free(drop->trunkdata); 08010 drop->trunkdata = NULL; 08011 } 08012 ast_mutex_unlock(&drop->lock); 08013 ast_mutex_destroy(&drop->lock); 08014 free(drop); 08015 08016 } 08017 if (iaxtrunkdebug) 08018 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 08019 iaxtrunkdebug =0; 08020 return 1; 08021 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12702 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12703 { 12704 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12705 12706 /* The frames_received field is used to hold whether we're matching 12707 * against a full frame or not ... */ 12708 12709 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 12710 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12711 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12695 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
12696 { 12697 const struct chan_iax2_pvt *pvt = obj; 12698 12699 return pvt->transfercallno; 12700 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2980 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02981 { 02982 int res; 02983 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02984 sizeof(*sin)); 02985 if (res < 0) { 02986 if (option_debug) 02987 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02988 handle_error(); 02989 } else 02990 res = 0; 02991 return res; 02992 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2668 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().
02669 { 02670 struct stat stbuf; 02671 struct iax_firmware *cur; 02672 int ifd; 02673 int fd; 02674 int res; 02675 02676 struct ast_iax2_firmware_header *fwh, fwh2; 02677 struct MD5Context md5; 02678 unsigned char sum[16]; 02679 unsigned char buf[1024]; 02680 int len, chunk; 02681 char *s2; 02682 char *last; 02683 s2 = alloca(strlen(s) + 100); 02684 if (!s2) { 02685 ast_log(LOG_WARNING, "Alloca failed!\n"); 02686 return -1; 02687 } 02688 last = strrchr(s, '/'); 02689 if (last) 02690 last++; 02691 else 02692 last = s; 02693 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02694 res = stat(s, &stbuf); 02695 if (res < 0) { 02696 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02697 return -1; 02698 } 02699 /* Make sure it's not a directory */ 02700 if (S_ISDIR(stbuf.st_mode)) 02701 return -1; 02702 ifd = open(s, O_RDONLY); 02703 if (ifd < 0) { 02704 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02705 return -1; 02706 } 02707 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 02708 if (fd < 0) { 02709 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02710 close(ifd); 02711 return -1; 02712 } 02713 /* Unlink our newly created file */ 02714 unlink(s2); 02715 02716 /* Now copy the firmware into it */ 02717 len = stbuf.st_size; 02718 while(len) { 02719 chunk = len; 02720 if (chunk > sizeof(buf)) 02721 chunk = sizeof(buf); 02722 res = read(ifd, buf, chunk); 02723 if (res != chunk) { 02724 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02725 close(ifd); 02726 close(fd); 02727 return -1; 02728 } 02729 res = write(fd, buf, chunk); 02730 if (res != chunk) { 02731 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02732 close(ifd); 02733 close(fd); 02734 return -1; 02735 } 02736 len -= chunk; 02737 } 02738 close(ifd); 02739 /* Return to the beginning */ 02740 lseek(fd, 0, SEEK_SET); 02741 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02742 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02743 close(fd); 02744 return -1; 02745 } 02746 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02747 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02748 close(fd); 02749 return -1; 02750 } 02751 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02752 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02753 close(fd); 02754 return -1; 02755 } 02756 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02757 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02758 close(fd); 02759 return -1; 02760 } 02761 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02762 if (fwh == MAP_FAILED) { 02763 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02764 close(fd); 02765 return -1; 02766 } 02767 MD5Init(&md5); 02768 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02769 MD5Final(sum, &md5); 02770 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02771 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02772 munmap((void*)fwh, stbuf.st_size); 02773 close(fd); 02774 return -1; 02775 } 02776 cur = waresl.wares; 02777 while(cur) { 02778 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02779 /* Found a candidate */ 02780 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02781 /* The version we have on loaded is older, load this one instead */ 02782 break; 02783 /* This version is no newer than what we have. Don't worry about it. 02784 We'll consider it a proper load anyhow though */ 02785 munmap((void*)fwh, stbuf.st_size); 02786 close(fd); 02787 return 0; 02788 } 02789 cur = cur->next; 02790 } 02791 if (!cur) { 02792 /* Allocate a new one and link it */ 02793 if ((cur = ast_calloc(1, sizeof(*cur)))) { 02794 cur->fd = -1; 02795 cur->next = waresl.wares; 02796 waresl.wares = cur; 02797 } 02798 } 02799 if (cur) { 02800 if (cur->fwh) { 02801 munmap((void*)cur->fwh, cur->mmaplen); 02802 } 02803 if (cur->fd > -1) 02804 close(cur->fd); 02805 cur->fwh = fwh; 02806 cur->fd = fd; 02807 cur->mmaplen = stbuf.st_size; 02808 cur->dead = 0; 02809 } 02810 return 0; 02811 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7118 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, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
07119 { 07120 int newcall = 0; 07121 char newip[256]; 07122 struct iax_ie_data ied; 07123 struct sockaddr_in new; 07124 07125 07126 memset(&ied, 0, sizeof(ied)); 07127 if (ies->apparent_addr) 07128 bcopy(ies->apparent_addr, &new, sizeof(new)); 07129 if (ies->callno) 07130 newcall = ies->callno; 07131 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07132 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07133 return -1; 07134 } 07135 pvt->transfercallno = newcall; 07136 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07137 inet_aton(newip, &pvt->transfer.sin_addr); 07138 pvt->transfer.sin_family = AF_INET; 07139 pvt->transferid = ies->transferid; 07140 /* only store by transfercallno if this is a new transfer, 07141 * just in case we get a duplicate TXREQ */ 07142 if (pvt->transferring == TRANSFER_NONE) { 07143 store_by_transfercallno(pvt); 07144 } 07145 pvt->transferring = TRANSFER_BEGIN; 07146 07147 if (ies->transferid) 07148 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07149 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07150 return 0; 07151 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1253 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01254 { 01255 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01256 if (csub & IAX_FLAG_SC_LOG) { 01257 /* special case for 'compressed' -1 */ 01258 if (csub == 0xff) 01259 return -1; 01260 else 01261 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01262 } 01263 else 01264 return csub; 01265 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 7407 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().
07408 { 07409 if (peer->expire > -1) { 07410 if (!ast_sched_del(sched, peer->expire)) { 07411 peer->expire = -1; 07412 peer_unref(peer); 07413 } 07414 } 07415 07416 if (peer->pokeexpire > -1) { 07417 if (!ast_sched_del(sched, peer->pokeexpire)) { 07418 peer->pokeexpire = -1; 07419 peer_unref(peer); 07420 } 07421 } 07422 07423 ao2_unlink(peers, peer); 07424 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12656 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), ast_mutex_destroy(), and iaxpeer_function.
12657 { 12658 int res; 12659 ast_custom_function_unregister(&iaxpeer_function); 12660 res = __unload_module(); 12661 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS 12662 ast_mutex_destroy(&sched_lock); 12663 #endif 12664 return res; 12665 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4739 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
04740 { 04741 ast_mutex_unlock(&iaxsl[callno1]); 04742 ast_mutex_unlock(&iaxsl[callno0]); 04743 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3452 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().
03453 { 03454 /* Video mini frames only encode the lower 15 bits of the session 03455 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03456 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03457 const int lower_mask = (1 << ts_shift) - 1; 03458 const int upper_mask = ~lower_mask; 03459 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03460 03461 if ( (fr->ts & upper_mask) == last_upper ) { 03462 const int x = fr->ts - iaxs[fr->callno]->last; 03463 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03464 03465 if (x < -threshold) { 03466 /* Sudden big jump backwards in timestamp: 03467 What likely happened here is that miniframe timestamp has circled but we haven't 03468 gotten the update from the main packet. We'll just pretend that we did, and 03469 update the timestamp appropriately. */ 03470 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03471 if (option_debug && iaxdebug) 03472 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 03473 } else if (x > threshold) { 03474 /* Sudden apparent big jump forwards in timestamp: 03475 What's likely happened is this is an old miniframe belonging to the previous 03476 top 15 or 16-bit timestamp that has turned up out of order. 03477 Adjust the timestamp appropriately. */ 03478 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03479 if (option_debug && iaxdebug) 03480 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 03481 } 03482 } 03483 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3487 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().
03488 { 03489 int when; 03490 03491 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03492 03493 when = jb_next(pvt->jb) - when; 03494 03495 AST_SCHED_DEL(sched, pvt->jbid); 03496 03497 if(when <= 0) { 03498 /* XXX should really just empty until when > 0.. */ 03499 when = 1; 03500 } 03501 03502 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 03503 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1744 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01745 { 01746 int max = 1; 01747 int x; 01748 /* XXX Prolly don't need locks here XXX */ 01749 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01750 if (iaxs[x]) 01751 max = x + 1; 01752 } 01753 maxnontrunkcall = max; 01754 if (option_debug && iaxdebug) 01755 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01756 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1457 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), iaxs, LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01458 { 01459 int max = TRUNK_CALL_START; 01460 int x; 01461 01462 /* XXX Prolly don't need locks here XXX */ 01463 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01464 if (iaxs[x]) { 01465 max = x + 1; 01466 } 01467 } 01468 01469 maxtrunkcall = max; 01470 if (option_debug && iaxdebug) 01471 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01472 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3051 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().
03052 { 03053 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03054 struct ast_iax2_full_hdr *fh = f->data; 03055 struct ast_frame af; 03056 03057 /* if frame is encrypted. decrypt before updating it. */ 03058 if (f->encmethods) { 03059 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03060 } 03061 /* Mark this as a retransmission */ 03062 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03063 /* Update iseqno */ 03064 f->iseqno = iaxs[f->callno]->iseqno; 03065 fh->iseqno = f->iseqno; 03066 03067 /* Now re-encrypt the frame */ 03068 if (f->encmethods) { 03069 /* since this is a retransmit frame, create a new random padding 03070 * before re-encrypting. */ 03071 build_rand_pad(f->semirand, sizeof(f->semirand)); 03072 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03073 } 03074 return 0; 03075 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 7520 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().
07521 { 07522 /* Called from IAX thread only, with proper iaxsl lock */ 07523 struct iax_ie_data ied; 07524 struct iax2_peer *p; 07525 int msgcount; 07526 char data[80]; 07527 int version; 07528 const char *peer_name; 07529 int res = -1; 07530 07531 memset(&ied, 0, sizeof(ied)); 07532 07533 peer_name = ast_strdupa(iaxs[callno]->peer); 07534 07535 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 07536 ast_mutex_unlock(&iaxsl[callno]); 07537 if (!(p = find_peer(peer_name, 1))) { 07538 ast_mutex_lock(&iaxsl[callno]); 07539 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 07540 return -1; 07541 } 07542 ast_mutex_lock(&iaxsl[callno]); 07543 if (!iaxs[callno]) 07544 goto return_unref; 07545 07546 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 07547 if (sin->sin_addr.s_addr) { 07548 time_t nowtime; 07549 time(&nowtime); 07550 realtime_update_peer(peer_name, sin, nowtime); 07551 } else { 07552 realtime_update_peer(peer_name, sin, 0); 07553 } 07554 } 07555 if (inaddrcmp(&p->addr, sin)) { 07556 if (iax2_regfunk) 07557 iax2_regfunk(p->name, 1); 07558 07559 /* modify entry in peercnts table as _not_ registered */ 07560 peercnt_modify(0, 0, &p->addr); 07561 07562 /* Stash the IP address from which they registered */ 07563 memcpy(&p->addr, sin, sizeof(p->addr)); 07564 07565 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 07566 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 07567 ast_db_put("IAX/Registry", p->name, data); 07568 if (option_verbose > 2) 07569 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 07570 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 07571 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 07572 register_peer_exten(p, 1); 07573 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07574 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 07575 if (option_verbose > 2) 07576 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 07577 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 07578 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 07579 register_peer_exten(p, 0); 07580 ast_db_del("IAX/Registry", p->name); 07581 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07582 } 07583 /* Update the host */ 07584 /* Verify that the host is really there */ 07585 iax2_poke_peer(p, callno); 07586 } 07587 07588 /* modify entry in peercnts table as registered */ 07589 if (p->maxcallno) { 07590 peercnt_modify(1, p->maxcallno, &p->addr); 07591 } 07592 07593 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 07594 if (!iaxs[callno]) { 07595 res = -1; 07596 goto return_unref; 07597 } 07598 07599 /* Store socket fd */ 07600 p->sockfd = fd; 07601 /* Setup the expiry */ 07602 if (p->expire > -1) { 07603 if (!ast_sched_del(sched, p->expire)) { 07604 p->expire = -1; 07605 peer_unref(p); 07606 } 07607 } 07608 /* treat an unspecified refresh interval as the minimum */ 07609 if (!refresh) 07610 refresh = min_reg_expire; 07611 if (refresh > max_reg_expire) { 07612 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07613 p->name, max_reg_expire, refresh); 07614 p->expiry = max_reg_expire; 07615 } else if (refresh < min_reg_expire) { 07616 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07617 p->name, min_reg_expire, refresh); 07618 p->expiry = min_reg_expire; 07619 } else { 07620 p->expiry = refresh; 07621 } 07622 if (p->expiry && sin->sin_addr.s_addr) { 07623 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07624 if (p->expire == -1) 07625 peer_unref(p); 07626 } 07627 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 07628 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 07629 if (sin->sin_addr.s_addr) { 07630 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 07631 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 07632 if (!ast_strlen_zero(p->mailbox)) { 07633 int new, old; 07634 ast_app_inboxcount(p->mailbox, &new, &old); 07635 if (new > 255) 07636 new = 255; 07637 if (old > 255) 07638 old = 255; 07639 msgcount = (old << 8) | new; 07640 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 07641 } 07642 if (ast_test_flag(p, IAX_HASCALLERID)) { 07643 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 07644 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 07645 } 07646 } 07647 version = iax_check_version(devtype); 07648 if (version) 07649 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 07650 07651 res = 0; 07652 07653 return_unref: 07654 peer_unref(p); 07655 07656 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 07657 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1300 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_objects().
01301 { 01302 struct iax2_user *user = obj, *user2 = arg; 01303 01304 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01305 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11309 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11310 { 11311 struct iax2_user *user = obj; 11312 11313 ast_set_flag(user, IAX_DELME); 11314 11315 return 0; 11316 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 11058 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().
11059 { 11060 struct iax2_user *user = obj; 11061 11062 ast_free_ha(user->ha); 11063 free_context(user->contexts); 11064 if(user->vars) { 11065 ast_variables_destroy(user->vars); 11066 user->vars = NULL; 11067 } 11068 ast_string_field_free_memory(user); 11069 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1290 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_objects().
01291 { 01292 const struct iax2_user *user = obj; 01293 01294 return ast_str_hash(user->name); 01295 }
Definition at line 1348 of file chan_iax2.c.
References ao2_ref().
01349 { 01350 ao2_ref(user, +1); 01351 return user; 01352 }
Definition at line 1354 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().
01355 { 01356 ao2_ref(user, -1); 01357 return NULL; 01358 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 7856 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().
07857 { 07858 struct iax_frame *f; 07859 07860 AST_LIST_LOCK(&iaxq.queue); 07861 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 07862 /* Send a copy immediately */ 07863 if ((f->callno == callno) && iaxs[f->callno] && 07864 ((unsigned char ) (f->oseqno - last) < 128) && 07865 (f->retries >= 0)) { 07866 send_packet(f); 07867 } 07868 } 07869 AST_LIST_UNLOCK(&iaxq.queue); 07870 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4625 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().
04626 { 04627 unsigned short callno = pvt->callno; 04628 04629 if (!pvt->peercallno) { 04630 /* We don't know the remote side's call number, yet. :( */ 04631 int count = 10; 04632 while (count-- && pvt && !pvt->peercallno) { 04633 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 04634 pvt = iaxs[callno]; 04635 } 04636 if (!pvt->peercallno) { 04637 return -1; 04638 } 04639 } 04640 04641 return 0; 04642 }
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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 12886 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 218 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 12886 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 156 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 157 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 717 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 677 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 682 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 680 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 720 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 12439 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 12444 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 12454 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 12449 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 12434 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 143 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 12408 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 12400 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 12392 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 722 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 724 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 174 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 223 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 798 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 726 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 729 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 281 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 226 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 204 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 224 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 177 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 12350 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 990 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 12416 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 934 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 941 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 478 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 158 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 161 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 163 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 476 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+1] [static] |
Definition at line 922 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_lock_owner(), 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 923 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_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 474 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 208 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 201 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 151 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 159 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 691 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 168 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 149 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 148 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 154 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 948 of file chan_iax2.c.
Referenced by __find_callno(), and update_max_nontrunk().
int maxtrunkcall = TRUNK_CALL_START [static] |
int min_reg_expire [static] |
Definition at line 167 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 219 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 220 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 172 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 228 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 12412 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 12404 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 12396 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 173 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 10275 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 10277 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 714 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 707 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 150 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 139 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 12346 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 10276 of file chan_iax2.c.
int randomcalltokendata [static] |
Definition at line 689 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 146 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 153 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 202 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 235 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 231 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 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 12334 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 12342 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 12366 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 12384 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 12370 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 12338 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 12378 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 12354 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 12388 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 12330 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 12374 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 12361 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 141 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 210 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 170 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 165 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 731 of file chan_iax2.c.
ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 155 of file chan_iax2.c.
int unloading [static] |
Definition at line 175 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 710 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().