#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 | 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 |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
#define | CALLTOKEN_IE_FORMAT "%u?%s" |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
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 int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static struct callno_entry * | get_unused_callno (int trunk, int validated) |
static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_callnumber_usage (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static int | load_objects (void) |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static int | peercnt_add (struct sockaddr_in *sin) |
static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
static int | peercnt_hash_cb (const void *obj, const int flags) |
static void | peercnt_modify (unsigned char reg, uint16_t limit, struct sockaddr_in *sin) |
static void | peercnt_remove (struct peercnt *peercnt) |
static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
static int | peercnt_remove_cb (const void *obj) |
static void | poke_all_peers (void) |
static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | 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 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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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] |
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 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 758 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 754 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 768 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 756 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 760 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 762 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 764 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 766 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 123 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
#define CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
Referenced by handle_call_token().
#define CALLTOKEN_IE_FORMAT "%u?%s" |
Referenced by handle_call_token().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 131 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 197 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 196 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 195 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 456 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15d %-15d\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 136 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
Definition at line 178 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 186 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 191 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 180 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 791 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 795 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 114 of file chan_iax2.c.
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 465 of file chan_iax2.c.
Referenced by ast_cli_netstats(), iax2_send(), and iax2_show_channels().
#define MAX_JITTER_BUFFER 50 |
Definition at line 453 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 688 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 459 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 457 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 454 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 122 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
#define SCHED_MULTITHREADED |
Definition at line 107 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1090 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
Definition at line 928 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 462 of file chan_iax2.c.
anonymous enum |
Definition at line 231 of file chan_iax2.c.
00231 { 00232 IAX_STATE_STARTED = (1 << 0), 00233 IAX_STATE_AUTHENTICATED = (1 << 1), 00234 IAX_STATE_TBD = (1 << 2), 00235 } iax2_state;
anonymous enum |
Definition at line 242 of file chan_iax2.c.
00242 { 00243 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00244 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00245 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00246 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00247 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00248 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00249 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00250 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00251 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00252 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00253 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00254 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00255 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00256 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00257 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00258 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00259 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00260 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00261 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00262 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00263 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00264 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00265 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00266 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00267 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00268 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00269 response, so that we've achieved a three-way handshake with 00270 them before sending voice or anything else*/ 00271 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00272 } iax2_flags;
anonymous enum |
Definition at line 1608 of file chan_iax2.c.
01608 { 01609 /* do not allow a new call number, only search ones in use for match */ 01610 NEW_PREVENT = 0, 01611 /* search for match first, then allow a new one to be allocated */ 01612 NEW_ALLOW = 1, 01613 /* do not search for match, force a new call number */ 01614 NEW_FORCE = 2, 01615 /* do not search for match, force a new call number. Signifies call number 01616 * has been calltoken validated */ 01617 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01618 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 282 of file chan_iax2.c.
00282 { 00283 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00284 CALLTOKEN_DEFAULT = 0, 00285 /*! \brief Require call token validation. */ 00286 CALLTOKEN_YES = 1, 00287 /*! \brief Require call token validation after a successful registration 00288 * using call token validation occurs. */ 00289 CALLTOKEN_AUTO = 2, 00290 /*! \brief Do not require call token validation. */ 00291 CALLTOKEN_NO = 3, 00292 };
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 408 of file chan_iax2.c.
00408 { 00409 REG_STATE_UNREGISTERED = 0, 00410 REG_STATE_REGSENT, 00411 REG_STATE_AUTHSENT, 00412 REG_STATE_REGISTERED, 00413 REG_STATE_REJECTED, 00414 REG_STATE_TIMEOUT, 00415 REG_STATE_NOAUTH 00416 };
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 418 of file chan_iax2.c.
00418 { 00419 TRANSFER_NONE = 0, 00420 TRANSFER_BEGIN, 00421 TRANSFER_READY, 00422 TRANSFER_RELEASED, 00423 TRANSFER_PASSTHROUGH, 00424 TRANSFER_MBEGIN, 00425 TRANSFER_MREADY, 00426 TRANSFER_MRELEASED, 00427 TRANSFER_MPASSTHROUGH, 00428 TRANSFER_MEDIA, 00429 TRANSFER_MEDIAPASS 00430 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2987 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().
02988 { 02989 /* Attempt to transmit the frame to the remote peer... 02990 Called without iaxsl held. */ 02991 struct iax_frame *f = (struct iax_frame *)data; 02992 int freeme=0; 02993 int callno = f->callno; 02994 /* Make sure this call is still active */ 02995 if (callno) 02996 ast_mutex_lock(&iaxsl[callno]); 02997 if (callno && iaxs[callno]) { 02998 if ((f->retries < 0) /* Already ACK'd */ || 02999 (f->retries >= max_retries) /* Too many attempts */) { 03000 /* Record an error if we've transmitted too many times */ 03001 if (f->retries >= max_retries) { 03002 if (f->transfer) { 03003 /* Transfer timeout */ 03004 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03005 } else if (f->final) { 03006 if (f->final) 03007 iax2_destroy(callno); 03008 } else { 03009 if (iaxs[callno]->owner) 03010 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); 03011 iaxs[callno]->error = ETIMEDOUT; 03012 if (iaxs[callno]->owner) { 03013 struct ast_frame fr = { 0, }; 03014 /* Hangup the fd */ 03015 fr.frametype = AST_FRAME_CONTROL; 03016 fr.subclass = AST_CONTROL_HANGUP; 03017 iax2_queue_frame(callno, &fr); // XXX 03018 /* Remember, owner could disappear */ 03019 if (iaxs[callno] && iaxs[callno]->owner) 03020 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03021 } else { 03022 if (iaxs[callno]->reg) { 03023 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03024 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03025 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03026 } 03027 iax2_destroy(callno); 03028 } 03029 } 03030 03031 } 03032 freeme++; 03033 } else { 03034 /* Update it if it needs it */ 03035 update_packet(f); 03036 /* Attempt transmission */ 03037 send_packet(f); 03038 f->retries++; 03039 /* Try again later after 10 times as long */ 03040 f->retrytime *= 10; 03041 if (f->retrytime > MAX_RETRY_TIME) 03042 f->retrytime = MAX_RETRY_TIME; 03043 /* Transfer messages max out at one second */ 03044 if (f->transfer && (f->retrytime > 1000)) 03045 f->retrytime = 1000; 03046 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03047 } 03048 } else { 03049 /* Make sure it gets freed */ 03050 f->retries = -1; 03051 freeme++; 03052 } 03053 if (callno) 03054 ast_mutex_unlock(&iaxsl[callno]); 03055 /* Do not try again */ 03056 if (freeme) { 03057 /* Don't attempt delivery, just remove it from the queue */ 03058 AST_LIST_LOCK(&iaxq.queue); 03059 AST_LIST_REMOVE(&iaxq.queue, f, list); 03060 iaxq.count--; 03061 AST_LIST_UNLOCK(&iaxq.queue); 03062 f->retrans = -1; 03063 /* Free the IAX frame */ 03064 iax2_frame_free(f); 03065 } 03066 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 7630 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().
07631 { 07632 /* Called from IAX thread only, without iaxs lock */ 07633 int callno = (int)(long)(nothing); 07634 struct iax_ie_data ied; 07635 ast_mutex_lock(&iaxsl[callno]); 07636 if (iaxs[callno]) { 07637 memset(&ied, 0, sizeof(ied)); 07638 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 07639 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 07640 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 07641 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 07642 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 07643 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07644 } 07645 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 07646 } 07647 ast_mutex_unlock(&iaxsl[callno]); 07648 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3971 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().
03972 { 03973 int callno = PTR_TO_CALLNO(nothing); 03974 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03975 ast_mutex_lock(&iaxsl[callno]); 03976 if (iaxs[callno]) { 03977 iaxs[callno]->initid = -1; 03978 iax2_queue_frame(callno, &f); 03979 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03980 } 03981 ast_mutex_unlock(&iaxsl[callno]); 03982 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 7679 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().
07680 { 07681 /* Called from IAX thread only, without iaxs lock */ 07682 int callno = (int)(long)(nothing); 07683 struct iax_ie_data ied; 07684 ast_mutex_lock(&iaxsl[callno]); 07685 if (iaxs[callno]) { 07686 memset(&ied, 0, sizeof(ied)); 07687 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 07688 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 07689 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 07690 } 07691 ast_mutex_unlock(&iaxsl[callno]); 07692 }
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 2840 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().
02841 { 02842 /* Just deliver the packet by using queueing. This is called by 02843 the IAX thread with the iaxsl lock held. */ 02844 struct iax_frame *fr = data; 02845 fr->retrans = -1; 02846 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02847 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02848 iax2_queue_frame(fr->callno, &fr->af); 02849 /* Free our iax frame */ 02850 iax2_frame_free(fr); 02851 /* And don't run again */ 02852 return 0; 02853 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7296 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().
07297 { 07298 struct iax2_peer *peer = (struct iax2_peer *) data; 07299 07300 if (!peer) 07301 return; 07302 07303 peer->expire = -1; 07304 07305 if (option_debug) 07306 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 07307 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 07308 realtime_update_peer(peer->name, &peer->addr, 0); 07309 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07310 /* modify entry in peercnts table as _not_ registered */ 07311 peercnt_modify(0, 0, &peer->addr); 07312 /* Reset the address */ 07313 memset(&peer->addr, 0, sizeof(peer->addr)); 07314 /* Reset expiry value */ 07315 peer->expiry = min_reg_expire; 07316 if (!ast_test_flag(peer, IAX_TEMPONLY)) 07317 ast_db_del("IAX/Registry", peer->name); 07318 register_peer_exten(peer, 0); 07319 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07320 if (iax2_regfunk) 07321 iax2_regfunk(peer->name, 0); 07322 07323 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 07324 unlink_peer(peer); 07325 07326 peer_unref(peer); 07327 }
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 2299 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, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
02300 { 02301 int res = 0; 02302 int x; 02303 /* this call is calltoken validated as long as it is either NEW_FORCE 02304 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02305 int validated = (new > NEW_ALLOW) ? 1 : 0; 02306 char host[80]; 02307 02308 if (new <= NEW_ALLOW) { 02309 if (callno) { 02310 struct chan_iax2_pvt *pvt; 02311 struct chan_iax2_pvt tmp_pvt = { 02312 .callno = dcallno, 02313 .peercallno = callno, 02314 .transfercallno = callno, 02315 /* hack!! */ 02316 .frames_received = check_dcallno, 02317 }; 02318 02319 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02320 /* this works for finding normal call numbers not involving transfering */ 02321 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02322 if (return_locked) { 02323 ast_mutex_lock(&iaxsl[pvt->callno]); 02324 } 02325 res = pvt->callno; 02326 ao2_ref(pvt, -1); 02327 pvt = NULL; 02328 return res; 02329 } 02330 /* this searches for transfer call numbers that might not get caught otherwise */ 02331 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02332 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr)); 02333 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02334 if (return_locked) { 02335 ast_mutex_lock(&iaxsl[pvt->callno]); 02336 } 02337 res = pvt->callno; 02338 ao2_ref(pvt, -1); 02339 pvt = NULL; 02340 return res; 02341 } 02342 } 02343 /* This will occur on the first response to a message that we initiated, 02344 * such as a PING. */ 02345 if (dcallno) { 02346 ast_mutex_lock(&iaxsl[dcallno]); 02347 } 02348 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02349 iaxs[dcallno]->peercallno = callno; 02350 res = dcallno; 02351 store_by_peercallno(iaxs[dcallno]); 02352 if (!res || !return_locked) { 02353 ast_mutex_unlock(&iaxsl[dcallno]); 02354 } 02355 return res; 02356 } 02357 if (dcallno) { 02358 ast_mutex_unlock(&iaxsl[dcallno]); 02359 } 02360 #ifdef IAX_OLD_FIND 02361 /* If we get here, we SHOULD NOT find a call structure for this 02362 callno; if we do, it means that there is a call structure that 02363 has a peer callno but did NOT get entered into the hash table, 02364 which is bad. 02365 02366 If we find a call structure using this old, slow method, output a log 02367 message so we'll know about it. After a few months of leaving this in 02368 place, if we don't hear about people seeing these messages, we can 02369 remove this code for good. 02370 */ 02371 02372 for (x = 1; !res && x < maxnontrunkcall; x++) { 02373 ast_mutex_lock(&iaxsl[x]); 02374 if (iaxs[x]) { 02375 /* Look for an exact match */ 02376 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02377 res = x; 02378 } 02379 } 02380 if (!res || !return_locked) 02381 ast_mutex_unlock(&iaxsl[x]); 02382 } 02383 02384 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02385 ast_mutex_lock(&iaxsl[x]); 02386 if (iaxs[x]) { 02387 /* Look for an exact match */ 02388 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02389 res = x; 02390 } 02391 } 02392 if (!res || !return_locked) 02393 ast_mutex_unlock(&iaxsl[x]); 02394 } 02395 02396 if (res) { 02397 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 02398 } 02399 #endif 02400 } 02401 if (!res && (new >= NEW_ALLOW)) { 02402 struct callno_entry *callno_entry; 02403 /* It may seem odd that we look through the peer list for a name for 02404 * this *incoming* call. Well, it is weird. However, users don't 02405 * have an IP address/port number that we can match against. So, 02406 * this is just checking for a peer that has that IP/port and 02407 * assuming that we have a user of the same name. This isn't always 02408 * correct, but it will be changed if needed after authentication. */ 02409 if (!iax2_getpeername(*sin, host, sizeof(host))) 02410 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02411 02412 if (peercnt_add(sin)) { 02413 /* This address has hit its callnumber limit. When the limit 02414 * is reached, the connection is not added to the peercnts table.*/ 02415 return 0; 02416 } 02417 02418 if (!(callno_entry = get_unused_callno(0, validated))) { 02419 /* since we ran out of space, remove the peercnt 02420 * entry we added earlier */ 02421 peercnt_remove_by_addr(sin); 02422 ast_log(LOG_WARNING, "No more space\n"); 02423 return 0; 02424 } 02425 x = callno_entry->callno; 02426 ast_mutex_lock(&iaxsl[x]); 02427 02428 iaxs[x] = new_iax(sin, host); 02429 update_max_nontrunk(); 02430 if (iaxs[x]) { 02431 if (option_debug && iaxdebug) 02432 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 02433 iaxs[x]->callno_entry = callno_entry; 02434 iaxs[x]->sockfd = sockfd; 02435 iaxs[x]->addr.sin_port = sin->sin_port; 02436 iaxs[x]->addr.sin_family = sin->sin_family; 02437 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02438 iaxs[x]->peercallno = callno; 02439 iaxs[x]->callno = x; 02440 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02441 iaxs[x]->expiry = min_reg_expire; 02442 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02443 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02444 iaxs[x]->amaflags = amaflags; 02445 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02446 02447 ast_string_field_set(iaxs[x], accountcode, accountcode); 02448 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02449 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02450 02451 if (iaxs[x]->peercallno) { 02452 store_by_peercallno(iaxs[x]); 02453 } 02454 } else { 02455 ast_log(LOG_WARNING, "Out of resources\n"); 02456 ast_mutex_unlock(&iaxsl[x]); 02457 replace_callno(callno_entry); 02458 return 0; 02459 } 02460 if (!return_locked) 02461 ast_mutex_unlock(&iaxsl[x]); 02462 res = x; 02463 } 02464 return res; 02465 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3413 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().
03414 { 03415 int callno = PTR_TO_CALLNO(p); 03416 struct chan_iax2_pvt *pvt = NULL; 03417 struct iax_frame *fr; 03418 jb_frame frame; 03419 int ret; 03420 long now; 03421 long next; 03422 struct timeval tv; 03423 03424 /* Make sure we have a valid private structure before going on */ 03425 ast_mutex_lock(&iaxsl[callno]); 03426 pvt = iaxs[callno]; 03427 if (!pvt) { 03428 /* No go! */ 03429 ast_mutex_unlock(&iaxsl[callno]); 03430 return; 03431 } 03432 03433 pvt->jbid = -1; 03434 03435 gettimeofday(&tv,NULL); 03436 /* round up a millisecond since ast_sched_runq does; */ 03437 /* prevents us from spinning while waiting for our now */ 03438 /* to catch up with runq's now */ 03439 tv.tv_usec += 1000; 03440 03441 now = ast_tvdiff_ms(tv, pvt->rxcore); 03442 03443 if(now >= (next = jb_next(pvt->jb))) { 03444 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 03445 switch(ret) { 03446 case JB_OK: 03447 fr = frame.data; 03448 __do_deliver(fr); 03449 /* __do_deliver() can cause the call to disappear */ 03450 pvt = iaxs[callno]; 03451 break; 03452 case JB_INTERP: 03453 { 03454 struct ast_frame af = { 0, }; 03455 03456 /* create an interpolation frame */ 03457 af.frametype = AST_FRAME_VOICE; 03458 af.subclass = pvt->voiceformat; 03459 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03460 af.src = "IAX2 JB interpolation"; 03461 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03462 af.offset = AST_FRIENDLY_OFFSET; 03463 03464 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03465 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03466 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03467 iax2_queue_frame(callno, &af); 03468 /* iax2_queue_frame() could cause the call to disappear */ 03469 pvt = iaxs[callno]; 03470 } 03471 } 03472 break; 03473 case JB_DROP: 03474 iax2_frame_free(frame.data); 03475 break; 03476 case JB_NOFRAME: 03477 case JB_EMPTY: 03478 /* do nothing */ 03479 break; 03480 default: 03481 /* shouldn't happen */ 03482 break; 03483 } 03484 } 03485 if (pvt) 03486 update_jbsched(pvt); 03487 ast_mutex_unlock(&iaxsl[callno]); 03488 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 6977 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
06978 { 06979 struct iax2_registry *reg = (struct iax2_registry *)data; 06980 reg->expire = -1; 06981 iax2_do_register(reg); 06982 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10165 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().
10166 { 10167 struct iax2_peer *peer = (struct iax2_peer *)data; 10168 int callno; 10169 10170 if (peer->lastms > -1) { 10171 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 10172 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 10173 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 10174 } 10175 if ((callno = peer->callno) > 0) { 10176 ast_mutex_lock(&iaxsl[callno]); 10177 iax2_destroy(callno); 10178 ast_mutex_unlock(&iaxsl[callno]); 10179 } 10180 peer->callno = 0; 10181 peer->lastms = -1; 10182 /* Try again quickly */ 10183 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10184 if (peer->pokeexpire == -1) 10185 peer_unref(peer); 10186 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7742 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
07743 { 07744 struct iax2_peer *peer = (struct iax2_peer *)data; 07745 iax2_poke_peer(peer, 0); 07746 peer_unref(peer); 07747 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5707 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and iax2_peer::username.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
05708 { 05709 regex_t regexbuf; 05710 int havepattern = 0; 05711 int total_peers = 0; 05712 int online_peers = 0; 05713 int offline_peers = 0; 05714 int unmonitored_peers = 0; 05715 struct ao2_iterator i; 05716 05717 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 05718 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 05719 05720 struct iax2_peer *peer = NULL; 05721 char name[256]; 05722 int registeredonly=0; 05723 char *term = manager ? "\r\n" : "\n"; 05724 05725 switch (argc) { 05726 case 6: 05727 if (!strcasecmp(argv[3], "registered")) 05728 registeredonly = 1; 05729 else 05730 return RESULT_SHOWUSAGE; 05731 if (!strcasecmp(argv[4], "like")) { 05732 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 05733 return RESULT_SHOWUSAGE; 05734 havepattern = 1; 05735 } else 05736 return RESULT_SHOWUSAGE; 05737 break; 05738 case 5: 05739 if (!strcasecmp(argv[3], "like")) { 05740 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05741 return RESULT_SHOWUSAGE; 05742 havepattern = 1; 05743 } else 05744 return RESULT_SHOWUSAGE; 05745 break; 05746 case 4: 05747 if (!strcasecmp(argv[3], "registered")) 05748 registeredonly = 1; 05749 else 05750 return RESULT_SHOWUSAGE; 05751 break; 05752 case 3: 05753 break; 05754 default: 05755 return RESULT_SHOWUSAGE; 05756 } 05757 05758 05759 if (s) 05760 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05761 else 05762 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 05763 05764 i = ao2_iterator_init(peers, 0); 05765 for (peer = ao2_iterator_next(&i); peer; 05766 peer_unref(peer), peer = ao2_iterator_next(&i)) { 05767 char nm[20]; 05768 char status[20]; 05769 char srch[2000]; 05770 int retstatus; 05771 05772 if (registeredonly && !peer->addr.sin_addr.s_addr) 05773 continue; 05774 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 05775 continue; 05776 05777 if (!ast_strlen_zero(peer->username)) 05778 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 05779 else 05780 ast_copy_string(name, peer->name, sizeof(name)); 05781 05782 retstatus = peer_status(peer, status, sizeof(status)); 05783 if (retstatus > 0) 05784 online_peers++; 05785 else if (!retstatus) 05786 offline_peers++; 05787 else 05788 unmonitored_peers++; 05789 05790 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 05791 05792 snprintf(srch, sizeof(srch), FORMAT, name, 05793 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05794 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05795 nm, 05796 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05797 peer->encmethods ? "(E)" : " ", status, term); 05798 05799 if (s) 05800 astman_append(s, FORMAT, name, 05801 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 05802 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05803 nm, 05804 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05805 peer->encmethods ? "(E)" : " ", status, term); 05806 else 05807 ast_cli(fd, FORMAT, name, 05808 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 05809 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 05810 nm, 05811 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 05812 peer->encmethods ? "(E)" : " ", status, term); 05813 total_peers++; 05814 } 05815 05816 if (s) 05817 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05818 else 05819 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 05820 05821 if (havepattern) 05822 regfree(®exbuf); 05823 05824 return RESULT_SUCCESS; 05825 #undef FORMAT 05826 #undef FORMAT2 05827 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 12686 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1065 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.
01066 { 01067 struct iax2_thread *thread = NULL; 01068 static time_t lasterror; 01069 static time_t t; 01070 01071 thread = find_idle_thread(); 01072 01073 if (thread != NULL) { 01074 thread->schedfunc = func; 01075 thread->scheddata = data; 01076 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01077 #ifdef DEBUG_SCHED_MULTITHREAD 01078 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01079 #endif 01080 signal_condition(&thread->lock, &thread->cond); 01081 return 0; 01082 } 01083 time(&t); 01084 if (t != lasterror && option_debug) 01085 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 01086 lasterror = t; 01087 01088 return -1; 01089 }
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 6232 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
06234 { 06235 struct ast_frame f = { 0, }; 06236 06237 f.frametype = type; 06238 f.subclass = command; 06239 f.datalen = datalen; 06240 f.src = __FUNCTION__; 06241 f.data = (void *) data; 06242 06243 return iax2_send(i, &f, ts, seqno, now, transfer, final); 06244 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1152 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, chan_iax2_pvt::lagid, LOG_WARNING, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01153 { 01154 int callno = (long) data; 01155 01156 ast_mutex_lock(&iaxsl[callno]); 01157 01158 if (iaxs[callno]) { 01159 if (iaxs[callno]->peercallno) { 01160 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01161 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01162 } else { 01163 /* I am the schedule, so I'm allowed to do this */ 01164 iaxs[callno]->lagid = -1; 01165 } 01166 } else { 01167 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); 01168 } 01169 01170 ast_mutex_unlock(&iaxsl[callno]); 01171 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1107 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, LOG_DEBUG, option_debug, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
01108 { 01109 int callno = (long) data; 01110 01111 ast_mutex_lock(&iaxsl[callno]); 01112 01113 if (iaxs[callno]) { 01114 if (iaxs[callno]->peercallno) { 01115 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01116 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01117 } else { 01118 /* I am the schedule, so I'm allowed to do this */ 01119 iaxs[callno]->pingid = -1; 01120 } 01121 } else if (option_debug > 0) { 01122 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); 01123 } 01124 01125 ast_mutex_unlock(&iaxsl[callno]); 01126 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 12374 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, callno_pool, callno_pool_trunk, 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, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, and waresl.
12375 { 12376 struct iax2_thread *thread = NULL; 12377 int x; 12378 12379 /* Make sure threads do not hold shared resources when they are canceled */ 12380 12381 /* Grab the sched lock resource to keep it away from threads about to die */ 12382 /* Cancel the network thread, close the net socket */ 12383 if (netthreadid != AST_PTHREADT_NULL) { 12384 AST_LIST_LOCK(&iaxq.queue); 12385 ast_mutex_lock(&sched_lock); 12386 pthread_cancel(netthreadid); 12387 ast_cond_signal(&sched_cond); 12388 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 12389 AST_LIST_UNLOCK(&iaxq.queue); 12390 pthread_join(netthreadid, NULL); 12391 } 12392 if (schedthreadid != AST_PTHREADT_NULL) { 12393 ast_mutex_lock(&sched_lock); 12394 pthread_cancel(schedthreadid); 12395 ast_cond_signal(&sched_cond); 12396 ast_mutex_unlock(&sched_lock); 12397 pthread_join(schedthreadid, NULL); 12398 } 12399 12400 /* Call for all threads to halt */ 12401 AST_LIST_LOCK(&idle_list); 12402 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 12403 AST_LIST_REMOVE_CURRENT(&idle_list, list); 12404 pthread_cancel(thread->threadid); 12405 } 12406 AST_LIST_TRAVERSE_SAFE_END 12407 AST_LIST_UNLOCK(&idle_list); 12408 12409 AST_LIST_LOCK(&active_list); 12410 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 12411 AST_LIST_REMOVE_CURRENT(&active_list, list); 12412 pthread_cancel(thread->threadid); 12413 } 12414 AST_LIST_TRAVERSE_SAFE_END 12415 AST_LIST_UNLOCK(&active_list); 12416 12417 AST_LIST_LOCK(&dynamic_list); 12418 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 12419 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 12420 pthread_cancel(thread->threadid); 12421 } 12422 AST_LIST_TRAVERSE_SAFE_END 12423 AST_LIST_UNLOCK(&dynamic_list); 12424 12425 AST_LIST_HEAD_DESTROY(&iaxq.queue); 12426 12427 /* Wait for threads to exit */ 12428 while(0 < iaxactivethreadcount) 12429 usleep(10000); 12430 12431 ast_netsock_release(netsock); 12432 ast_netsock_release(outsock); 12433 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 12434 if (iaxs[x]) { 12435 iax2_destroy(x); 12436 } 12437 } 12438 ast_manager_unregister( "IAXpeers" ); 12439 ast_manager_unregister( "IAXnetstats" ); 12440 ast_unregister_application(papp); 12441 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12442 ast_unregister_switch(&iax2_switch); 12443 ast_channel_unregister(&iax2_tech); 12444 delete_users(); 12445 iax_provision_unload(); 12446 sched_context_destroy(sched); 12447 reload_firmware(1); 12448 12449 ast_mutex_destroy(&waresl.lock); 12450 12451 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12452 ast_mutex_destroy(&iaxsl[x]); 12453 } 12454 12455 ao2_ref(peers, -1); 12456 ao2_ref(users, -1); 12457 ao2_ref(iax_peercallno_pvts, -1); 12458 ao2_ref(iax_transfercallno_pvts, -1); 12459 ao2_ref(peercnts, -1); 12460 ao2_ref(callno_limits, -1); 12461 ao2_ref(calltoken_ignores, -1); 12462 ao2_ref(callno_pool, -1); 12463 ao2_ref(callno_pool_trunk, -1); 12464 12465 return 0; 12466 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 12686 of file chan_iax2.c.
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2067 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().
02068 { 02069 struct addr_range tmp; 02070 struct addr_range *addr_range = NULL; 02071 struct ast_ha *ha = NULL; 02072 02073 if (ast_strlen_zero(addr)) { 02074 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02075 return -1; 02076 } 02077 02078 ha = ast_append_ha("permit", addr, NULL); 02079 02080 /* check for valid config information */ 02081 if (!ha) { 02082 ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr); 02083 return -1; 02084 } 02085 02086 ast_copy_ha(ha, &tmp.ha); 02087 /* find or create the addr_range */ 02088 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02089 ao2_lock(addr_range); 02090 addr_range->delme = 0; 02091 ao2_unlock(addr_range); 02092 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02093 /* copy over config data into addr_range object */ 02094 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02095 ao2_link(calltoken_ignores, addr_range); 02096 } else { 02097 ast_free_ha(ha); 02098 return -1; 02099 } 02100 02101 ast_free_ha(ha); 02102 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02103 02104 return 0; 02105 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4049 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().
04050 { 04051 /* first make sure their are two empty bytes left in ied->buf */ 04052 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04053 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04054 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04055 pvt->calltoken_ie_len = 2; 04056 } 04057 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1725 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
01726 { 01727 struct addr_range *lim1 = obj, *lim2 = arg; 01728 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) && 01729 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ? 01730 CMP_MATCH | CMP_STOP : 0; 01731 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1712 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01713 { 01714 struct addr_range *lim = obj; 01715 lim->delme = 1; 01716 return 0; 01717 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1719 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01720 { 01721 const struct addr_range *lim = obj; 01722 return abs((int) lim->ha.netaddr.s_addr); 01723 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1745 of file chan_iax2.c.
References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
01746 { 01747 struct addr_range *addr_range = obj; 01748 struct sockaddr_in *sin = arg; 01749 01750 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 01751 return CMP_MATCH | CMP_STOP; 01752 } 01753 return 0; 01754 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 6285 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
06286 { 06287 while(con) { 06288 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 06289 return -1; 06290 con = con->next; 06291 } 06292 return 0; 06293 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 6048 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().
06049 { 06050 int x; 06051 int numchans = 0; 06052 char first_message[10] = { 0, }; 06053 char last_message[10] = { 0, }; 06054 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06055 ast_mutex_lock(&iaxsl[x]); 06056 if (iaxs[x]) { 06057 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06058 char *fmt; 06059 jb_info jbinfo; 06060 06061 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06062 jb_getinfo(iaxs[x]->jb, &jbinfo); 06063 localjitter = jbinfo.jitter; 06064 localdelay = jbinfo.current - jbinfo.min; 06065 locallost = jbinfo.frames_lost; 06066 locallosspct = jbinfo.losspct/1000; 06067 localdropped = jbinfo.frames_dropped; 06068 localooo = jbinfo.frames_ooo; 06069 } else { 06070 localjitter = -1; 06071 localdelay = 0; 06072 locallost = -1; 06073 locallosspct = -1; 06074 localdropped = 0; 06075 localooo = -1; 06076 } 06077 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06078 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06079 if (limit_fmt) 06080 fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"; 06081 else 06082 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"; 06083 if (s) 06084 06085 astman_append(s, fmt, 06086 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06087 iaxs[x]->pingtime, 06088 localjitter, 06089 localdelay, 06090 locallost, 06091 locallosspct, 06092 localdropped, 06093 localooo, 06094 iaxs[x]->frames_received/1000, 06095 iaxs[x]->remote_rr.jitter, 06096 iaxs[x]->remote_rr.delay, 06097 iaxs[x]->remote_rr.losscnt, 06098 iaxs[x]->remote_rr.losspct, 06099 iaxs[x]->remote_rr.dropped, 06100 iaxs[x]->remote_rr.ooo, 06101 iaxs[x]->remote_rr.packets/1000, 06102 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06103 first_message, 06104 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06105 last_message); 06106 else 06107 ast_cli(fd, fmt, 06108 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06109 iaxs[x]->pingtime, 06110 localjitter, 06111 localdelay, 06112 locallost, 06113 locallosspct, 06114 localdropped, 06115 localooo, 06116 iaxs[x]->frames_received/1000, 06117 iaxs[x]->remote_rr.jitter, 06118 iaxs[x]->remote_rr.delay, 06119 iaxs[x]->remote_rr.losscnt, 06120 iaxs[x]->remote_rr.losspct, 06121 iaxs[x]->remote_rr.dropped, 06122 iaxs[x]->remote_rr.ooo, 06123 iaxs[x]->remote_rr.packets/1000, 06124 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06125 first_message, 06126 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06127 last_message); 06128 numchans++; 06129 } 06130 ast_mutex_unlock(&iaxsl[x]); 06131 } 06132 return numchans; 06133 }
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 4873 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().
04874 { 04875 struct ast_channel *tmp; 04876 struct chan_iax2_pvt *i; 04877 struct ast_variable *v = NULL; 04878 04879 if (!(i = iaxs[callno])) { 04880 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 04881 return NULL; 04882 } 04883 04884 /* Don't hold call lock */ 04885 ast_mutex_unlock(&iaxsl[callno]); 04886 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); 04887 ast_mutex_lock(&iaxsl[callno]); 04888 if (i != iaxs[callno]) { 04889 if (tmp) { 04890 /* unlock and relock iaxsl[callno] to preserve locking order */ 04891 ast_mutex_unlock(&iaxsl[callno]); 04892 ast_channel_free(tmp); 04893 ast_mutex_lock(&iaxsl[callno]); 04894 } 04895 return NULL; 04896 } 04897 04898 if (!tmp) 04899 return NULL; 04900 tmp->tech = &iax2_tech; 04901 /* We can support any format by default, until we get restricted */ 04902 tmp->nativeformats = capability; 04903 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 04904 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 04905 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 04906 04907 /* Don't use ast_set_callerid() here because it will 04908 * generate a NewCallerID event before the NewChannel event */ 04909 if (!ast_strlen_zero(i->ani)) 04910 tmp->cid.cid_ani = ast_strdup(i->ani); 04911 else 04912 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04913 tmp->cid.cid_dnid = ast_strdup(i->dnid); 04914 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04915 tmp->cid.cid_pres = i->calling_pres; 04916 tmp->cid.cid_ton = i->calling_ton; 04917 tmp->cid.cid_tns = i->calling_tns; 04918 if (!ast_strlen_zero(i->language)) 04919 ast_string_field_set(tmp, language, i->language); 04920 if (!ast_strlen_zero(i->accountcode)) 04921 ast_string_field_set(tmp, accountcode, i->accountcode); 04922 if (i->amaflags) 04923 tmp->amaflags = i->amaflags; 04924 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04925 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04926 if (i->adsi) 04927 tmp->adsicpe = i->peeradsicpe; 04928 else 04929 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04930 i->owner = tmp; 04931 i->capability = capability; 04932 04933 for (v = i->vars ; v ; v = v->next) 04934 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04935 04936 if (state != AST_STATE_DOWN) { 04937 if (ast_pbx_start(tmp)) { 04938 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04939 ast_hangup(tmp); 04940 i->owner = NULL; 04941 return NULL; 04942 } 04943 } 04944 04945 ast_module_ref(ast_module_info->self); 04946 04947 return tmp; 04948 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3068 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03069 { 03070 #ifdef SCHED_MULTITHREADED 03071 if (schedule_action(__attempt_transmit, data)) 03072 #endif 03073 __attempt_transmit(data); 03074 return 0; 03075 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 7664 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().
07665 { 07666 /* Schedule sending the authentication failure in one second, to prevent 07667 guessing */ 07668 if (iaxs[callno]) { 07669 iaxs[callno]->authfail = failcode; 07670 if (delayreject) { 07671 AST_SCHED_DEL(sched, iaxs[callno]->authid); 07672 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 07673 } else 07674 auth_reject((void *)(long)callno); 07675 } 07676 return 0; 07677 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 7650 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().
07651 { 07652 int callno = (int)(long)(data); 07653 ast_mutex_lock(&iaxsl[callno]); 07654 if (iaxs[callno]) 07655 iaxs[callno]->authid = -1; 07656 ast_mutex_unlock(&iaxsl[callno]); 07657 #ifdef SCHED_MULTITHREADED 07658 if (schedule_action(__auth_reject, data)) 07659 #endif 07660 __auth_reject(data); 07661 return 0; 07662 }
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 6845 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().
06846 { 06847 int res = -1; 06848 int x; 06849 if (!ast_strlen_zero(keyn)) { 06850 if (!(authmethods & IAX_AUTH_RSA)) { 06851 if (ast_strlen_zero(secret)) 06852 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)); 06853 } else if (ast_strlen_zero(challenge)) { 06854 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 06855 } else { 06856 char sig[256]; 06857 struct ast_key *key; 06858 key = ast_key_get(keyn, AST_KEY_PRIVATE); 06859 if (!key) { 06860 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 06861 } else { 06862 if (ast_sign(key, (char*)challenge, sig)) { 06863 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 06864 res = -1; 06865 } else { 06866 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 06867 res = 0; 06868 } 06869 } 06870 } 06871 } 06872 /* Fall back */ 06873 if (res && !ast_strlen_zero(secret)) { 06874 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 06875 struct MD5Context md5; 06876 unsigned char digest[16]; 06877 char digres[128]; 06878 MD5Init(&md5); 06879 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 06880 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 06881 MD5Final(digest, &md5); 06882 /* If they support md5, authenticate with it. */ 06883 for (x=0;x<16;x++) 06884 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 06885 if (pvt) { 06886 build_encryption_keys(digest, pvt); 06887 } 06888 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 06889 res = 0; 06890 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 06891 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 06892 res = 0; 06893 } else 06894 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 06895 } 06896 return res; 06897 }
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 6903 of file chan_iax2.c.
References iax2_peer::addr, 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(), realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.
Referenced by socket_process().
06904 { 06905 struct iax2_peer *peer = NULL; 06906 /* Start pessimistic */ 06907 int res = -1; 06908 int authmethods = 0; 06909 struct iax_ie_data ied; 06910 uint16_t callno = p->callno; 06911 06912 memset(&ied, 0, sizeof(ied)); 06913 06914 if (ies->username) 06915 ast_string_field_set(p, username, ies->username); 06916 if (ies->challenge) 06917 ast_string_field_set(p, challenge, ies->challenge); 06918 if (ies->authmethods) 06919 authmethods = ies->authmethods; 06920 if (authmethods & IAX_AUTH_MD5) 06921 merge_encryption(p, ies->encmethods); 06922 else 06923 p->encmethods = 0; 06924 06925 /* Check for override RSA authentication first */ 06926 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 06927 /* Normal password authentication */ 06928 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 06929 } else { 06930 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06931 while ((peer = ao2_iterator_next(&i))) { 06932 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 06933 /* No peer specified at our end, or this is the peer */ 06934 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 06935 /* No username specified in peer rule, or this is the right username */ 06936 && (!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))) 06937 /* No specified host, or this is our host */ 06938 ) { 06939 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 06940 if (!res) { 06941 peer_unref(peer); 06942 break; 06943 } 06944 } 06945 peer_unref(peer); 06946 } 06947 if (!peer) { 06948 /* We checked our list and didn't find one. It's unlikely, but possible, 06949 that we're trying to authenticate *to* a realtime peer */ 06950 const char *peer_name = ast_strdupa(p->peer); 06951 ast_mutex_unlock(&iaxsl[callno]); 06952 if ((peer = realtime_peer(peer_name, NULL))) { 06953 ast_mutex_lock(&iaxsl[callno]); 06954 if (!(p = iaxs[callno])) { 06955 peer_unref(peer); 06956 return -1; 06957 } 06958 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 06959 peer_unref(peer); 06960 } 06961 if (!peer) { 06962 ast_mutex_lock(&iaxsl[callno]); 06963 if (!(p = iaxs[callno])) 06964 return -1; 06965 } 06966 } 06967 } 06968 if (ies->encmethods) 06969 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 06970 if (!res) 06971 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 06972 return res; 06973 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 6554 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(), and chan_iax2_pvt::username.
Referenced by socket_process().
06555 { 06556 struct iax_ie_data ied; 06557 int res = -1, authreq_restrict = 0; 06558 char challenge[10]; 06559 struct chan_iax2_pvt *p = iaxs[call_num]; 06560 06561 memset(&ied, 0, sizeof(ied)); 06562 06563 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 06564 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06565 struct iax2_user *user, tmp_user = { 06566 .name = p->username, 06567 }; 06568 06569 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06570 if (user) { 06571 if (user->curauthreq == user->maxauthreq) 06572 authreq_restrict = 1; 06573 else 06574 user->curauthreq++; 06575 user = user_unref(user); 06576 } 06577 } 06578 06579 /* If the AUTHREQ limit test failed, send back an error */ 06580 if (authreq_restrict) { 06581 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 06582 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 06583 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 06584 return 0; 06585 } 06586 06587 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06588 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 06589 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06590 ast_string_field_set(p, challenge, challenge); 06591 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 06592 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 06593 } 06594 if (p->encmethods) 06595 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 06596 06597 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 06598 06599 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 06600 06601 if (p->encmethods) 06602 ast_set_flag(p, IAX_ENCRYPTED); 06603 06604 return res; 06605 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6607 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(), and chan_iax2_pvt::username.
Referenced by socket_process().
06608 { 06609 char requeststr[256]; 06610 char md5secret[256] = ""; 06611 char secret[256] = ""; 06612 char rsasecret[256] = ""; 06613 int res = -1; 06614 int x; 06615 struct iax2_user *user, tmp_user = { 06616 .name = p->username, 06617 }; 06618 06619 if (p->authrej) { 06620 return res; 06621 } 06622 user = ao2_find(users, &tmp_user, OBJ_POINTER); 06623 if (user) { 06624 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 06625 ast_atomic_fetchadd_int(&user->curauthreq, -1); 06626 ast_clear_flag(p, IAX_MAXAUTHREQ); 06627 } 06628 ast_string_field_set(p, host, user->name); 06629 user = user_unref(user); 06630 } 06631 06632 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 06633 return res; 06634 if (ies->password) 06635 ast_copy_string(secret, ies->password, sizeof(secret)); 06636 if (ies->md5_result) 06637 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06638 if (ies->rsa_result) 06639 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06640 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 06641 struct ast_key *key; 06642 char *keyn; 06643 char tmpkey[256]; 06644 char *stringp=NULL; 06645 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 06646 stringp=tmpkey; 06647 keyn = strsep(&stringp, ":"); 06648 while(keyn) { 06649 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06650 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 06651 res = 0; 06652 break; 06653 } else if (!key) 06654 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 06655 keyn = strsep(&stringp, ":"); 06656 } 06657 } else if (p->authmethods & IAX_AUTH_MD5) { 06658 struct MD5Context md5; 06659 unsigned char digest[16]; 06660 char *tmppw, *stringp; 06661 06662 tmppw = ast_strdupa(p->secret); 06663 stringp = tmppw; 06664 while((tmppw = strsep(&stringp, ";"))) { 06665 MD5Init(&md5); 06666 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 06667 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06668 MD5Final(digest, &md5); 06669 /* If they support md5, authenticate with it. */ 06670 for (x=0;x<16;x++) 06671 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06672 if (!strcasecmp(requeststr, md5secret)) { 06673 res = 0; 06674 break; 06675 } 06676 } 06677 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 06678 if (!strcmp(secret, p->secret)) 06679 res = 0; 06680 } 06681 return res; 06682 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3984 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03985 { 03986 #ifdef SCHED_MULTITHREADED 03987 if (schedule_action(__auto_congest, data)) 03988 #endif 03989 __auto_congest(data); 03990 return 0; 03991 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 7694 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().
07695 { 07696 int callno = (int)(long)(data); 07697 ast_mutex_lock(&iaxsl[callno]); 07698 if (iaxs[callno]) { 07699 iaxs[callno]->autoid = -1; 07700 } 07701 ast_mutex_unlock(&iaxsl[callno]); 07702 #ifdef SCHED_MULTITHREADED 07703 if (schedule_action(__auto_hangup, data)) 07704 #endif 07705 __auto_hangup(data); 07706 return 0; 07707 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2014 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().
02015 { 02016 struct addr_range *addr_range = NULL; 02017 struct addr_range tmp; 02018 struct ast_ha *ha; 02019 int limit; 02020 int found; 02021 02022 for (; v; v = v->next) { 02023 limit = -1; 02024 found = 0; 02025 ha = ast_append_ha("permit", v->name, NULL); 02026 02027 /* check for valid config information */ 02028 if (!ha) { 02029 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02030 continue; 02031 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02032 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02033 ast_free_ha(ha); 02034 continue; 02035 } 02036 02037 ast_copy_ha(ha, &tmp.ha); 02038 /* find or create the addr_range */ 02039 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02040 ao2_lock(addr_range); 02041 found = 1; 02042 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02043 ast_free_ha(ha); 02044 return; /* out of memory */ 02045 } 02046 02047 /* copy over config data into addr_range object */ 02048 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02049 ast_free_ha(ha); /* cleanup the tmp ha */ 02050 addr_range->limit = limit; 02051 addr_range->delme = 0; 02052 02053 /* cleanup */ 02054 if (found) { 02055 ao2_unlock(addr_range); 02056 } else { 02057 ao2_link(callno_limits, addr_range); 02058 } 02059 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02060 } 02061 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 10498 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
10499 { 10500 struct iax2_context *con; 10501 10502 if ((con = ast_calloc(1, sizeof(*con)))) 10503 ast_copy_string(con->context, context, sizeof(con->context)); 10504 10505 return con; 10506 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5277 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().
05278 { 05279 /* it is required to hold the corresponding decrypt key to our encrypt key 05280 * in the pvt struct because queued frames occasionally need to be decrypted and 05281 * re-encrypted when updated for a retransmission */ 05282 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05283 aes_encrypt_key128(digest, &pvt->ecx); 05284 aes_decrypt_key128(digest, &pvt->mydcx); 05285 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5271 of file chan_iax2.c.
References aes_decrypt_key128(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05272 { 05273 build_ecx_key(digest, pvt); 05274 aes_decrypt_key128(digest, &pvt->dcx); 05275 }
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 10645 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, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.
10646 { 10647 struct iax2_peer *peer = NULL; 10648 struct ast_ha *oldha = NULL; 10649 int maskfound=0; 10650 int found=0; 10651 int firstpass=1; 10652 struct iax2_peer tmp_peer = { 10653 .name = name, 10654 }; 10655 10656 if (!temponly) { 10657 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 10658 if (peer && !ast_test_flag(peer, IAX_DELME)) 10659 firstpass = 0; 10660 } 10661 10662 if (peer) { 10663 found++; 10664 if (firstpass) { 10665 oldha = peer->ha; 10666 peer->ha = NULL; 10667 } 10668 unlink_peer(peer); 10669 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 10670 peer->expire = -1; 10671 peer->pokeexpire = -1; 10672 peer->sockfd = defaultsockfd; 10673 if (ast_string_field_init(peer, 32)) 10674 peer = peer_unref(peer); 10675 } 10676 10677 if (peer) { 10678 if (firstpass) { 10679 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10680 peer->encmethods = iax2_encryption; 10681 peer->adsi = adsi; 10682 ast_string_field_set(peer,secret,""); 10683 if (!found) { 10684 ast_string_field_set(peer, name, name); 10685 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10686 peer->expiry = min_reg_expire; 10687 } 10688 peer->prefs = prefs; 10689 peer->capability = iax2_capability; 10690 peer->smoothing = 0; 10691 peer->pokefreqok = DEFAULT_FREQ_OK; 10692 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 10693 peer->maxcallno = 0; 10694 peercnt_modify(0, 0, &peer->addr); 10695 peer->calltoken_required = CALLTOKEN_DEFAULT; 10696 ast_string_field_set(peer,context,""); 10697 ast_string_field_set(peer,peercontext,""); 10698 ast_clear_flag(peer, IAX_HASCALLERID); 10699 ast_string_field_set(peer, cid_name, ""); 10700 ast_string_field_set(peer, cid_num, ""); 10701 ast_string_field_set(peer, mohinterpret, mohinterpret); 10702 ast_string_field_set(peer, mohsuggest, mohsuggest); 10703 } 10704 10705 if (!v) { 10706 v = alt; 10707 alt = NULL; 10708 } 10709 while(v) { 10710 if (!strcasecmp(v->name, "secret")) { 10711 ast_string_field_set(peer, secret, v->value); 10712 } else if (!strcasecmp(v->name, "mailbox")) { 10713 ast_string_field_set(peer, mailbox, v->value); 10714 } else if (!strcasecmp(v->name, "hasvoicemail")) { 10715 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 10716 ast_string_field_set(peer, mailbox, name); 10717 } 10718 } else if (!strcasecmp(v->name, "mohinterpret")) { 10719 ast_string_field_set(peer, mohinterpret, v->value); 10720 } else if (!strcasecmp(v->name, "mohsuggest")) { 10721 ast_string_field_set(peer, mohsuggest, v->value); 10722 } else if (!strcasecmp(v->name, "dbsecret")) { 10723 ast_string_field_set(peer, dbsecret, v->value); 10724 } else if (!strcasecmp(v->name, "trunk")) { 10725 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 10726 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 10727 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 10728 ast_clear_flag(peer, IAX_TRUNK); 10729 } 10730 } else if (!strcasecmp(v->name, "auth")) { 10731 peer->authmethods = get_auth_methods(v->value); 10732 } else if (!strcasecmp(v->name, "encryption")) { 10733 peer->encmethods = get_encrypt_methods(v->value); 10734 } else if (!strcasecmp(v->name, "notransfer")) { 10735 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10736 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 10737 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 10738 } else if (!strcasecmp(v->name, "transfer")) { 10739 if (!strcasecmp(v->value, "mediaonly")) { 10740 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10741 } else if (ast_true(v->value)) { 10742 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10743 } else 10744 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10745 } else if (!strcasecmp(v->name, "jitterbuffer")) { 10746 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 10747 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 10748 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 10749 } else if (!strcasecmp(v->name, "host")) { 10750 if (!strcasecmp(v->value, "dynamic")) { 10751 /* They'll register with us */ 10752 ast_set_flag(peer, IAX_DYNAMIC); 10753 if (!found) { 10754 /* Initialize stuff iff we're not found, otherwise 10755 we keep going with what we had */ 10756 memset(&peer->addr.sin_addr, 0, 4); 10757 if (peer->addr.sin_port) { 10758 /* If we've already got a port, make it the default rather than absolute */ 10759 peer->defaddr.sin_port = peer->addr.sin_port; 10760 peer->addr.sin_port = 0; 10761 } 10762 } 10763 } else { 10764 /* Non-dynamic. Make sure we become that way if we're not */ 10765 AST_SCHED_DEL(sched, peer->expire); 10766 ast_clear_flag(peer, IAX_DYNAMIC); 10767 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 10768 return peer_unref(peer); 10769 if (!peer->addr.sin_port) 10770 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 10771 } 10772 if (!maskfound) 10773 inet_aton("255.255.255.255", &peer->mask); 10774 } else if (!strcasecmp(v->name, "defaultip")) { 10775 if (ast_get_ip(&peer->defaddr, v->value)) 10776 return peer_unref(peer); 10777 } else if (!strcasecmp(v->name, "sourceaddress")) { 10778 peer_set_srcaddr(peer, v->value); 10779 } else if (!strcasecmp(v->name, "permit") || 10780 !strcasecmp(v->name, "deny")) { 10781 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 10782 } else if (!strcasecmp(v->name, "mask")) { 10783 maskfound++; 10784 inet_aton(v->value, &peer->mask); 10785 } else if (!strcasecmp(v->name, "context")) { 10786 ast_string_field_set(peer, context, v->value); 10787 } else if (!strcasecmp(v->name, "regexten")) { 10788 ast_string_field_set(peer, regexten, v->value); 10789 } else if (!strcasecmp(v->name, "peercontext")) { 10790 ast_string_field_set(peer, peercontext, v->value); 10791 } else if (!strcasecmp(v->name, "port")) { 10792 if (ast_test_flag(peer, IAX_DYNAMIC)) 10793 peer->defaddr.sin_port = htons(atoi(v->value)); 10794 else 10795 peer->addr.sin_port = htons(atoi(v->value)); 10796 } else if (!strcasecmp(v->name, "username")) { 10797 ast_string_field_set(peer, username, v->value); 10798 } else if (!strcasecmp(v->name, "allow")) { 10799 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 10800 } else if (!strcasecmp(v->name, "disallow")) { 10801 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 10802 } else if (!strcasecmp(v->name, "callerid")) { 10803 if (!ast_strlen_zero(v->value)) { 10804 char name2[80]; 10805 char num2[80]; 10806 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 10807 ast_string_field_set(peer, cid_name, name2); 10808 ast_string_field_set(peer, cid_num, num2); 10809 } else { 10810 ast_string_field_set(peer, cid_name, ""); 10811 ast_string_field_set(peer, cid_num, ""); 10812 } 10813 ast_set_flag(peer, IAX_HASCALLERID); 10814 } else if (!strcasecmp(v->name, "fullname")) { 10815 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 10816 ast_set_flag(peer, IAX_HASCALLERID); 10817 } else if (!strcasecmp(v->name, "cid_number")) { 10818 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 10819 ast_set_flag(peer, IAX_HASCALLERID); 10820 } else if (!strcasecmp(v->name, "sendani")) { 10821 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 10822 } else if (!strcasecmp(v->name, "inkeys")) { 10823 ast_string_field_set(peer, inkeys, v->value); 10824 } else if (!strcasecmp(v->name, "outkey")) { 10825 ast_string_field_set(peer, outkey, v->value); 10826 } else if (!strcasecmp(v->name, "qualify")) { 10827 if (!strcasecmp(v->value, "no")) { 10828 peer->maxms = 0; 10829 } else if (!strcasecmp(v->value, "yes")) { 10830 peer->maxms = DEFAULT_MAXMS; 10831 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 10832 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); 10833 peer->maxms = 0; 10834 } 10835 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 10836 peer->smoothing = ast_true(v->value); 10837 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 10838 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 10839 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); 10840 } 10841 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 10842 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 10843 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); 10844 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 10845 } else if (!strcasecmp(v->name, "timezone")) { 10846 ast_string_field_set(peer, zonetag, v->value); 10847 } else if (!strcasecmp(v->name, "adsi")) { 10848 peer->adsi = ast_true(v->value); 10849 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 10850 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 10851 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 10852 } else { 10853 peercnt_modify(1, peer->maxcallno, &peer->addr); 10854 } 10855 } else if (!strcasecmp(v->name, "requirecalltoken")) { 10856 /* default is required unless in optional ip list */ 10857 if (ast_false(v->value)) { 10858 peer->calltoken_required = CALLTOKEN_NO; 10859 } else if (!strcasecmp(v->value, "auto")) { 10860 peer->calltoken_required = CALLTOKEN_AUTO; 10861 } else if (ast_true(v->value)) { 10862 peer->calltoken_required = CALLTOKEN_YES; 10863 } else { 10864 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 10865 } 10866 } /* else if (strcasecmp(v->name,"type")) */ 10867 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10868 v = v->next; 10869 if (!v) { 10870 v = alt; 10871 alt = NULL; 10872 } 10873 } 10874 if (!peer->authmethods) 10875 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 10876 ast_clear_flag(peer, IAX_DELME); 10877 /* Make sure these are IPv4 addresses */ 10878 peer->addr.sin_family = AF_INET; 10879 } 10880 if (oldha) 10881 ast_free_ha(oldha); 10882 return peer; 10883 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 5261 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05262 { 05263 long tmp; 05264 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05265 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05266 buf += sizeof(tmp); 05267 len -= sizeof(tmp); 05268 } 05269 }
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 10899 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(), ast_variable::value, and iax2_user::vars.
10900 { 10901 struct iax2_user *user = NULL; 10902 struct iax2_context *con, *conl = NULL; 10903 struct ast_ha *oldha = NULL; 10904 struct iax2_context *oldcon = NULL; 10905 int format; 10906 int firstpass=1; 10907 int oldcurauthreq = 0; 10908 char *varname = NULL, *varval = NULL; 10909 struct ast_variable *tmpvar = NULL; 10910 struct iax2_user tmp_user = { 10911 .name = name, 10912 }; 10913 10914 if (!temponly) { 10915 user = ao2_find(users, &tmp_user, OBJ_POINTER); 10916 if (user && !ast_test_flag(user, IAX_DELME)) 10917 firstpass = 0; 10918 } 10919 10920 if (user) { 10921 if (firstpass) { 10922 oldcurauthreq = user->curauthreq; 10923 oldha = user->ha; 10924 oldcon = user->contexts; 10925 user->ha = NULL; 10926 user->contexts = NULL; 10927 } 10928 /* Already in the list, remove it and it will be added back (or FREE'd) */ 10929 ao2_unlink(users, user); 10930 } else { 10931 user = ao2_alloc(sizeof(*user), user_destructor); 10932 } 10933 10934 if (user) { 10935 if (firstpass) { 10936 ast_string_field_free_memory(user); 10937 memset(user, 0, sizeof(struct iax2_user)); 10938 if (ast_string_field_init(user, 32)) { 10939 user = user_unref(user); 10940 goto cleanup; 10941 } 10942 user->maxauthreq = maxauthreq; 10943 user->curauthreq = oldcurauthreq; 10944 user->prefs = prefs; 10945 user->capability = iax2_capability; 10946 user->encmethods = iax2_encryption; 10947 user->adsi = adsi; 10948 user->calltoken_required = CALLTOKEN_DEFAULT; 10949 ast_string_field_set(user, name, name); 10950 ast_string_field_set(user, language, language); 10951 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 10952 ast_clear_flag(user, IAX_HASCALLERID); 10953 ast_string_field_set(user, cid_name, ""); 10954 ast_string_field_set(user, cid_num, ""); 10955 ast_string_field_set(user, accountcode, accountcode); 10956 ast_string_field_set(user, mohinterpret, mohinterpret); 10957 ast_string_field_set(user, mohsuggest, mohsuggest); 10958 } 10959 if (!v) { 10960 v = alt; 10961 alt = NULL; 10962 } 10963 while(v) { 10964 if (!strcasecmp(v->name, "context")) { 10965 con = build_context(v->value); 10966 if (con) { 10967 if (conl) 10968 conl->next = con; 10969 else 10970 user->contexts = con; 10971 conl = con; 10972 } 10973 } else if (!strcasecmp(v->name, "permit") || 10974 !strcasecmp(v->name, "deny")) { 10975 user->ha = ast_append_ha(v->name, v->value, user->ha); 10976 } else if (!strcasecmp(v->name, "setvar")) { 10977 varname = ast_strdupa(v->value); 10978 if (varname && (varval = strchr(varname,'='))) { 10979 *varval = '\0'; 10980 varval++; 10981 if((tmpvar = ast_variable_new(varname, varval))) { 10982 tmpvar->next = user->vars; 10983 user->vars = tmpvar; 10984 } 10985 } 10986 } else if (!strcasecmp(v->name, "allow")) { 10987 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 10988 } else if (!strcasecmp(v->name, "disallow")) { 10989 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 10990 } else if (!strcasecmp(v->name, "trunk")) { 10991 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 10992 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 10993 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 10994 ast_clear_flag(user, IAX_TRUNK); 10995 } 10996 } else if (!strcasecmp(v->name, "auth")) { 10997 user->authmethods = get_auth_methods(v->value); 10998 } else if (!strcasecmp(v->name, "encryption")) { 10999 user->encmethods = get_encrypt_methods(v->value); 11000 } else if (!strcasecmp(v->name, "notransfer")) { 11001 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11002 ast_clear_flag(user, IAX_TRANSFERMEDIA); 11003 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 11004 } else if (!strcasecmp(v->name, "transfer")) { 11005 if (!strcasecmp(v->value, "mediaonly")) { 11006 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11007 } else if (ast_true(v->value)) { 11008 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11009 } else 11010 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11011 } else if (!strcasecmp(v->name, "codecpriority")) { 11012 if(!strcasecmp(v->value, "caller")) 11013 ast_set_flag(user, IAX_CODEC_USER_FIRST); 11014 else if(!strcasecmp(v->value, "disabled")) 11015 ast_set_flag(user, IAX_CODEC_NOPREFS); 11016 else if(!strcasecmp(v->value, "reqonly")) { 11017 ast_set_flag(user, IAX_CODEC_NOCAP); 11018 ast_set_flag(user, IAX_CODEC_NOPREFS); 11019 } 11020 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11021 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 11022 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11023 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 11024 } else if (!strcasecmp(v->name, "dbsecret")) { 11025 ast_string_field_set(user, dbsecret, v->value); 11026 } else if (!strcasecmp(v->name, "secret")) { 11027 if (!ast_strlen_zero(user->secret)) { 11028 char *old = ast_strdupa(user->secret); 11029 11030 ast_string_field_build(user, secret, "%s;%s", old, v->value); 11031 } else 11032 ast_string_field_set(user, secret, v->value); 11033 } else if (!strcasecmp(v->name, "callerid")) { 11034 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 11035 char name2[80]; 11036 char num2[80]; 11037 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 11038 ast_string_field_set(user, cid_name, name2); 11039 ast_string_field_set(user, cid_num, num2); 11040 ast_set_flag(user, IAX_HASCALLERID); 11041 } else { 11042 ast_clear_flag(user, IAX_HASCALLERID); 11043 ast_string_field_set(user, cid_name, ""); 11044 ast_string_field_set(user, cid_num, ""); 11045 } 11046 } else if (!strcasecmp(v->name, "fullname")) { 11047 if (!ast_strlen_zero(v->value)) { 11048 ast_string_field_set(user, cid_name, v->value); 11049 ast_set_flag(user, IAX_HASCALLERID); 11050 } else { 11051 ast_string_field_set(user, cid_name, ""); 11052 if (ast_strlen_zero(user->cid_num)) 11053 ast_clear_flag(user, IAX_HASCALLERID); 11054 } 11055 } else if (!strcasecmp(v->name, "cid_number")) { 11056 if (!ast_strlen_zero(v->value)) { 11057 ast_string_field_set(user, cid_num, v->value); 11058 ast_set_flag(user, IAX_HASCALLERID); 11059 } else { 11060 ast_string_field_set(user, cid_num, ""); 11061 if (ast_strlen_zero(user->cid_name)) 11062 ast_clear_flag(user, IAX_HASCALLERID); 11063 } 11064 } else if (!strcasecmp(v->name, "accountcode")) { 11065 ast_string_field_set(user, accountcode, v->value); 11066 } else if (!strcasecmp(v->name, "mohinterpret")) { 11067 ast_string_field_set(user, mohinterpret, v->value); 11068 } else if (!strcasecmp(v->name, "mohsuggest")) { 11069 ast_string_field_set(user, mohsuggest, v->value); 11070 } else if (!strcasecmp(v->name, "language")) { 11071 ast_string_field_set(user, language, v->value); 11072 } else if (!strcasecmp(v->name, "amaflags")) { 11073 format = ast_cdr_amaflags2int(v->value); 11074 if (format < 0) { 11075 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11076 } else { 11077 user->amaflags = format; 11078 } 11079 } else if (!strcasecmp(v->name, "inkeys")) { 11080 ast_string_field_set(user, inkeys, v->value); 11081 } else if (!strcasecmp(v->name, "maxauthreq")) { 11082 user->maxauthreq = atoi(v->value); 11083 if (user->maxauthreq < 0) 11084 user->maxauthreq = 0; 11085 } else if (!strcasecmp(v->name, "adsi")) { 11086 user->adsi = ast_true(v->value); 11087 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11088 /* default is required unless in optional ip list */ 11089 if (ast_false(v->value)) { 11090 user->calltoken_required = CALLTOKEN_NO; 11091 } else if (!strcasecmp(v->value, "auto")) { 11092 user->calltoken_required = CALLTOKEN_AUTO; 11093 } else if (ast_true(v->value)) { 11094 user->calltoken_required = CALLTOKEN_YES; 11095 } else { 11096 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11097 } 11098 } /* else if (strcasecmp(v->name,"type")) */ 11099 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11100 v = v->next; 11101 if (!v) { 11102 v = alt; 11103 alt = NULL; 11104 } 11105 } 11106 if (!user->authmethods) { 11107 if (!ast_strlen_zero(user->secret)) { 11108 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11109 if (!ast_strlen_zero(user->inkeys)) 11110 user->authmethods |= IAX_AUTH_RSA; 11111 } else if (!ast_strlen_zero(user->inkeys)) { 11112 user->authmethods = IAX_AUTH_RSA; 11113 } else { 11114 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11115 } 11116 } 11117 ast_clear_flag(user, IAX_DELME); 11118 } 11119 cleanup: 11120 if (oldha) 11121 ast_free_ha(oldha); 11122 if (oldcon) 11123 free_context(oldcon); 11124 return user; 11125 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 11654 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().
11655 { 11656 struct sockaddr_in sin; 11657 int x; 11658 int callno; 11659 struct iax_ie_data ied; 11660 struct create_addr_info cai; 11661 struct parsed_dial_string pds; 11662 char *tmpstr; 11663 11664 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11665 /* Look for an *exact match* call. Once a call is negotiated, it can only 11666 look up entries for a single context */ 11667 if (!ast_mutex_trylock(&iaxsl[x])) { 11668 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 11669 return x; 11670 ast_mutex_unlock(&iaxsl[x]); 11671 } 11672 } 11673 11674 /* No match found, we need to create a new one */ 11675 11676 memset(&cai, 0, sizeof(cai)); 11677 memset(&ied, 0, sizeof(ied)); 11678 memset(&pds, 0, sizeof(pds)); 11679 11680 tmpstr = ast_strdupa(data); 11681 parse_dial_string(tmpstr, &pds); 11682 11683 if (ast_strlen_zero(pds.peer)) { 11684 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 11685 return -1; 11686 } 11687 11688 /* Populate our address from the given */ 11689 if (create_addr(pds.peer, NULL, &sin, &cai)) 11690 return -1; 11691 11692 if (option_debug) 11693 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 11694 pds.peer, pds.username, pds.password, pds.context); 11695 11696 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11697 if (callno < 1) { 11698 ast_log(LOG_WARNING, "Unable to create call\n"); 11699 return -1; 11700 } 11701 11702 ast_string_field_set(iaxs[callno], dproot, data); 11703 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 11704 11705 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 11706 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 11707 /* the string format is slightly different from a standard dial string, 11708 because the context appears in the 'exten' position 11709 */ 11710 if (pds.exten) 11711 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 11712 if (pds.username) 11713 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 11714 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 11715 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 11716 /* Keep password handy */ 11717 if (pds.password) 11718 ast_string_field_set(iaxs[callno], secret, pds.password); 11719 if (pds.key) 11720 ast_string_field_set(iaxs[callno], outkey, pds.key); 11721 /* Start the call going */ 11722 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11723 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 11724 11725 return callno; 11726 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5127 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.
05128 { 05129 /* Returns where in "receive time" we are. That is, how many ms 05130 since we received (or would have received) the frame with timestamp 0 */ 05131 int ms; 05132 #ifdef IAXTESTS 05133 int jit; 05134 #endif /* IAXTESTS */ 05135 /* Setup rxcore if necessary */ 05136 if (ast_tvzero(p->rxcore)) { 05137 p->rxcore = ast_tvnow(); 05138 if (option_debug && iaxdebug) 05139 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05140 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05141 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05142 #if 1 05143 if (option_debug && iaxdebug) 05144 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05145 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05146 #endif 05147 } 05148 05149 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05150 #ifdef IAXTESTS 05151 if (test_jit) { 05152 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05153 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05154 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05155 jit = -jit; 05156 ms += jit; 05157 } 05158 } 05159 if (test_late) { 05160 ms += test_late; 05161 test_late = 0; 05162 } 05163 #endif /* IAXTESTS */ 05164 return ms; 05165 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 4994 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().
04995 { 04996 int ms; 04997 int voice = 0; 04998 int genuine = 0; 04999 int adjust; 05000 int rate = ast_format_rate(f->subclass) / 1000; 05001 struct timeval *delivery = NULL; 05002 05003 05004 /* What sort of frame do we have?: voice is self-explanatory 05005 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05006 non-genuine frames are CONTROL frames [ringing etc], DTMF 05007 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05008 the others need a timestamp slaved to the voice frames so that they go in sequence 05009 */ 05010 if (f) { 05011 if (f->frametype == AST_FRAME_VOICE) { 05012 voice = 1; 05013 delivery = &f->delivery; 05014 } else if (f->frametype == AST_FRAME_IAX) { 05015 genuine = 1; 05016 } else if (f->frametype == AST_FRAME_CNG) { 05017 p->notsilenttx = 0; 05018 } 05019 } 05020 if (ast_tvzero(p->offset)) { 05021 gettimeofday(&p->offset, NULL); 05022 /* Round to nearest 20ms for nice looking traces */ 05023 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05024 } 05025 /* If the timestamp is specified, just send it as is */ 05026 if (ts) 05027 return ts; 05028 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05029 if (delivery && !ast_tvzero(*delivery)) { 05030 ms = ast_tvdiff_ms(*delivery, p->offset); 05031 if (ms < 0) { 05032 ms = 0; 05033 } 05034 if (option_debug > 2 && iaxdebug) 05035 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05036 } else { 05037 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05038 if (ms < 0) 05039 ms = 0; 05040 if (voice) { 05041 /* On a voice frame, use predicted values if appropriate */ 05042 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05043 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05044 /* AN EXPLANATION: 05045 When we send voice, we usually send "calculated" timestamps worked out 05046 on the basis of the number of samples sent. When we send other frames, 05047 we usually send timestamps worked out from the real clock. 05048 The problem is that they can tend to drift out of step because the 05049 source channel's clock and our clock may not be exactly at the same rate. 05050 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05051 for this call. Moving it adjusts timestamps for non-voice frames. 05052 We make the adjustment in the style of a moving average. Each time we 05053 adjust p->offset by 10% of the difference between our clock-derived 05054 timestamp and the predicted timestamp. That's why you see "10000" 05055 below even though IAX2 timestamps are in milliseconds. 05056 The use of a moving average avoids offset moving too radically. 05057 Generally, "adjust" roams back and forth around 0, with offset hardly 05058 changing at all. But if a consistent different starts to develop it 05059 will be eliminated over the course of 10 frames (200-300msecs) 05060 */ 05061 adjust = (ms - p->nextpred); 05062 if (adjust < 0) 05063 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05064 else if (adjust > 0) 05065 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05066 05067 if (!p->nextpred) { 05068 p->nextpred = ms; /*f->samples / rate;*/ 05069 if (p->nextpred <= p->lastsent) 05070 p->nextpred = p->lastsent + 3; 05071 } 05072 ms = p->nextpred; 05073 } else { 05074 /* in this case, just use the actual 05075 * time, since we're either way off 05076 * (shouldn't happen), or we're ending a 05077 * silent period -- and seed the next 05078 * predicted time. Also, round ms to the 05079 * next multiple of frame size (so our 05080 * silent periods are multiples of 05081 * frame size too) */ 05082 05083 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05084 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05085 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05086 05087 if (f->samples >= rate) /* check to make sure we dont core dump */ 05088 { 05089 int diff = ms % (f->samples / rate); 05090 if (diff) 05091 ms += f->samples/rate - diff; 05092 } 05093 05094 p->nextpred = ms; 05095 p->notsilenttx = 1; 05096 } 05097 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05098 /* 05099 * IAX2 draft 03 says that timestamps MUST be in order. 05100 * It does not say anything about several frames having the same timestamp 05101 * When transporting video, we can have a frame that spans multiple iax packets 05102 * (so called slices), so it would make sense to use the same timestamp for all of 05103 * them 05104 * We do want to make sure that frames don't go backwards though 05105 */ 05106 if ( (unsigned int)ms < p->lastsent ) 05107 ms = p->lastsent; 05108 } else { 05109 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05110 it's a genuine frame */ 05111 if (genuine) { 05112 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05113 if (ms <= p->lastsent) 05114 ms = p->lastsent + 3; 05115 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05116 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05117 ms = p->lastsent + 3; 05118 } 05119 } 05120 } 05121 p->lastsent = ms; 05122 if (voice) 05123 p->nextpred = p->nextpred + f->samples / rate; 05124 return ms; 05125 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 4950 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().
04951 { 04952 unsigned long int mssincetx; /* unsigned to handle overflows */ 04953 long int ms, pred; 04954 04955 tpeer->trunkact = *tv; 04956 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 04957 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 04958 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 04959 tpeer->txtrunktime = *tv; 04960 tpeer->lastsent = 999999; 04961 } 04962 /* Update last transmit time now */ 04963 tpeer->lasttxtime = *tv; 04964 04965 /* Calculate ms offset */ 04966 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 04967 /* Predict from last value */ 04968 pred = tpeer->lastsent + sampms; 04969 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 04970 ms = pred; 04971 04972 /* We never send the same timestamp twice, so fudge a little if we must */ 04973 if (ms == tpeer->lastsent) 04974 ms = tpeer->lastsent + 1; 04975 tpeer->lastsent = ms; 04976 return ms; 04977 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2200 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02201 { 02202 return abs(ast_random()); 02203 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 1761 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(), S_OR, and user_unref().
Referenced by handle_call_token().
01762 { 01763 struct addr_range *addr_range; 01764 struct iax2_peer *peer = NULL; 01765 struct iax2_user *user = NULL; 01766 /* if no username is given, check for guest accounts */ 01767 const char *find = S_OR(name, "guest"); 01768 int res = 1; /* required by default */ 01769 int optional = 0; 01770 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 01771 /* There are only two cases in which calltoken validation is not required. 01772 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 01773 * the peer definition has not set the requirecalltoken option. 01774 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 01775 */ 01776 01777 /* ----- Case 1 ----- */ 01778 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 01779 ao2_ref(addr_range, -1); 01780 optional = 1; 01781 } 01782 01783 /* ----- Case 2 ----- */ 01784 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 01785 calltoken_required = user->calltoken_required; 01786 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 1))) { 01787 calltoken_required = peer->calltoken_required; 01788 } 01789 01790 if (peer) { 01791 peer_unref(peer); 01792 } 01793 if (user) { 01794 user_unref(user); 01795 } 01796 if (option_debug) { 01797 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); 01798 } 01799 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 01800 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 01801 res = 0; 01802 } 01803 01804 return res; 01805 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6296 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_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, 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_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(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
06297 { 06298 /* Start pessimistic */ 06299 int res = -1; 06300 int version = 2; 06301 struct iax2_user *user = NULL, *best = NULL; 06302 int bestscore = 0; 06303 int gotcapability = 0; 06304 struct ast_variable *v = NULL, *tmpvar = NULL; 06305 struct ao2_iterator i; 06306 06307 if (!iaxs[callno]) 06308 return res; 06309 if (ies->called_number) 06310 ast_string_field_set(iaxs[callno], exten, ies->called_number); 06311 if (ies->calling_number) { 06312 ast_shrink_phone_number(ies->calling_number); 06313 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 06314 } 06315 if (ies->calling_name) 06316 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 06317 if (ies->calling_ani) 06318 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 06319 if (ies->dnid) 06320 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 06321 if (ies->rdnis) 06322 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 06323 if (ies->called_context) 06324 ast_string_field_set(iaxs[callno], context, ies->called_context); 06325 if (ies->language) 06326 ast_string_field_set(iaxs[callno], language, ies->language); 06327 if (ies->username) 06328 ast_string_field_set(iaxs[callno], username, ies->username); 06329 if (ies->calling_ton > -1) 06330 iaxs[callno]->calling_ton = ies->calling_ton; 06331 if (ies->calling_tns > -1) 06332 iaxs[callno]->calling_tns = ies->calling_tns; 06333 if (ies->calling_pres > -1) 06334 iaxs[callno]->calling_pres = ies->calling_pres; 06335 if (ies->format) 06336 iaxs[callno]->peerformat = ies->format; 06337 if (ies->adsicpe) 06338 iaxs[callno]->peeradsicpe = ies->adsicpe; 06339 if (ies->capability) { 06340 gotcapability = 1; 06341 iaxs[callno]->peercapability = ies->capability; 06342 } 06343 if (ies->version) 06344 version = ies->version; 06345 06346 /* Use provided preferences until told otherwise for actual preferences */ 06347 if(ies->codec_prefs) { 06348 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 06349 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 06350 } 06351 06352 if (!gotcapability) 06353 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 06354 if (version > IAX_PROTO_VERSION) { 06355 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 06356 ast_inet_ntoa(sin->sin_addr), version); 06357 return res; 06358 } 06359 /* Search the userlist for a compatible entry, and fill in the rest */ 06360 i = ao2_iterator_init(users, 0); 06361 while ((user = ao2_iterator_next(&i))) { 06362 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 06363 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 06364 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 06365 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 06366 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 06367 if (!ast_strlen_zero(iaxs[callno]->username)) { 06368 /* Exact match, stop right now. */ 06369 if (best) 06370 user_unref(best); 06371 best = user; 06372 break; 06373 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 06374 /* No required authentication */ 06375 if (user->ha) { 06376 /* There was host authentication and we passed, bonus! */ 06377 if (bestscore < 4) { 06378 bestscore = 4; 06379 if (best) 06380 user_unref(best); 06381 best = user; 06382 continue; 06383 } 06384 } else { 06385 /* No host access, but no secret, either, not bad */ 06386 if (bestscore < 3) { 06387 bestscore = 3; 06388 if (best) 06389 user_unref(best); 06390 best = user; 06391 continue; 06392 } 06393 } 06394 } else { 06395 if (user->ha) { 06396 /* Authentication, but host access too, eh, it's something.. */ 06397 if (bestscore < 2) { 06398 bestscore = 2; 06399 if (best) 06400 user_unref(best); 06401 best = user; 06402 continue; 06403 } 06404 } else { 06405 /* Authentication and no host access... This is our baseline */ 06406 if (bestscore < 1) { 06407 bestscore = 1; 06408 if (best) 06409 user_unref(best); 06410 best = user; 06411 continue; 06412 } 06413 } 06414 } 06415 } 06416 user_unref(user); 06417 } 06418 user = best; 06419 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 06420 user = realtime_user(iaxs[callno]->username, sin); 06421 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 06422 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 06423 user = user_unref(user); 06424 } 06425 } 06426 if (user) { 06427 /* We found our match (use the first) */ 06428 /* copy vars */ 06429 for (v = user->vars ; v ; v = v->next) { 06430 if((tmpvar = ast_variable_new(v->name, v->value))) { 06431 tmpvar->next = iaxs[callno]->vars; 06432 iaxs[callno]->vars = tmpvar; 06433 } 06434 } 06435 /* If a max AUTHREQ restriction is in place, activate it */ 06436 if (user->maxauthreq > 0) 06437 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 06438 iaxs[callno]->prefs = user->prefs; 06439 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 06440 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 06441 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 06442 iaxs[callno]->encmethods = user->encmethods; 06443 /* Store the requested username if not specified */ 06444 if (ast_strlen_zero(iaxs[callno]->username)) 06445 ast_string_field_set(iaxs[callno], username, user->name); 06446 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 06447 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 06448 iaxs[callno]->capability = user->capability; 06449 /* And use the default context */ 06450 if (ast_strlen_zero(iaxs[callno]->context)) { 06451 if (user->contexts) 06452 ast_string_field_set(iaxs[callno], context, user->contexts->context); 06453 else 06454 ast_string_field_set(iaxs[callno], context, context); 06455 } 06456 /* And any input keys */ 06457 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 06458 /* And the permitted authentication methods */ 06459 iaxs[callno]->authmethods = user->authmethods; 06460 iaxs[callno]->adsi = user->adsi; 06461 /* If the user has callerid, override the remote caller id. */ 06462 if (ast_test_flag(user, IAX_HASCALLERID)) { 06463 iaxs[callno]->calling_tns = 0; 06464 iaxs[callno]->calling_ton = 0; 06465 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 06466 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 06467 ast_string_field_set(iaxs[callno], ani, user->cid_num); 06468 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 06469 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 06470 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 06471 } /* else user is allowed to set their own CID settings */ 06472 if (!ast_strlen_zero(user->accountcode)) 06473 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 06474 if (!ast_strlen_zero(user->mohinterpret)) 06475 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 06476 if (!ast_strlen_zero(user->mohsuggest)) 06477 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 06478 if (user->amaflags) 06479 iaxs[callno]->amaflags = user->amaflags; 06480 if (!ast_strlen_zero(user->language)) 06481 ast_string_field_set(iaxs[callno], language, user->language); 06482 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 06483 /* Keep this check last */ 06484 if (!ast_strlen_zero(user->dbsecret)) { 06485 char *family, *key=NULL; 06486 char buf[80]; 06487 family = ast_strdupa(user->dbsecret); 06488 key = strchr(family, '/'); 06489 if (key) { 06490 *key = '\0'; 06491 key++; 06492 } 06493 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 06494 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 06495 else 06496 ast_string_field_set(iaxs[callno], secret, buf); 06497 } else 06498 ast_string_field_set(iaxs[callno], secret, user->secret); 06499 res = 0; 06500 user = user_unref(user); 06501 } else { 06502 /* user was not found, but we should still fake an AUTHREQ. 06503 * Set authmethods to the last known authmethod used by the system 06504 * Set a fake secret, it's not looked at, just required to attempt authentication. 06505 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 06506 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06507 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06508 iaxs[callno]->authrej = 1; 06509 if (!ast_strlen_zero(iaxs[callno]->username)) { 06510 /* only send the AUTHREQ if a username was specified. */ 06511 res = 0; 06512 } 06513 } 06514 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 06515 return res; 06516 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 8052 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
08053 { 08054 unsigned int ourver; 08055 char rsi[80]; 08056 snprintf(rsi, sizeof(rsi), "si-%s", si); 08057 if (iax_provision_version(&ourver, rsi, 1)) 08058 return 0; 08059 if (option_debug) 08060 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 08061 if (ourver != ver) 08062 iax2_provision(sin, sockfd, NULL, rsi, 1); 08063 return 0; 08064 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 10524 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
10525 { 10526 int sd; 10527 int res; 10528 10529 sd = socket(AF_INET, SOCK_DGRAM, 0); 10530 if (sd < 0) { 10531 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 10532 return -1; 10533 } 10534 10535 res = bind(sd, sa, salen); 10536 if (res < 0) { 10537 if (option_debug) 10538 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 10539 close(sd); 10540 return 1; 10541 } 10542 10543 close(sd); 10544 return 0; 10545 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7023 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().
07024 { 07025 char exten[256] = ""; 07026 int status = CACHE_FLAG_UNKNOWN; 07027 int expiry = iaxdefaultdpcache; 07028 int x; 07029 int matchmore = 0; 07030 struct iax2_dpcache *dp, *prev; 07031 07032 if (ies->called_number) 07033 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07034 07035 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07036 status = CACHE_FLAG_EXISTS; 07037 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07038 status = CACHE_FLAG_CANEXIST; 07039 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07040 status = CACHE_FLAG_NONEXISTENT; 07041 07042 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 07043 /* Don't really do anything with this */ 07044 } 07045 if (ies->refresh) 07046 expiry = ies->refresh; 07047 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07048 matchmore = CACHE_FLAG_MATCHMORE; 07049 ast_mutex_lock(&dpcache_lock); 07050 prev = NULL; 07051 dp = pvt->dpentries; 07052 while(dp) { 07053 if (!strcmp(dp->exten, exten)) { 07054 /* Let them go */ 07055 if (prev) 07056 prev->peer = dp->peer; 07057 else 07058 pvt->dpentries = dp->peer; 07059 dp->peer = NULL; 07060 dp->callno = 0; 07061 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 07062 if (dp->flags & CACHE_FLAG_PENDING) { 07063 dp->flags &= ~CACHE_FLAG_PENDING; 07064 dp->flags |= status; 07065 dp->flags |= matchmore; 07066 } 07067 /* Wake up waiters */ 07068 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 07069 if (dp->waiters[x] > -1) { 07070 if (write(dp->waiters[x], "asdf", 4) < 0) { 07071 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 07072 } 07073 } 07074 } 07075 } 07076 prev = dp; 07077 dp = dp->peer; 07078 } 07079 ast_mutex_unlock(&dpcache_lock); 07080 return 0; 07081 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3253 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, and peer_unref().
03254 { 03255 int which = 0; 03256 struct iax2_peer *peer; 03257 char *res = NULL; 03258 int wordlen = strlen(word); 03259 struct ao2_iterator i; 03260 03261 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 03262 if (pos != 3) 03263 return NULL; 03264 03265 i = ao2_iterator_init(peers, 0); 03266 while ((peer = ao2_iterator_next(&i))) { 03267 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 03268 res = ast_strdup(peer->name); 03269 peer_unref(peer); 03270 break; 03271 } 03272 peer_unref(peer); 03273 } 03274 03275 return res; 03276 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7083 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().
07084 { 07085 int peercallno = 0; 07086 struct chan_iax2_pvt *pvt = iaxs[callno]; 07087 struct iax_frame *cur; 07088 jb_frame frame; 07089 07090 if (ies->callno) 07091 peercallno = ies->callno; 07092 07093 if (peercallno < 1) { 07094 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07095 return -1; 07096 } 07097 remove_by_transfercallno(pvt); 07098 /* since a transfer has taken place, the address will change. 07099 * This must be accounted for in the peercnts table. Remove 07100 * the old address and add the new one */ 07101 peercnt_remove_by_addr(&pvt->addr); 07102 peercnt_add(&pvt->transfer); 07103 /* now copy over the new address */ 07104 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 07105 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 07106 /* Reset sequence numbers */ 07107 pvt->oseqno = 0; 07108 pvt->rseqno = 0; 07109 pvt->iseqno = 0; 07110 pvt->aseqno = 0; 07111 07112 if (pvt->peercallno) { 07113 remove_by_peercallno(pvt); 07114 } 07115 pvt->peercallno = peercallno; 07116 /*this is where the transfering call swiches hash tables */ 07117 store_by_peercallno(pvt); 07118 pvt->transferring = TRANSFER_NONE; 07119 pvt->svoiceformat = -1; 07120 pvt->voiceformat = 0; 07121 pvt->svideoformat = -1; 07122 pvt->videoformat = 0; 07123 pvt->transfercallno = -1; 07124 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 07125 memset(&pvt->offset, 0, sizeof(pvt->offset)); 07126 /* reset jitterbuffer */ 07127 while(jb_getall(pvt->jb,&frame) == JB_OK) 07128 iax2_frame_free(frame.data); 07129 jb_reset(pvt->jb); 07130 pvt->lag = 0; 07131 pvt->last = 0; 07132 pvt->lastsent = 0; 07133 pvt->nextpred = 0; 07134 pvt->pingtime = DEFAULT_RETRY_TIME; 07135 AST_LIST_LOCK(&iaxq.queue); 07136 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07137 /* We must cancel any packets that would have been transmitted 07138 because now we're talking to someone new. It's okay, they 07139 were transmitted to someone that didn't care anyway. */ 07140 if (callno == cur->callno) 07141 cur->retries = -1; 07142 } 07143 AST_LIST_UNLOCK(&iaxq.queue); 07144 return 0; 07145 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1183 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().
01184 { 01185 int x; 01186 int power=-1; 01187 /* If it's 128 or smaller, just return it */ 01188 if (subclass < IAX_FLAG_SC_LOG) 01189 return subclass; 01190 /* Otherwise find its power */ 01191 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01192 if (subclass & (1 << x)) { 01193 if (power > -1) { 01194 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01195 return 0; 01196 } else 01197 power = x; 01198 } 01199 } 01200 return power | IAX_FLAG_SC_LOG; 01201 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 8066 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().
08067 { 08068 jb_info stats; 08069 jb_getinfo(pvt->jb, &stats); 08070 08071 memset(iep, 0, sizeof(*iep)); 08072 08073 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 08074 if(stats.frames_in == 0) stats.frames_in = 1; 08075 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 08076 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 08077 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 08078 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 08079 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 08080 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3876 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.
03877 { 03878 struct ast_hostent ahp; 03879 struct hostent *hp; 03880 struct iax2_peer *peer; 03881 int res = -1; 03882 struct ast_codec_pref ourprefs; 03883 03884 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03885 cai->sockfd = defaultsockfd; 03886 cai->maxtime = 0; 03887 sin->sin_family = AF_INET; 03888 03889 if (!(peer = find_peer(peername, 1))) { 03890 cai->found = 0; 03891 03892 hp = ast_gethostbyname(peername, &ahp); 03893 if (hp) { 03894 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03895 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03896 /* use global iax prefs for unknown peer/user */ 03897 /* But move the calling channel's native codec to the top of the preference list */ 03898 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03899 if (c) 03900 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03901 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03902 return 0; 03903 } else { 03904 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03905 return -1; 03906 } 03907 } 03908 03909 cai->found = 1; 03910 03911 /* if the peer has no address (current or default), return failure */ 03912 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03913 goto return_unref; 03914 03915 /* if the peer is being monitored and is currently unreachable, return failure */ 03916 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03917 goto return_unref; 03918 03919 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03920 cai->maxtime = peer->maxms; 03921 cai->capability = peer->capability; 03922 cai->encmethods = peer->encmethods; 03923 cai->sockfd = peer->sockfd; 03924 cai->adsi = peer->adsi; 03925 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03926 /* Move the calling channel's native codec to the top of the preference list */ 03927 if (c) { 03928 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03929 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03930 } 03931 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03932 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03933 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03934 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03935 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03936 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03937 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03938 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03939 if (ast_strlen_zero(peer->dbsecret)) { 03940 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03941 } else { 03942 char *family; 03943 char *key = NULL; 03944 03945 family = ast_strdupa(peer->dbsecret); 03946 key = strchr(family, '/'); 03947 if (key) 03948 *key++ = '\0'; 03949 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03950 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03951 goto return_unref; 03952 } 03953 } 03954 03955 if (peer->addr.sin_addr.s_addr) { 03956 sin->sin_addr = peer->addr.sin_addr; 03957 sin->sin_port = peer->addr.sin_port; 03958 } else { 03959 sin->sin_addr = peer->defaddr.sin_addr; 03960 sin->sin_port = peer->defaddr.sin_port; 03961 } 03962 03963 res = 0; 03964 03965 return_unref: 03966 peer_unref(peer); 03967 03968 return res; 03969 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2205 of file chan_iax2.c.
References ao2_alloc(), ao2_container_alloc(), ao2_ref(), callno_hash(), callno_pool, CALLNO_POOL_BUCKETS, callno_pool_trunk, IAX_MAX_CALLS, and TRUNK_CALL_START.
Referenced by load_objects().
02206 { 02207 uint16_t i; 02208 02209 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02210 return -1; 02211 } 02212 02213 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02214 return -1; 02215 } 02216 02217 /* start at 2, 0 and 1 are reserved */ 02218 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02219 struct callno_entry *callno_entry; 02220 02221 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02222 return -1; 02223 } 02224 02225 callno_entry->callno = i; 02226 02227 if (i < TRUNK_CALL_START) { 02228 ao2_link(callno_pool, callno_entry); 02229 } else { 02230 ao2_link(callno_pool_trunk, callno_entry); 02231 } 02232 02233 ao2_ref(callno_entry, -1); 02234 } 02235 02236 return 0; 02237 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5335 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().
05336 { 05337 int padding; 05338 unsigned char *workspace; 05339 05340 workspace = alloca(*datalen); 05341 memset(f, 0, sizeof(*f)); 05342 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05343 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05344 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05345 return -1; 05346 /* Decrypt */ 05347 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05348 05349 padding = 16 + (workspace[15] & 0x0f); 05350 if (option_debug && iaxdebug) 05351 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05352 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05353 return -1; 05354 05355 *datalen -= padding; 05356 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05357 f->frametype = fh->type; 05358 if (f->frametype == AST_FRAME_VIDEO) { 05359 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05360 } else { 05361 f->subclass = uncompress_subclass(fh->csub); 05362 } 05363 } else { 05364 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05365 if (option_debug && iaxdebug) 05366 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 05367 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05368 return -1; 05369 /* Decrypt */ 05370 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05371 padding = 16 + (workspace[15] & 0x0f); 05372 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05373 return -1; 05374 *datalen -= padding; 05375 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05376 } 05377 return 0; 05378 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 5421 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().
05422 { 05423 int res=-1; 05424 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 05425 /* Search for possible keys, given secrets */ 05426 struct MD5Context md5; 05427 unsigned char digest[16]; 05428 char *tmppw, *stringp; 05429 05430 tmppw = ast_strdupa(iaxs[callno]->secret); 05431 stringp = tmppw; 05432 while ((tmppw = strsep(&stringp, ";"))) { 05433 MD5Init(&md5); 05434 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05435 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05436 MD5Final(digest, &md5); 05437 build_encryption_keys(digest, iaxs[callno]); 05438 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05439 if (!res) { 05440 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 05441 break; 05442 } 05443 } 05444 } else 05445 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05446 return res; 05447 }
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 8128 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().
08129 { 08130 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 08131 struct ast_iax2_full_hdr *fh, *cur_fh; 08132 08133 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 08134 return; 08135 08136 pkt_buf->len = from_here->buf_len; 08137 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 08138 08139 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 08140 ast_mutex_lock(&to_here->lock); 08141 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 08142 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 08143 if (fh->oseqno < cur_fh->oseqno) { 08144 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 08145 break; 08146 } 08147 } 08148 AST_LIST_TRAVERSE_SAFE_END 08149 08150 if (!cur_pkt_buf) 08151 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 08152 08153 ast_mutex_unlock(&to_here->lock); 08154 }
static void delete_users | ( | void | ) | [static] |
Definition at line 11145 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(), chan_iax2_pvt::reg, sched, and user_delme_cb().
11146 { 11147 struct iax2_registry *reg; 11148 11149 ao2_callback(users, 0, user_delme_cb, NULL); 11150 11151 AST_LIST_LOCK(®istrations); 11152 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 11153 ast_sched_del(sched, reg->expire); 11154 if (reg->callno) { 11155 int callno = reg->callno; 11156 ast_mutex_lock(&iaxsl[callno]); 11157 if (iaxs[callno]) { 11158 iaxs[callno]->reg = NULL; 11159 iax2_destroy(callno); 11160 } 11161 ast_mutex_unlock(&iaxsl[callno]); 11162 } 11163 if (reg->dnsmgr) 11164 ast_dnsmgr_release(reg->dnsmgr); 11165 free(reg); 11166 } 11167 AST_LIST_UNLOCK(®istrations); 11168 11169 ao2_callback(peers, 0, peer_delme_cb, NULL); 11170 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2567 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
02568 { 02569 /* Close firmware */ 02570 if (cur->fwh) { 02571 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02572 } 02573 close(cur->fd); 02574 free(cur); 02575 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 7900 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().
07901 { 07902 unsigned short dpstatus = 0; 07903 struct iax_ie_data ied1; 07904 int mm; 07905 07906 memset(&ied1, 0, sizeof(ied1)); 07907 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 07908 /* Must be started */ 07909 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 07910 dpstatus = IAX_DPSTATUS_EXISTS; 07911 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 07912 dpstatus = IAX_DPSTATUS_CANEXIST; 07913 } else { 07914 dpstatus = IAX_DPSTATUS_NONEXISTENT; 07915 } 07916 if (ast_ignore_pattern(context, callednum)) 07917 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 07918 if (mm) 07919 dpstatus |= IAX_DPSTATUS_MATCHMORE; 07920 if (!skiplock) 07921 ast_mutex_lock(&iaxsl[callno]); 07922 if (iaxs[callno]) { 07923 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 07924 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 07925 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 07926 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 07927 } 07928 if (!skiplock) 07929 ast_mutex_unlock(&iaxsl[callno]); 07930 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 7932 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().
07933 { 07934 /* Look up for dpreq */ 07935 struct dpreq_data *dpr = data; 07936 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 07937 if (dpr->callerid) 07938 free(dpr->callerid); 07939 free(dpr); 07940 return NULL; 07941 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 5380 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().
05381 { 05382 int padding; 05383 unsigned char *workspace; 05384 workspace = alloca(*datalen + 32); 05385 if (!workspace) 05386 return -1; 05387 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05388 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05389 if (option_debug && iaxdebug) 05390 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05391 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05392 padding = 16 + (padding & 0xf); 05393 memcpy(workspace, poo, padding); 05394 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05395 workspace[15] &= 0xf0; 05396 workspace[15] |= (padding & 0xf); 05397 if (option_debug && iaxdebug) 05398 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]); 05399 *datalen += padding; 05400 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05401 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05402 memcpy(poo, workspace + *datalen - 32, 32); 05403 } else { 05404 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05405 if (option_debug && iaxdebug) 05406 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 05407 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 05408 padding = 16 + (padding & 0xf); 05409 memcpy(workspace, poo, padding); 05410 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05411 workspace[15] &= 0xf0; 05412 workspace[15] |= (padding & 0x0f); 05413 *datalen += padding; 05414 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 05415 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 05416 memcpy(poo, workspace + *datalen - 32, 32); 05417 } 05418 return 0; 05419 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 7329 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
07330 { 07331 #ifdef SCHED_MULTITHREADED 07332 if (schedule_action(__expire_registry, data)) 07333 #endif 07334 __expire_registry(data); 07335 return 0; 07336 }
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 11728 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().
11729 { 11730 struct iax2_dpcache *dp, *prev = NULL, *next; 11731 struct timeval tv; 11732 int x; 11733 int com[2]; 11734 int timeout; 11735 int old=0; 11736 int outfd; 11737 int abort; 11738 int callno; 11739 struct ast_channel *c; 11740 struct ast_frame *f; 11741 gettimeofday(&tv, NULL); 11742 dp = dpcache; 11743 while(dp) { 11744 next = dp->next; 11745 /* Expire old caches */ 11746 if (ast_tvcmp(tv, dp->expiry) > 0) { 11747 /* It's expired, let it disappear */ 11748 if (prev) 11749 prev->next = dp->next; 11750 else 11751 dpcache = dp->next; 11752 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 11753 /* Free memory and go again */ 11754 free(dp); 11755 } else { 11756 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); 11757 } 11758 dp = next; 11759 continue; 11760 } 11761 /* We found an entry that matches us! */ 11762 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 11763 break; 11764 prev = dp; 11765 dp = next; 11766 } 11767 if (!dp) { 11768 /* No matching entry. Create a new one. */ 11769 /* First, can we make a callno? */ 11770 callno = cache_get_callno_locked(data); 11771 if (callno < 0) { 11772 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 11773 return NULL; 11774 } 11775 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 11776 ast_mutex_unlock(&iaxsl[callno]); 11777 return NULL; 11778 } 11779 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 11780 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 11781 gettimeofday(&dp->expiry, NULL); 11782 dp->orig = dp->expiry; 11783 /* Expires in 30 mins by default */ 11784 dp->expiry.tv_sec += iaxdefaultdpcache; 11785 dp->next = dpcache; 11786 dp->flags = CACHE_FLAG_PENDING; 11787 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 11788 dp->waiters[x] = -1; 11789 dpcache = dp; 11790 dp->peer = iaxs[callno]->dpentries; 11791 iaxs[callno]->dpentries = dp; 11792 /* Send the request if we're already up */ 11793 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 11794 iax2_dprequest(dp, callno); 11795 ast_mutex_unlock(&iaxsl[callno]); 11796 } 11797 /* By here we must have a dp */ 11798 if (dp->flags & CACHE_FLAG_PENDING) { 11799 /* Okay, here it starts to get nasty. We need a pipe now to wait 11800 for a reply to come back so long as it's pending */ 11801 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 11802 /* Find an empty slot */ 11803 if (dp->waiters[x] < 0) 11804 break; 11805 } 11806 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 11807 ast_log(LOG_WARNING, "No more waiter positions available\n"); 11808 return NULL; 11809 } 11810 if (pipe(com)) { 11811 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 11812 return NULL; 11813 } 11814 dp->waiters[x] = com[1]; 11815 /* Okay, now we wait */ 11816 timeout = iaxdefaulttimeout * 1000; 11817 /* Temporarily unlock */ 11818 ast_mutex_unlock(&dpcache_lock); 11819 /* Defer any dtmf */ 11820 if (chan) 11821 old = ast_channel_defer_dtmf(chan); 11822 abort = 0; 11823 while(timeout) { 11824 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 11825 if (outfd > -1) { 11826 break; 11827 } 11828 if (c) { 11829 f = ast_read(c); 11830 if (f) 11831 ast_frfree(f); 11832 else { 11833 /* Got hung up on, abort! */ 11834 break; 11835 abort = 1; 11836 } 11837 } 11838 } 11839 if (!timeout) { 11840 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 11841 } 11842 ast_mutex_lock(&dpcache_lock); 11843 dp->waiters[x] = -1; 11844 close(com[1]); 11845 close(com[0]); 11846 if (abort) { 11847 /* Don't interpret anything, just abort. Not sure what th epoint 11848 of undeferring dtmf on a hung up channel is but hey whatever */ 11849 if (!old && chan) 11850 ast_channel_undefer_dtmf(chan); 11851 return NULL; 11852 } 11853 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 11854 /* Now to do non-independent analysis the results of our wait */ 11855 if (dp->flags & CACHE_FLAG_PENDING) { 11856 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 11857 pending. Don't let it take as long to timeout. */ 11858 dp->flags &= ~CACHE_FLAG_PENDING; 11859 dp->flags |= CACHE_FLAG_TIMEOUT; 11860 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 11861 systems without leaving it unavailable once the server comes back online */ 11862 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 11863 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 11864 if (dp->waiters[x] > -1) { 11865 if (write(dp->waiters[x], "asdf", 4) < 0) { 11866 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 11867 } 11868 } 11869 } 11870 } 11871 } 11872 /* Our caller will obtain the rest */ 11873 if (!old && chan) 11874 ast_channel_undefer_dtmf(chan); 11875 } 11876 return dp; 11877 }
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 2467 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02467 { 02468 02469 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02470 }
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 2472 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
02472 { 02473 02474 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02475 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1016 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().
01017 { 01018 pthread_attr_t attr; 01019 struct iax2_thread *thread = NULL; 01020 01021 /* Pop the head of the list off */ 01022 AST_LIST_LOCK(&idle_list); 01023 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01024 AST_LIST_UNLOCK(&idle_list); 01025 01026 /* If no idle thread is available from the regular list, try dynamic */ 01027 if (thread == NULL) { 01028 AST_LIST_LOCK(&dynamic_list); 01029 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01030 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 01031 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 01032 /* We need to MAKE a thread! */ 01033 if ((thread = ast_calloc(1, sizeof(*thread)))) { 01034 thread->threadnum = iaxdynamicthreadnum++; 01035 thread->type = IAX_TYPE_DYNAMIC; 01036 ast_mutex_init(&thread->lock); 01037 ast_cond_init(&thread->cond, NULL); 01038 pthread_attr_init(&attr); 01039 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01040 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 01041 free(thread); 01042 thread = NULL; 01043 } else { 01044 /* All went well and the thread is up, so increment our count */ 01045 iaxdynamicthreadcount++; 01046 01047 /* Wait for the thread to be ready before returning it to the caller */ 01048 while (!thread->ready_for_signal) 01049 usleep(1); 01050 } 01051 } 01052 } 01053 AST_LIST_UNLOCK(&dynamic_list); 01054 } 01055 01056 /* this thread is not processing a full frame (since it is idle), 01057 so ensure that the field for the full frame call number is empty */ 01058 if (thread) 01059 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01060 01061 return thread; 01062 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1261 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, and realtime_peer().
01262 { 01263 struct iax2_peer *peer = NULL; 01264 struct iax2_peer tmp_peer = { 01265 .name = name, 01266 }; 01267 01268 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01269 01270 /* Now go for realtime if applicable */ 01271 if(!peer && realtime) 01272 peer = realtime_peer(name, NULL); 01273 01274 return peer; 01275 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 5167 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().
05168 { 05169 struct iax2_trunk_peer *tpeer; 05170 05171 /* Finds and locks trunk peer */ 05172 ast_mutex_lock(&tpeerlock); 05173 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 05174 /* We don't lock here because tpeer->addr *never* changes */ 05175 if (!inaddrcmp(&tpeer->addr, sin)) { 05176 ast_mutex_lock(&tpeer->lock); 05177 break; 05178 } 05179 } 05180 if (!tpeer) { 05181 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05182 ast_mutex_init(&tpeer->lock); 05183 tpeer->lastsent = 9999; 05184 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05185 tpeer->trunkact = ast_tvnow(); 05186 ast_mutex_lock(&tpeer->lock); 05187 tpeer->next = tpeers; 05188 tpeer->sockfd = fd; 05189 tpeers = tpeer; 05190 #ifdef SO_NO_CHECK 05191 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05192 #endif 05193 if (option_debug) 05194 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05195 } 05196 } 05197 ast_mutex_unlock(&tpeerlock); 05198 return tpeer; 05199 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1289 of file chan_iax2.c.
References ao2_find(), and iax2_user::name.
01290 { 01291 struct iax2_user tmp_user = { 01292 .name = name, 01293 }; 01294 01295 return ao2_find(users, &tmp_user, OBJ_POINTER); 01296 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 4979 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
04980 { 04981 long ms; /* NOT unsigned */ 04982 if (ast_tvzero(iaxs[callno]->rxcore)) { 04983 /* Initialize rxcore time if appropriate */ 04984 gettimeofday(&iaxs[callno]->rxcore, NULL); 04985 /* Round to nearest 20ms so traces look pretty */ 04986 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 04987 } 04988 /* Calculate difference between trunk and channel */ 04989 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 04990 /* Return as the sum of trunk time and the difference between trunk and real time */ 04991 return ms + ts; 04992 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 10276 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
10277 { 10278 struct iax2_context *conl; 10279 while(con) { 10280 conl = con; 10281 con = con->next; 10282 free(conl); 10283 } 10284 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 12001 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.
12002 { 12003 struct iax2_peer *peer; 12004 char *peername, *colname; 12005 12006 peername = ast_strdupa(data); 12007 12008 /* if our channel, return the IP address of the endpoint of current channel */ 12009 if (!strcmp(peername,"CURRENTCHANNEL")) { 12010 unsigned short callno; 12011 if (chan->tech != &iax2_tech) 12012 return -1; 12013 callno = PTR_TO_CALLNO(chan->tech_pvt); 12014 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 12015 return 0; 12016 } 12017 12018 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 12019 *colname++ = '\0'; 12020 else if ((colname = strchr(peername, '|'))) 12021 *colname++ = '\0'; 12022 else 12023 colname = "ip"; 12024 12025 if (!(peer = find_peer(peername, 1))) 12026 return -1; 12027 12028 if (!strcasecmp(colname, "ip")) { 12029 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12030 } else if (!strcasecmp(colname, "status")) { 12031 peer_status(peer, buf, len); 12032 } else if (!strcasecmp(colname, "mailbox")) { 12033 ast_copy_string(buf, peer->mailbox, len); 12034 } else if (!strcasecmp(colname, "context")) { 12035 ast_copy_string(buf, peer->context, len); 12036 } else if (!strcasecmp(colname, "expire")) { 12037 snprintf(buf, len, "%d", peer->expire); 12038 } else if (!strcasecmp(colname, "dynamic")) { 12039 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 12040 } else if (!strcasecmp(colname, "callerid_name")) { 12041 ast_copy_string(buf, peer->cid_name, len); 12042 } else if (!strcasecmp(colname, "callerid_num")) { 12043 ast_copy_string(buf, peer->cid_num, len); 12044 } else if (!strcasecmp(colname, "codecs")) { 12045 ast_getformatname_multiple(buf, len -1, peer->capability); 12046 } else if (!strncasecmp(colname, "codec[", 6)) { 12047 char *codecnum, *ptr; 12048 int index = 0, codec = 0; 12049 12050 codecnum = strchr(colname, '['); 12051 *codecnum = '\0'; 12052 codecnum++; 12053 if ((ptr = strchr(codecnum, ']'))) { 12054 *ptr = '\0'; 12055 } 12056 index = atoi(codecnum); 12057 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12058 ast_copy_string(buf, ast_getformatname(codec), len); 12059 } else { 12060 buf[0] = '\0'; 12061 } 12062 } else { 12063 buf[0] = '\0'; 12064 } 12065 12066 peer_unref(peer); 12067 12068 return 0; 12069 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 10508 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
10509 { 10510 int methods = 0; 10511 if (strstr(value, "rsa")) 10512 methods |= IAX_AUTH_RSA; 10513 if (strstr(value, "md5")) 10514 methods |= IAX_AUTH_MD5; 10515 if (strstr(value, "plaintext")) 10516 methods |= IAX_AUTH_PLAINTEXT; 10517 return methods; 10518 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1138 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01139 { 01140 int e; 01141 if (!strcasecmp(s, "aes128")) 01142 e = IAX_ENCRYPT_AES128; 01143 else if (ast_true(s)) 01144 e = IAX_ENCRYPT_AES128; 01145 else 01146 e = 0; 01147 return e; 01148 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3490 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03491 { 03492 #ifdef SCHED_MULTITHREADED 03493 if (schedule_action(__get_from_jb, data)) 03494 #endif 03495 __get_from_jb(data); 03496 return 0; 03497 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2138 of file chan_iax2.c.
References ao2_container_count(), ao2_find(), ao2_lock(), ao2_unlock(), ast_log(), callno_pool, callno_pool_trunk, global_maxcallno_nonval, LOG_WARNING, total_nonval_callno_used, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02139 { 02140 struct callno_entry *callno_entry = NULL; 02141 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02142 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02143 /* Minor optimization for the extreme case. */ 02144 return NULL; 02145 } 02146 02147 /* the callno_pool container is locked here primarily to ensure thread 02148 * safety of the total_nonval_callno_used check and increment */ 02149 ao2_lock(callno_pool); 02150 02151 /* only a certain number of nonvalidated call numbers should be allocated. 02152 * If there ever is an attack, this separates the calltoken validating 02153 * users from the non calltoken validating users. */ 02154 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02155 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02156 ao2_unlock(callno_pool); 02157 return NULL; 02158 } 02159 02160 /* unlink the object from the container, taking over ownership 02161 * of the reference the container had to the object */ 02162 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02163 02164 if (callno_entry) { 02165 callno_entry->validated = validated; 02166 if (!validated) { 02167 total_nonval_callno_used++; 02168 } 02169 } 02170 02171 ao2_unlock(callno_pool); 02172 return callno_entry; 02173 }
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 4183 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(), ast_iax2_full_hdr::scallno, send_apathetic_reply(), t, ast_iax2_full_hdr::ts, and uncompress_subclass().
Referenced by socket_process().
04185 { 04186 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04187 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04188 char buf[256] = { 0 }; 04189 time_t t = time(NULL); 04190 char hash[41]; /* 40 char sha1 hash */ 04191 int subclass = uncompress_subclass(fh->csub); 04192 04193 /* ----- Case 1 ----- */ 04194 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04195 struct iax_ie_data ied = { 04196 .buf = { 0 }, 04197 .pos = 0, 04198 }; 04199 04200 /* create the hash with their address data and our timestamp */ 04201 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04202 ast_sha1_hash(hash, buf); 04203 04204 snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04205 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf); 04206 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04207 04208 return 1; 04209 04210 /* ----- Case 2 ----- */ 04211 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04212 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04213 char *rec_ts = NULL; /* received timestamp */ 04214 unsigned int rec_time; /* received time_t */ 04215 04216 /* split the timestamp from the hash data */ 04217 rec_hash = strchr((char *) ies->calltokendata, '?'); 04218 if (rec_hash) { 04219 *rec_hash++ = '\0'; 04220 rec_ts = (char *) ies->calltokendata; 04221 } 04222 04223 /* check that we have valid data before we do any comparisons */ 04224 if (!rec_hash || !rec_ts) { 04225 goto reject; 04226 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04227 goto reject; 04228 } 04229 04230 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04231 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04232 ast_sha1_hash(hash, buf); 04233 04234 /* compare hashes and then check timestamp delay */ 04235 if (strcmp(hash, rec_hash)) { 04236 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04237 goto reject; /* received hash does not match ours, reject */ 04238 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04239 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04240 goto reject; /* too much delay, reject */ 04241 } 04242 04243 /* at this point the call token is valid, returning 0 04244 * will allow socket_process to continue as usual */ 04245 requirecalltoken_mark_auto(ies->username, subclass); 04246 return 0; 04247 04248 /* ----- Case 3 ----- */ 04249 } else { /* calltokens are not supported for this client, how do we respond? */ 04250 if (calltoken_required(sin, ies->username, subclass)) { 04251 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenignore list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), ies->username); 04252 goto reject; 04253 } 04254 return 0; /* calltoken is not required for this addr, so permit it. */ 04255 } 04256 04257 reject: 04258 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04259 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04260 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04261 } else { 04262 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04263 } 04264 04265 return 1; 04266 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 8098 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.
08099 { 08100 struct iax2_pkt_buf *pkt_buf; 08101 08102 ast_mutex_lock(&thread->lock); 08103 08104 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 08105 ast_mutex_unlock(&thread->lock); 08106 08107 thread->buf = pkt_buf->buf; 08108 thread->buf_len = pkt_buf->len; 08109 thread->buf_size = pkt_buf->len + 1; 08110 08111 socket_process(thread); 08112 08113 thread->buf = NULL; 08114 ast_free(pkt_buf); 08115 08116 ast_mutex_lock(&thread->lock); 08117 } 08118 08119 ast_mutex_unlock(&thread->lock); 08120 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2855 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().
02856 { 02857 /* XXX Ideally we should figure out why an error occured and then abort those 02858 rather than continuing to try. Unfortunately, the published interface does 02859 not seem to work XXX */ 02860 #if 0 02861 struct sockaddr_in *sin; 02862 int res; 02863 struct msghdr m; 02864 struct sock_extended_err e; 02865 m.msg_name = NULL; 02866 m.msg_namelen = 0; 02867 m.msg_iov = NULL; 02868 m.msg_control = &e; 02869 m.msg_controllen = sizeof(e); 02870 m.msg_flags = 0; 02871 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02872 if (res < 0) 02873 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02874 else { 02875 if (m.msg_controllen) { 02876 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02877 if (sin) 02878 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02879 else 02880 ast_log(LOG_WARNING, "No address detected??\n"); 02881 } else { 02882 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02883 } 02884 } 02885 #endif 02886 return 0; 02887 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 7148 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().
07149 { 07150 struct iax2_registry *reg; 07151 /* Start pessimistic */ 07152 char peer[256] = ""; 07153 char msgstatus[60]; 07154 int refresh = 60; 07155 char ourip[256] = "<Unspecified>"; 07156 struct sockaddr_in oldus; 07157 struct sockaddr_in us; 07158 int oldmsgs; 07159 07160 memset(&us, 0, sizeof(us)); 07161 if (ies->apparent_addr) 07162 bcopy(ies->apparent_addr, &us, sizeof(us)); 07163 if (ies->username) 07164 ast_copy_string(peer, ies->username, sizeof(peer)); 07165 if (ies->refresh) 07166 refresh = ies->refresh; 07167 if (ies->calling_number) { 07168 /* We don't do anything with it really, but maybe we should */ 07169 } 07170 reg = iaxs[callno]->reg; 07171 if (!reg) { 07172 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 07173 return -1; 07174 } 07175 memcpy(&oldus, ®->us, sizeof(oldus)); 07176 oldmsgs = reg->messages; 07177 if (inaddrcmp(®->addr, sin)) { 07178 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07179 return -1; 07180 } 07181 memcpy(®->us, &us, sizeof(reg->us)); 07182 if (ies->msgcount >= 0) 07183 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 07184 /* always refresh the registration at the interval requested by the server 07185 we are registering to 07186 */ 07187 reg->refresh = refresh; 07188 AST_SCHED_DEL(sched, reg->expire); 07189 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07190 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 07191 if (option_verbose > 2) { 07192 if (reg->messages > 255) 07193 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 07194 else if (reg->messages > 1) 07195 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 07196 else if (reg->messages > 0) 07197 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 07198 else 07199 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 07200 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07201 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 07202 } 07203 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 07204 } 07205 reg->regstate = REG_STATE_REGISTERED; 07206 return 0; 07207 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2276 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().
02277 { 02278 if (frametype != AST_FRAME_IAX) { 02279 return 0; 02280 } 02281 switch (subclass) { 02282 case IAX_COMMAND_NEW: 02283 case IAX_COMMAND_REGREQ: 02284 case IAX_COMMAND_FWDOWNL: 02285 case IAX_COMMAND_REGREL: 02286 return 1; 02287 case IAX_COMMAND_POKE: 02288 if (!inbound) { 02289 return 1; 02290 } 02291 break; 02292 } 02293 return 0; 02294 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4785 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.
04786 { 04787 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04788 if (option_debug) 04789 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 04790 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 04791 }
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 4630 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.
04631 { 04632 struct ast_channel *cs[3]; 04633 struct ast_channel *who, *other; 04634 int to = -1; 04635 int res = -1; 04636 int transferstarted=0; 04637 struct ast_frame *f; 04638 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 04639 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 04640 struct timeval waittimer = {0, 0}, tv; 04641 04642 lock_both(callno0, callno1); 04643 if (!iaxs[callno0] || !iaxs[callno1]) { 04644 unlock_both(callno0, callno1); 04645 return AST_BRIDGE_FAILED; 04646 } 04647 /* Put them in native bridge mode */ 04648 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 04649 iaxs[callno0]->bridgecallno = callno1; 04650 iaxs[callno1]->bridgecallno = callno0; 04651 } 04652 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 04653 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 04654 transferstarted = 1; 04655 } 04656 unlock_both(callno0, callno1); 04657 04658 /* If not, try to bridge until we can execute a transfer, if we can */ 04659 cs[0] = c0; 04660 cs[1] = c1; 04661 for (/* ever */;;) { 04662 /* Check in case we got masqueraded into */ 04663 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 04664 if (option_verbose > 2) 04665 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 04666 /* Remove from native mode */ 04667 if (c0->tech == &iax2_tech) { 04668 ast_mutex_lock(&iaxsl[callno0]); 04669 iaxs[callno0]->bridgecallno = 0; 04670 ast_mutex_unlock(&iaxsl[callno0]); 04671 } 04672 if (c1->tech == &iax2_tech) { 04673 ast_mutex_lock(&iaxsl[callno1]); 04674 iaxs[callno1]->bridgecallno = 0; 04675 ast_mutex_unlock(&iaxsl[callno1]); 04676 } 04677 return AST_BRIDGE_FAILED_NOWARN; 04678 } 04679 if (c0->nativeformats != c1->nativeformats) { 04680 if (option_verbose > 2) { 04681 char buf0[255]; 04682 char buf1[255]; 04683 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 04684 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 04685 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 04686 } 04687 /* Remove from native mode */ 04688 lock_both(callno0, callno1); 04689 if (iaxs[callno0]) 04690 iaxs[callno0]->bridgecallno = 0; 04691 if (iaxs[callno1]) 04692 iaxs[callno1]->bridgecallno = 0; 04693 unlock_both(callno0, callno1); 04694 return AST_BRIDGE_FAILED_NOWARN; 04695 } 04696 /* check if transfered and if we really want native bridging */ 04697 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 04698 /* Try the transfer */ 04699 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 04700 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 04701 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 04702 transferstarted = 1; 04703 } 04704 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 04705 /* Call has been transferred. We're no longer involved */ 04706 gettimeofday(&tv, NULL); 04707 if (ast_tvzero(waittimer)) { 04708 waittimer = tv; 04709 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 04710 c0->_softhangup |= AST_SOFTHANGUP_DEV; 04711 c1->_softhangup |= AST_SOFTHANGUP_DEV; 04712 *fo = NULL; 04713 *rc = c0; 04714 res = AST_BRIDGE_COMPLETE; 04715 break; 04716 } 04717 } 04718 to = 1000; 04719 who = ast_waitfor_n(cs, 2, &to); 04720 if (timeoutms > -1) { 04721 timeoutms -= (1000 - to); 04722 if (timeoutms < 0) 04723 timeoutms = 0; 04724 } 04725 if (!who) { 04726 if (!timeoutms) { 04727 res = AST_BRIDGE_RETRY; 04728 break; 04729 } 04730 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 04731 res = AST_BRIDGE_FAILED; 04732 break; 04733 } 04734 continue; 04735 } 04736 f = ast_read(who); 04737 if (!f) { 04738 *fo = NULL; 04739 *rc = who; 04740 res = AST_BRIDGE_COMPLETE; 04741 break; 04742 } 04743 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 04744 *fo = f; 04745 *rc = who; 04746 res = AST_BRIDGE_COMPLETE; 04747 break; 04748 } 04749 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 04750 if ((f->frametype == AST_FRAME_VOICE) || 04751 (f->frametype == AST_FRAME_TEXT) || 04752 (f->frametype == AST_FRAME_VIDEO) || 04753 (f->frametype == AST_FRAME_IMAGE) || 04754 (f->frametype == AST_FRAME_DTMF) || 04755 (f->frametype == AST_FRAME_CONTROL)) { 04756 /* monitored dtmf take out of the bridge. 04757 * check if we monitor the specific source. 04758 */ 04759 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 04760 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 04761 *rc = who; 04762 *fo = f; 04763 res = AST_BRIDGE_COMPLETE; 04764 /* Remove from native mode */ 04765 break; 04766 } 04767 /* everything else goes to the other side */ 04768 ast_write(other, f); 04769 } 04770 ast_frfree(f); 04771 /* Swap who gets priority */ 04772 cs[2] = cs[0]; 04773 cs[0] = cs[1]; 04774 cs[1] = cs[2]; 04775 } 04776 lock_both(callno0, callno1); 04777 if(iaxs[callno0]) 04778 iaxs[callno0]->bridgecallno = 0; 04779 if(iaxs[callno1]) 04780 iaxs[callno1]->bridgecallno = 0; 04781 unlock_both(callno0, callno1); 04782 return res; 04783 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4326 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.
04327 { 04328 struct sockaddr_in sin; 04329 char *l=NULL, *n=NULL, *tmpstr; 04330 struct iax_ie_data ied; 04331 char *defaultrdest = "s"; 04332 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04333 struct parsed_dial_string pds; 04334 struct create_addr_info cai; 04335 04336 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04337 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04338 return -1; 04339 } 04340 04341 memset(&cai, 0, sizeof(cai)); 04342 cai.encmethods = iax2_encryption; 04343 04344 memset(&pds, 0, sizeof(pds)); 04345 tmpstr = ast_strdupa(dest); 04346 parse_dial_string(tmpstr, &pds); 04347 04348 if (ast_strlen_zero(pds.peer)) { 04349 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04350 return -1; 04351 } 04352 04353 if (!pds.exten) { 04354 pds.exten = defaultrdest; 04355 } 04356 04357 if (create_addr(pds.peer, c, &sin, &cai)) { 04358 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04359 return -1; 04360 } 04361 04362 if (!pds.username && !ast_strlen_zero(cai.username)) 04363 pds.username = cai.username; 04364 if (!pds.password && !ast_strlen_zero(cai.secret)) 04365 pds.password = cai.secret; 04366 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04367 pds.key = cai.outkey; 04368 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04369 pds.context = cai.peercontext; 04370 04371 /* Keep track of the context for outgoing calls too */ 04372 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04373 04374 if (pds.port) 04375 sin.sin_port = htons(atoi(pds.port)); 04376 04377 l = c->cid.cid_num; 04378 n = c->cid.cid_name; 04379 04380 /* Now build request */ 04381 memset(&ied, 0, sizeof(ied)); 04382 04383 /* On new call, first IE MUST be IAX version of caller */ 04384 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04385 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04386 if (pds.options && strchr(pds.options, 'a')) { 04387 /* Request auto answer */ 04388 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04389 } 04390 04391 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04392 04393 if (l) { 04394 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04395 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04396 } else { 04397 if (n) 04398 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04399 else 04400 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04401 } 04402 04403 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04404 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04405 04406 if (n) 04407 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04408 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04409 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04410 04411 if (!ast_strlen_zero(c->language)) 04412 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04413 if (!ast_strlen_zero(c->cid.cid_dnid)) 04414 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04415 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04416 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04417 04418 if (pds.context) 04419 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04420 04421 if (pds.username) 04422 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04423 04424 if (cai.encmethods) 04425 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04426 04427 ast_mutex_lock(&iaxsl[callno]); 04428 04429 if (!ast_strlen_zero(c->context)) 04430 ast_string_field_set(iaxs[callno], context, c->context); 04431 04432 if (pds.username) 04433 ast_string_field_set(iaxs[callno], username, pds.username); 04434 04435 iaxs[callno]->encmethods = cai.encmethods; 04436 04437 iaxs[callno]->adsi = cai.adsi; 04438 04439 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04440 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04441 04442 if (pds.key) 04443 ast_string_field_set(iaxs[callno], outkey, pds.key); 04444 if (pds.password) 04445 ast_string_field_set(iaxs[callno], secret, pds.password); 04446 04447 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04448 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04449 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04450 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04451 04452 if (iaxs[callno]->maxtime) { 04453 /* Initialize pingtime and auto-congest time */ 04454 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04455 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04456 } else if (autokill) { 04457 iaxs[callno]->pingtime = autokill / 2; 04458 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04459 } 04460 04461 /* send the command using the appropriate socket for this peer */ 04462 iaxs[callno]->sockfd = cai.sockfd; 04463 04464 /* Transmit the string in a "NEW" request */ 04465 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04466 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04467 04468 ast_mutex_unlock(&iaxsl[callno]); 04469 ast_setstate(c, AST_STATE_RINGING); 04470 04471 return 0; 04472 }
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 11903 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.
11904 { 11905 int res = 0; 11906 struct iax2_dpcache *dp; 11907 #if 0 11908 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 11909 #endif 11910 if ((priority != 1) && (priority != 2)) 11911 return 0; 11912 ast_mutex_lock(&dpcache_lock); 11913 dp = find_cache(chan, data, context, exten, priority); 11914 if (dp) { 11915 if (dp->flags & CACHE_FLAG_CANEXIST) 11916 res= 1; 11917 } 11918 ast_mutex_unlock(&dpcache_lock); 11919 if (!dp) { 11920 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 11921 } 11922 return res; 11923 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3993 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03994 { 03995 time_t t; 03996 struct tm tm; 03997 unsigned int tmp; 03998 time(&t); 03999 if (!ast_strlen_zero(tz)) 04000 ast_localtime(&t, &tm, tz); 04001 else 04002 ast_localtime(&t, &tm, NULL); 04003 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04004 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04005 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04006 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04007 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04008 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04009 return tmp; 04010 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1429 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, 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().
01430 { 01431 struct chan_iax2_pvt *pvt; 01432 struct ast_channel *owner; 01433 01434 retry: 01435 pvt = iaxs[callno]; 01436 01437 owner = pvt ? pvt->owner : NULL; 01438 01439 if (owner) { 01440 if (ast_mutex_trylock(&owner->lock)) { 01441 if (option_debug > 2) 01442 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01443 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01444 goto retry; 01445 } 01446 } 01447 01448 /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we 01449 * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee 01450 * the pvt stays around, a ref count is added to it. */ 01451 if (!owner && pvt) { 01452 ao2_ref(pvt, +1); 01453 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01454 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01455 ao2_ref(pvt, -1); 01456 if (iaxs[callno]) { 01457 iaxs[callno] = NULL; 01458 } else { 01459 pvt = NULL; 01460 } 01461 } 01462 01463 if (pvt) { 01464 if (!owner) { 01465 pvt->owner = NULL; 01466 } else { 01467 /* If there's an owner, prod it to give up */ 01468 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01469 * because we already hold the owner channel lock. */ 01470 ast_queue_hangup(owner); 01471 } 01472 01473 if (pvt->peercallno) { 01474 remove_by_peercallno(pvt); 01475 } 01476 01477 if (pvt->transfercallno) { 01478 remove_by_transfercallno(pvt); 01479 } 01480 01481 if (!owner) { 01482 ao2_ref(pvt, -1); 01483 pvt = NULL; 01484 } 01485 } 01486 01487 if (owner) { 01488 ast_mutex_unlock(&owner->lock); 01489 } 01490 01491 if (callno & 0x4000) { 01492 update_max_trunk(); 01493 } 01494 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1340 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(), and chan_iax2_pvt::username.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01341 { 01342 /* Decrement AUTHREQ count if needed */ 01343 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01344 struct iax2_user *user; 01345 struct iax2_user tmp_user = { 01346 .name = pvt->username, 01347 }; 01348 01349 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01350 if (user) { 01351 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01352 user = user_unref(user); 01353 } 01354 01355 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01356 } 01357 01358 /* No more pings or lagrq's */ 01359 AST_SCHED_DEL(sched, pvt->pingid); 01360 AST_SCHED_DEL(sched, pvt->lagid); 01361 AST_SCHED_DEL(sched, pvt->autoid); 01362 AST_SCHED_DEL(sched, pvt->authid); 01363 AST_SCHED_DEL(sched, pvt->initid); 01364 AST_SCHED_DEL(sched, pvt->jbid); 01365 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 12094 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().
12095 { 12096 struct parsed_dial_string pds; 12097 char *tmp = ast_strdupa(data); 12098 struct iax2_peer *p; 12099 int res = AST_DEVICE_INVALID; 12100 12101 memset(&pds, 0, sizeof(pds)); 12102 parse_dial_string(tmp, &pds); 12103 12104 if (ast_strlen_zero(pds.peer)) { 12105 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12106 return res; 12107 } 12108 12109 if (option_debug > 2) 12110 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 12111 12112 /* SLD: FIXME: second call to find_peer during registration */ 12113 if (!(p = find_peer(pds.peer, 1))) 12114 return res; 12115 12116 res = AST_DEVICE_UNAVAILABLE; 12117 if (option_debug > 2) 12118 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 12119 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 12120 12121 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 12122 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 12123 /* Peer is registered, or have default IP address 12124 and a valid registration */ 12125 if (p->historicms == 0 || p->historicms <= p->maxms) 12126 /* let the core figure out whether it is in use or not */ 12127 res = AST_DEVICE_UNKNOWN; 12128 } 12129 12130 peer_unref(p); 12131 12132 return res; 12133 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 3609 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03610 { 03611 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 03612 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 3614 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03615 { 03616 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 03617 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6147 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06148 { 06149 if (argc < 2 || argc > 3) 06150 return RESULT_SHOWUSAGE; 06151 iaxdebug = 1; 06152 ast_cli(fd, "IAX2 Debugging Enabled\n"); 06153 return RESULT_SUCCESS; 06154 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6165 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06166 { 06167 if (argc < 3 || argc > 4) 06168 return RESULT_SHOWUSAGE; 06169 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 06170 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 06171 return RESULT_SUCCESS; 06172 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 9988 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().
09989 { 09990 struct iax_ie_data ied; 09991 if (option_debug && iaxdebug) 09992 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 09993 09994 if (reg->dnsmgr && 09995 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 09996 /* Maybe the IP has changed, force DNS refresh */ 09997 ast_dnsmgr_refresh(reg->dnsmgr); 09998 } 09999 10000 /* 10001 * if IP has Changed, free allocated call to create a new one with new IP 10002 * call has the pointer to IP and must be updated to the new one 10003 */ 10004 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 10005 int callno = reg->callno; 10006 ast_mutex_lock(&iaxsl[callno]); 10007 iax2_destroy(callno); 10008 ast_mutex_unlock(&iaxsl[callno]); 10009 reg->callno = 0; 10010 } 10011 if (!reg->addr.sin_addr.s_addr) { 10012 if (option_debug && iaxdebug) 10013 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 10014 /* Setup the next registration attempt */ 10015 AST_SCHED_DEL(sched, reg->expire); 10016 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10017 return -1; 10018 } 10019 10020 if (!reg->callno) { 10021 if (option_debug) 10022 ast_log(LOG_DEBUG, "Allocate call number\n"); 10023 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 10024 if (reg->callno < 1) { 10025 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 10026 return -1; 10027 } else if (option_debug) 10028 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 10029 iaxs[reg->callno]->reg = reg; 10030 ast_mutex_unlock(&iaxsl[reg->callno]); 10031 } 10032 /* Schedule the next registration attempt */ 10033 AST_SCHED_DEL(sched, reg->expire); 10034 /* Setup the next registration a little early */ 10035 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 10036 /* Send the request */ 10037 memset(&ied, 0, sizeof(ied)); 10038 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 10039 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 10040 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 10041 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 10042 reg->regstate = REG_STATE_REGSENT; 10043 return 0; 10044 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 6984 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
06985 { 06986 #ifdef SCHED_MULTITHREADED 06987 if (schedule_action(__iax2_do_register_s, data)) 06988 #endif 06989 __iax2_do_register_s(data); 06990 return 0; 06991 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6156 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06157 { 06158 if (argc < 3 || argc > 4) 06159 return RESULT_SHOWUSAGE; 06160 iaxtrunkdebug = 1; 06161 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 06162 return RESULT_SUCCESS; 06163 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 7709 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().
07710 { 07711 struct iax_ie_data ied; 07712 /* Auto-hangup with 30 seconds of inactivity */ 07713 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 07714 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 07715 memset(&ied, 0, sizeof(ied)); 07716 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 07717 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 07718 dp->flags |= CACHE_FLAG_TRANSMITTED; 07719 }
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 11949 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.
11950 { 11951 char odata[256]; 11952 char req[256]; 11953 char *ncontext; 11954 struct iax2_dpcache *dp; 11955 struct ast_app *dial; 11956 #if 0 11957 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); 11958 #endif 11959 if (priority == 2) { 11960 /* Indicate status, can be overridden in dialplan */ 11961 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 11962 if (dialstatus) { 11963 dial = pbx_findapp(dialstatus); 11964 if (dial) 11965 pbx_exec(chan, dial, ""); 11966 } 11967 return -1; 11968 } else if (priority != 1) 11969 return -1; 11970 ast_mutex_lock(&dpcache_lock); 11971 dp = find_cache(chan, data, context, exten, priority); 11972 if (dp) { 11973 if (dp->flags & CACHE_FLAG_EXISTS) { 11974 ast_copy_string(odata, data, sizeof(odata)); 11975 ncontext = strchr(odata, '/'); 11976 if (ncontext) { 11977 *ncontext = '\0'; 11978 ncontext++; 11979 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 11980 } else { 11981 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 11982 } 11983 if (option_verbose > 2) 11984 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 11985 } else { 11986 ast_mutex_unlock(&dpcache_lock); 11987 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 11988 return -1; 11989 } 11990 } 11991 ast_mutex_unlock(&dpcache_lock); 11992 dial = pbx_findapp("Dial"); 11993 if (dial) { 11994 return pbx_exec(chan, dial, req); 11995 } else { 11996 ast_log(LOG_WARNING, "No dial application registered\n"); 11997 } 11998 return -1; 11999 }
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 11880 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.
11881 { 11882 struct iax2_dpcache *dp; 11883 int res = 0; 11884 #if 0 11885 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 11886 #endif 11887 if ((priority != 1) && (priority != 2)) 11888 return 0; 11889 ast_mutex_lock(&dpcache_lock); 11890 dp = find_cache(chan, data, context, exten, priority); 11891 if (dp) { 11892 if (dp->flags & CACHE_FLAG_EXISTS) 11893 res= 1; 11894 } 11895 ast_mutex_unlock(&dpcache_lock); 11896 if (!dp) { 11897 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 11898 } 11899 return res; 11900 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3636 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.
03637 { 03638 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 03639 ast_mutex_lock(&iaxsl[callno]); 03640 if (iaxs[callno]) 03641 iaxs[callno]->owner = newchan; 03642 else 03643 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 03644 ast_mutex_unlock(&iaxsl[callno]); 03645 return 0; 03646 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1423 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().
01424 { 01425 AST_SCHED_DEL(sched, fr->retrans); 01426 iax_frame_free(fr); 01427 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1310 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_copy_string(), iax2_peer::name, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01311 { 01312 struct iax2_peer *peer = NULL; 01313 int res = 0; 01314 struct ao2_iterator i; 01315 01316 i = ao2_iterator_init(peers, 0); 01317 while ((peer = ao2_iterator_next(&i))) { 01318 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01319 (peer->addr.sin_port == sin.sin_port)) { 01320 ast_copy_string(host, peer->name, len); 01321 peer_unref(peer); 01322 res = 1; 01323 break; 01324 } 01325 peer_unref(peer); 01326 } 01327 01328 if (!peer) { 01329 peer = realtime_peer(NULL, &sin); 01330 if (peer) { 01331 ast_copy_string(host, peer->name, len); 01332 peer_unref(peer); 01333 res = 1; 01334 } 01335 } 01336 01337 return res; 01338 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 4852 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, and peer_unref().
Referenced by check_access().
04853 { 04854 struct iax2_peer *peer; 04855 int res = 0; 04856 struct ao2_iterator i; 04857 04858 i = ao2_iterator_init(peers, 0); 04859 while ((peer = ao2_iterator_next(&i))) { 04860 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 04861 (peer->addr.sin_port == sin.sin_port)) { 04862 res = ast_test_flag(peer, IAX_TRUNK); 04863 peer_unref(peer); 04864 break; 04865 } 04866 peer_unref(peer); 04867 } 04868 04869 return res; 04870 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4474 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.
04475 { 04476 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04477 struct iax_ie_data ied; 04478 int alreadygone; 04479 memset(&ied, 0, sizeof(ied)); 04480 ast_mutex_lock(&iaxsl[callno]); 04481 if (callno && iaxs[callno]) { 04482 if (option_debug) 04483 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 04484 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04485 /* Send the hangup unless we have had a transmission error or are already gone */ 04486 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04487 if (!iaxs[callno]->error && !alreadygone) { 04488 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04489 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04490 } 04491 if (!iaxs[callno]) { 04492 ast_mutex_unlock(&iaxsl[callno]); 04493 return 0; 04494 } 04495 } 04496 /* Explicitly predestroy it */ 04497 iax2_predestroy(callno); 04498 /* If we were already gone to begin with, destroy us now */ 04499 if (iaxs[callno] && alreadygone) { 04500 if (option_debug) 04501 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 04502 iax2_destroy(callno); 04503 } else if (iaxs[callno]) { 04504 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 04505 } 04506 } else if (c->tech_pvt) { 04507 /* If this call no longer exists, but the channel still 04508 * references it we need to set the channel's tech_pvt to null 04509 * to avoid ast_channel_free() trying to free it. 04510 */ 04511 c->tech_pvt = NULL; 04512 } 04513 ast_mutex_unlock(&iaxsl[callno]); 04514 if (option_verbose > 2) 04515 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 04516 return 0; 04517 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 4793 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().
04794 { 04795 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04796 struct chan_iax2_pvt *pvt; 04797 int res = 0; 04798 04799 if (option_debug && iaxdebug) 04800 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 04801 04802 ast_mutex_lock(&iaxsl[callno]); 04803 pvt = iaxs[callno]; 04804 04805 if (wait_for_peercallno(pvt)) { 04806 res = -1; 04807 goto done; 04808 } 04809 04810 switch (condition) { 04811 case AST_CONTROL_HOLD: 04812 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04813 ast_moh_start(c, data, pvt->mohinterpret); 04814 goto done; 04815 } 04816 break; 04817 case AST_CONTROL_UNHOLD: 04818 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 04819 ast_moh_stop(c); 04820 goto done; 04821 } 04822 } 04823 04824 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 04825 04826 done: 04827 ast_mutex_unlock(&iaxsl[callno]); 04828 04829 return res; 04830 }
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 11926 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.
11927 { 11928 int res = 0; 11929 struct iax2_dpcache *dp; 11930 #if 0 11931 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 11932 #endif 11933 if ((priority != 1) && (priority != 2)) 11934 return 0; 11935 ast_mutex_lock(&dpcache_lock); 11936 dp = find_cache(chan, data, context, exten, priority); 11937 if (dp) { 11938 if (dp->flags & CACHE_FLAG_MATCHMORE) 11939 res= 1; 11940 } 11941 ast_mutex_unlock(&dpcache_lock); 11942 if (!dp) { 11943 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 11944 } 11945 return res; 11946 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6174 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06175 { 06176 if (argc < 3 || argc > 4) 06177 return RESULT_SHOWUSAGE; 06178 iaxdebug = 0; 06179 ast_cli(fd, "IAX2 Debugging Disabled\n"); 06180 return RESULT_SUCCESS; 06181 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6192 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06193 { 06194 if (argc < 4 || argc > 5) 06195 return RESULT_SHOWUSAGE; 06196 jb_setoutput(jb_error_output, jb_warning_output, NULL); 06197 jb_debug_output("\n"); 06198 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 06199 return RESULT_SUCCESS; 06200 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6183 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06184 { 06185 if (argc < 4 || argc > 5) 06186 return RESULT_SHOWUSAGE; 06187 iaxtrunkdebug = 0; 06188 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 06189 return RESULT_SUCCESS; 06190 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 10188 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
10189 { 10190 struct iax2_peer *peer = (struct iax2_peer *)data; 10191 peer->pokeexpire = -1; 10192 #ifdef SCHED_MULTITHREADED 10193 if (schedule_action(__iax2_poke_noanswer, data)) 10194 #endif 10195 __iax2_poke_noanswer(data); 10196 peer_unref(peer); 10197 return 0; 10198 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 10209 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().
10210 { 10211 int callno; 10212 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 10213 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 10214 immediately after clearing things out */ 10215 peer->lastms = 0; 10216 peer->historicms = 0; 10217 peer->pokeexpire = -1; 10218 peer->callno = 0; 10219 return 0; 10220 } 10221 10222 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 10223 if ((callno = peer->callno) > 0) { 10224 ast_log(LOG_NOTICE, "Still have a callno...\n"); 10225 ast_mutex_lock(&iaxsl[callno]); 10226 iax2_destroy(callno); 10227 ast_mutex_unlock(&iaxsl[callno]); 10228 } 10229 if (heldcall) 10230 ast_mutex_unlock(&iaxsl[heldcall]); 10231 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 10232 if (heldcall) 10233 ast_mutex_lock(&iaxsl[heldcall]); 10234 if (peer->callno < 1) { 10235 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 10236 return -1; 10237 } 10238 10239 /* Speed up retransmission times for this qualify call */ 10240 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 10241 iaxs[peer->callno]->peerpoke = peer; 10242 10243 /* Remove any pending pokeexpire task */ 10244 if (peer->pokeexpire > -1) { 10245 if (!ast_sched_del(sched, peer->pokeexpire)) { 10246 peer->pokeexpire = -1; 10247 peer_unref(peer); 10248 } 10249 } 10250 10251 /* Queue up a new task to handle no reply */ 10252 /* If the host is already unreachable then use the unreachable interval instead */ 10253 if (peer->lastms < 0) { 10254 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 10255 } else 10256 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 10257 10258 if (peer->pokeexpire == -1) 10259 peer_unref(peer); 10260 10261 /* And send the poke */ 10262 ast_mutex_lock(&iaxsl[callno]); 10263 if (iaxs[callno]) { 10264 struct iax_ie_data ied = { 10265 .buf = { 0 }, 10266 .pos = 0, 10267 }; 10268 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 10269 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 10270 } 10271 ast_mutex_unlock(&iaxsl[callno]); 10272 10273 return 0; 10274 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10200 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
10201 { 10202 struct iax2_peer *peer = obj; 10203 10204 iax2_poke_peer(peer, 0); 10205 10206 return 0; 10207 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 7749 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
07750 { 07751 struct iax2_peer *peer = (struct iax2_peer *)data; 07752 peer->pokeexpire = -1; 07753 #ifdef SCHED_MULTITHREADED 07754 if (schedule_action(__iax2_poke_peer_s, data)) 07755 #endif 07756 __iax2_poke_peer_s(data); 07757 return 0; 07758 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2939 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().
02940 { 02941 struct ast_channel *c; 02942 struct chan_iax2_pvt *pvt = iaxs[callno]; 02943 02944 if (!pvt) 02945 return -1; 02946 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02947 iax2_destroy_helper(pvt); 02948 ast_set_flag(pvt, IAX_ALREADYGONE); 02949 } 02950 c = pvt->owner; 02951 if (c) { 02952 c->tech_pvt = NULL; 02953 iax2_queue_hangup(callno); 02954 pvt->owner = NULL; 02955 ast_module_unref(ast_module_info->self); 02956 } 02957 return 0; 02958 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 9863 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
09864 { 09865 struct iax2_thread *thread = data; 09866 struct timeval tv; 09867 struct timespec ts; 09868 int put_into_idle = 0; 09869 09870 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 09871 pthread_cleanup_push(iax2_process_thread_cleanup, data); 09872 for(;;) { 09873 /* Wait for something to signal us to be awake */ 09874 ast_mutex_lock(&thread->lock); 09875 09876 /* Flag that we're ready to accept signals */ 09877 thread->ready_for_signal = 1; 09878 09879 /* Put into idle list if applicable */ 09880 if (put_into_idle) 09881 insert_idle_thread(thread); 09882 09883 if (thread->type == IAX_TYPE_DYNAMIC) { 09884 struct iax2_thread *t = NULL; 09885 /* Wait to be signalled or time out */ 09886 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 09887 ts.tv_sec = tv.tv_sec; 09888 ts.tv_nsec = tv.tv_usec * 1000; 09889 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 09890 /* This thread was never put back into the available dynamic 09891 * thread list, so just go away. */ 09892 if (!put_into_idle) { 09893 ast_mutex_unlock(&thread->lock); 09894 break; 09895 } 09896 AST_LIST_LOCK(&dynamic_list); 09897 /* Account for the case where this thread is acquired *right* after a timeout */ 09898 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 09899 iaxdynamicthreadcount--; 09900 AST_LIST_UNLOCK(&dynamic_list); 09901 if (t) { 09902 /* This dynamic thread timed out waiting for a task and was 09903 * not acquired immediately after the timeout, 09904 * so it's time to go away. */ 09905 ast_mutex_unlock(&thread->lock); 09906 break; 09907 } 09908 /* Someone grabbed our thread *right* after we timed out. 09909 * Wait for them to set us up with something to do and signal 09910 * us to continue. */ 09911 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 09912 ts.tv_sec = tv.tv_sec; 09913 ts.tv_nsec = tv.tv_usec * 1000; 09914 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 09915 { 09916 ast_mutex_unlock(&thread->lock); 09917 break; 09918 } 09919 } 09920 } else { 09921 ast_cond_wait(&thread->cond, &thread->lock); 09922 } 09923 09924 /* Go back into our respective list */ 09925 put_into_idle = 1; 09926 09927 ast_mutex_unlock(&thread->lock); 09928 09929 if (thread->iostate == IAX_IOSTATE_IDLE) 09930 continue; 09931 09932 /* Add ourselves to the active list now */ 09933 AST_LIST_LOCK(&active_list); 09934 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09935 AST_LIST_UNLOCK(&active_list); 09936 09937 /* See what we need to do */ 09938 switch(thread->iostate) { 09939 case IAX_IOSTATE_READY: 09940 thread->actions++; 09941 thread->iostate = IAX_IOSTATE_PROCESSING; 09942 socket_process(thread); 09943 handle_deferred_full_frames(thread); 09944 break; 09945 case IAX_IOSTATE_SCHEDREADY: 09946 thread->actions++; 09947 thread->iostate = IAX_IOSTATE_PROCESSING; 09948 #ifdef SCHED_MULTITHREADED 09949 thread->schedfunc(thread->scheddata); 09950 #endif 09951 break; 09952 } 09953 time(&thread->checktime); 09954 thread->iostate = IAX_IOSTATE_IDLE; 09955 #ifdef DEBUG_SCHED_MULTITHREAD 09956 thread->curfunc[0]='\0'; 09957 #endif 09958 09959 /* Now... remove ourselves from the active list, and return to the idle list */ 09960 AST_LIST_LOCK(&active_list); 09961 AST_LIST_REMOVE(&active_list, thread, list); 09962 AST_LIST_UNLOCK(&active_list); 09963 09964 /* Make sure another frame didn't sneak in there after we thought we were done. */ 09965 handle_deferred_full_frames(thread); 09966 } 09967 09968 /*!\note For some reason, idle threads are exiting without being removed 09969 * from an idle list, which is causing memory corruption. Forcibly remove 09970 * it from the list, if it's there. 09971 */ 09972 AST_LIST_LOCK(&idle_list); 09973 AST_LIST_REMOVE(&idle_list, thread, list); 09974 AST_LIST_UNLOCK(&idle_list); 09975 09976 AST_LIST_LOCK(&dynamic_list); 09977 AST_LIST_REMOVE(&dynamic_list, thread, list); 09978 AST_LIST_UNLOCK(&dynamic_list); 09979 09980 /* I am exiting here on my own volition, I need to clean up my own data structures 09981 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 09982 */ 09983 pthread_cleanup_pop(1); 09984 09985 return NULL; 09986 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 9854 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().
09855 { 09856 struct iax2_thread *thread = data; 09857 ast_mutex_destroy(&thread->lock); 09858 ast_cond_destroy(&thread->cond); 09859 free(thread); 09860 ast_atomic_dec_and_test(&iaxactivethreadcount); 09861 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10143 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
10144 { 10145 int force = 0; 10146 int res; 10147 if (argc < 4) 10148 return RESULT_SHOWUSAGE; 10149 if ((argc > 4)) { 10150 if (!strcasecmp(argv[4], "forced")) 10151 force = 1; 10152 else 10153 return RESULT_SHOWUSAGE; 10154 } 10155 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 10156 if (res < 0) 10157 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 10158 else if (res < 1) 10159 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 10160 else 10161 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 10162 return RESULT_SUCCESS; 10163 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10046 of file chan_iax2.c.
References iax_prov_complete_template().
10047 { 10048 if (pos != 3) 10049 return NULL; 10050 return iax_prov_complete_template(line, word, pos, state); 10051 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 10053 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().
10054 { 10055 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 10056 is found for template */ 10057 struct iax_ie_data provdata; 10058 struct iax_ie_data ied; 10059 unsigned int sig; 10060 struct sockaddr_in sin; 10061 int callno; 10062 struct create_addr_info cai; 10063 10064 memset(&cai, 0, sizeof(cai)); 10065 10066 if (option_debug) 10067 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 10068 10069 if (iax_provision_build(&provdata, &sig, template, force)) { 10070 if (option_debug) 10071 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 10072 return 0; 10073 } 10074 10075 if (end) { 10076 memcpy(&sin, end, sizeof(sin)); 10077 cai.sockfd = sockfd; 10078 } else if (create_addr(dest, NULL, &sin, &cai)) 10079 return -1; 10080 10081 /* Build the rest of the message */ 10082 memset(&ied, 0, sizeof(ied)); 10083 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 10084 10085 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10086 if (!callno) 10087 return -1; 10088 10089 if (iaxs[callno]) { 10090 /* Schedule autodestruct in case they don't ever give us anything back */ 10091 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 10092 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 10093 ast_set_flag(iaxs[callno], IAX_PROVISION); 10094 /* Got a call number now, so go ahead and send the provisioning information */ 10095 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 10096 } 10097 ast_mutex_unlock(&iaxsl[callno]); 10098 10099 return 1; 10100 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3077 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, and user_unref().
03078 { 03079 struct iax2_peer *peer = NULL; 03080 struct iax2_user *user = NULL; 03081 03082 if (argc != 4) 03083 return RESULT_SHOWUSAGE; 03084 if (!strcmp(argv[3],"all")) { 03085 prune_users(); 03086 prune_peers(); 03087 ast_cli(fd, "OK cache is flushed.\n"); 03088 return RESULT_SUCCESS; 03089 } 03090 peer = find_peer(argv[3], 0); 03091 user = find_user(argv[3]); 03092 if (peer || user) { 03093 if (peer) { 03094 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03095 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03096 expire_registry(peer_ref(peer)); 03097 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]); 03098 } else { 03099 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]); 03100 } 03101 peer_unref(peer); 03102 } 03103 if (user) { 03104 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03105 ast_set_flag(user, IAX_RTAUTOCLEAR); 03106 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]); 03107 } else { 03108 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]); 03109 } 03110 ao2_unlink(users,user); 03111 user_unref(user); 03112 } 03113 } else { 03114 ast_cli(fd, "%s was not found in the cache.\n", argv[3]); 03115 } 03116 03117 return RESULT_SUCCESS; 03118 }
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 2549 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
02551 { 02552 for (;;) { 02553 if (iaxs[callno] && iaxs[callno]->owner) { 02554 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02555 /* Avoid deadlock by pausing and trying again */ 02556 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02557 } else { 02558 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02559 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02560 break; 02561 } 02562 } else 02563 break; 02564 } 02565 return 0; 02566 }
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 2487 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02488 { 02489 for (;;) { 02490 if (iaxs[callno] && iaxs[callno]->owner) { 02491 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02492 /* Avoid deadlock by pausing and trying again */ 02493 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02494 } else { 02495 ast_queue_frame(iaxs[callno]->owner, f); 02496 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02497 break; 02498 } 02499 } else 02500 break; 02501 } 02502 return 0; 02503 }
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 2518 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02519 { 02520 for (;;) { 02521 if (iaxs[callno] && iaxs[callno]->owner) { 02522 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 02523 /* Avoid deadlock by pausing and trying again */ 02524 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02525 } else { 02526 ast_queue_hangup(iaxs[callno]->owner); 02527 ast_mutex_unlock(&iaxs[callno]->owner->lock); 02528 break; 02529 } 02530 } else 02531 break; 02532 } 02533 return 0; 02534 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4583 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
04584 { 04585 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 04586 return NULL; 04587 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 7209 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().
07210 { 07211 struct iax2_registry *reg; 07212 char copy[256]; 07213 char *username, *hostname, *secret; 07214 char *porta; 07215 char *stringp=NULL; 07216 07217 if (!value) 07218 return -1; 07219 ast_copy_string(copy, value, sizeof(copy)); 07220 stringp=copy; 07221 username = strsep(&stringp, "@"); 07222 hostname = strsep(&stringp, "@"); 07223 if (!hostname) { 07224 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 07225 return -1; 07226 } 07227 stringp=username; 07228 username = strsep(&stringp, ":"); 07229 secret = strsep(&stringp, ":"); 07230 stringp=hostname; 07231 hostname = strsep(&stringp, ":"); 07232 porta = strsep(&stringp, ":"); 07233 07234 if (porta && !atoi(porta)) { 07235 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 07236 return -1; 07237 } 07238 if (!(reg = ast_calloc(1, sizeof(*reg)))) 07239 return -1; 07240 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 07241 free(reg); 07242 return -1; 07243 } 07244 ast_copy_string(reg->username, username, sizeof(reg->username)); 07245 if (secret) 07246 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 07247 reg->expire = -1; 07248 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 07249 reg->addr.sin_family = AF_INET; 07250 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 07251 AST_LIST_LOCK(®istrations); 07252 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 07253 AST_LIST_UNLOCK(®istrations); 07254 07255 return 0; 07256 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11644 of file chan_iax2.c.
References reload_config().
11645 { 11646 return reload_config(); 11647 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 10286 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.
10287 { 10288 int callno; 10289 int res; 10290 int fmt, native; 10291 struct sockaddr_in sin; 10292 struct ast_channel *c; 10293 struct parsed_dial_string pds; 10294 struct create_addr_info cai; 10295 char *tmpstr; 10296 10297 memset(&pds, 0, sizeof(pds)); 10298 tmpstr = ast_strdupa(data); 10299 parse_dial_string(tmpstr, &pds); 10300 10301 if (ast_strlen_zero(pds.peer)) { 10302 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10303 return NULL; 10304 } 10305 10306 memset(&cai, 0, sizeof(cai)); 10307 cai.capability = iax2_capability; 10308 10309 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10310 10311 /* Populate our address from the given */ 10312 if (create_addr(pds.peer, NULL, &sin, &cai)) { 10313 *cause = AST_CAUSE_UNREGISTERED; 10314 return NULL; 10315 } 10316 10317 if (pds.port) 10318 sin.sin_port = htons(atoi(pds.port)); 10319 10320 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10321 if (callno < 1) { 10322 ast_log(LOG_WARNING, "Unable to create call\n"); 10323 *cause = AST_CAUSE_CONGESTION; 10324 return NULL; 10325 } 10326 10327 /* If this is a trunk, update it now */ 10328 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 10329 if (ast_test_flag(&cai, IAX_TRUNK)) { 10330 int new_callno; 10331 if ((new_callno = make_trunk(callno, 1)) != -1) 10332 callno = new_callno; 10333 } 10334 iaxs[callno]->maxtime = cai.maxtime; 10335 if (cai.found) 10336 ast_string_field_set(iaxs[callno], host, pds.peer); 10337 10338 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 10339 10340 ast_mutex_unlock(&iaxsl[callno]); 10341 10342 if (c) { 10343 /* Choose a format we can live with */ 10344 if (c->nativeformats & format) 10345 c->nativeformats &= format; 10346 else { 10347 native = c->nativeformats; 10348 fmt = format; 10349 res = ast_translator_best_choice(&fmt, &native); 10350 if (res < 0) { 10351 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 10352 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 10353 ast_hangup(c); 10354 return NULL; 10355 } 10356 c->nativeformats = native; 10357 } 10358 c->readformat = ast_best_codec(c->nativeformats); 10359 c->writeformat = c->readformat; 10360 } 10361 10362 return c; 10363 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1093 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), and sched_lock.
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_hangup(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), sched_delay_remove(), socket_process(), update_jbsched(), and update_registry().
01094 { 01095 int res; 01096 01097 ast_mutex_lock(&sched_lock); 01098 res = ast_sched_add(con, when, callback, data); 01099 ast_cond_signal(&sched_cond); 01100 ast_mutex_unlock(&sched_lock); 01101 01102 return res; 01103 }
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 5449 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(), and socket_process().
05450 { 05451 /* Queue a packet for delivery on a given private structure. Use "ts" for 05452 timestamp, or calculate if ts is 0. Send immediately without retransmission 05453 or delayed, with retransmission */ 05454 struct ast_iax2_full_hdr *fh; 05455 struct ast_iax2_mini_hdr *mh; 05456 struct ast_iax2_video_hdr *vh; 05457 struct { 05458 struct iax_frame fr2; 05459 unsigned char buffer[4096]; 05460 } frb; 05461 struct iax_frame *fr; 05462 int res; 05463 int sendmini=0; 05464 unsigned int lastsent; 05465 unsigned int fts; 05466 05467 frb.fr2.afdatalen = sizeof(frb.buffer); 05468 05469 if (!pvt) { 05470 ast_log(LOG_WARNING, "No private structure for packet?\n"); 05471 return -1; 05472 } 05473 05474 lastsent = pvt->lastsent; 05475 05476 /* Calculate actual timestamp */ 05477 fts = calc_timestamp(pvt, ts, f); 05478 05479 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 05480 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 05481 * increment the "predicted timestamps" for voice, if we're predecting */ 05482 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 05483 return 0; 05484 05485 05486 if ((ast_test_flag(pvt, IAX_TRUNK) || 05487 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 05488 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 05489 /* High two bytes are the same on timestamp, or sending on a trunk */ && 05490 (f->frametype == AST_FRAME_VOICE) 05491 /* is a voice frame */ && 05492 (f->subclass == pvt->svoiceformat) 05493 /* is the same type */ ) { 05494 /* Force immediate rather than delayed transmission */ 05495 now = 1; 05496 /* Mark that mini-style frame is appropriate */ 05497 sendmini = 1; 05498 } 05499 if ( f->frametype == AST_FRAME_VIDEO ) { 05500 /* 05501 * If the lower 15 bits of the timestamp roll over, or if 05502 * the video format changed then send a full frame. 05503 * Otherwise send a mini video frame 05504 */ 05505 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 05506 ((f->subclass & ~0x1) == pvt->svideoformat) 05507 ) { 05508 now = 1; 05509 sendmini = 1; 05510 } else { 05511 now = 0; 05512 sendmini = 0; 05513 } 05514 pvt->lastvsent = fts; 05515 } 05516 if (f->frametype == AST_FRAME_IAX) { 05517 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 05518 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 05519 if (!pvt->first_iax_message) { 05520 pvt->first_iax_message = pvt->last_iax_message; 05521 } 05522 } 05523 /* Allocate an iax_frame */ 05524 if (now) { 05525 fr = &frb.fr2; 05526 } else 05527 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)); 05528 if (!fr) { 05529 ast_log(LOG_WARNING, "Out of memory\n"); 05530 return -1; 05531 } 05532 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 05533 iax_frame_wrap(fr, f); 05534 05535 fr->ts = fts; 05536 fr->callno = pvt->callno; 05537 fr->transfer = transfer; 05538 fr->final = final; 05539 fr->encmethods = 0; 05540 if (!sendmini) { 05541 /* We need a full frame */ 05542 if (seqno > -1) 05543 fr->oseqno = seqno; 05544 else 05545 fr->oseqno = pvt->oseqno++; 05546 fr->iseqno = pvt->iseqno; 05547 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 05548 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 05549 fh->ts = htonl(fr->ts); 05550 fh->oseqno = fr->oseqno; 05551 if (transfer) { 05552 fh->iseqno = 0; 05553 } else 05554 fh->iseqno = fr->iseqno; 05555 /* Keep track of the last thing we've acknowledged */ 05556 if (!transfer) 05557 pvt->aseqno = fr->iseqno; 05558 fh->type = fr->af.frametype & 0xFF; 05559 if (fr->af.frametype == AST_FRAME_VIDEO) 05560 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 05561 else 05562 fh->csub = compress_subclass(fr->af.subclass); 05563 if (transfer) { 05564 fr->dcallno = pvt->transfercallno; 05565 } else 05566 fr->dcallno = pvt->peercallno; 05567 fh->dcallno = htons(fr->dcallno); 05568 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 05569 fr->data = fh; 05570 fr->retries = 0; 05571 /* Retry after 2x the ping time has passed */ 05572 fr->retrytime = pvt->pingtime * 2; 05573 if (fr->retrytime < MIN_RETRY_TIME) 05574 fr->retrytime = MIN_RETRY_TIME; 05575 if (fr->retrytime > MAX_RETRY_TIME) 05576 fr->retrytime = MAX_RETRY_TIME; 05577 /* Acks' don't get retried */ 05578 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 05579 fr->retries = -1; 05580 else if (f->frametype == AST_FRAME_VOICE) 05581 pvt->svoiceformat = f->subclass; 05582 else if (f->frametype == AST_FRAME_VIDEO) 05583 pvt->svideoformat = f->subclass & ~0x1; 05584 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05585 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05586 if (iaxdebug) { 05587 if (fr->transfer) 05588 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05589 else 05590 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 05591 } 05592 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 05593 fr->encmethods = pvt->encmethods; 05594 fr->ecx = pvt->ecx; 05595 fr->mydcx = pvt->mydcx; 05596 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 05597 } else 05598 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05599 } 05600 05601 if (now) { 05602 res = send_packet(fr); 05603 } else 05604 res = iax2_transmit(fr); 05605 } else { 05606 if (ast_test_flag(pvt, IAX_TRUNK)) { 05607 iax2_trunk_queue(pvt, fr); 05608 res = 0; 05609 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 05610 /* Video frame have no sequence number */ 05611 fr->oseqno = -1; 05612 fr->iseqno = -1; 05613 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 05614 vh->zeros = 0; 05615 vh->callno = htons(0x8000 | fr->callno); 05616 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 05617 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 05618 fr->data = vh; 05619 fr->retries = -1; 05620 res = send_packet(fr); 05621 } else { 05622 /* Mini-frames have no sequence number */ 05623 fr->oseqno = -1; 05624 fr->iseqno = -1; 05625 /* Mini frame will do */ 05626 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 05627 mh->callno = htons(fr->callno); 05628 mh->ts = htons(fr->ts & 0xFFFF); 05629 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 05630 fr->data = mh; 05631 fr->retries = -1; 05632 if (pvt->transferring == TRANSFER_MEDIAPASS) 05633 fr->transfer = 1; 05634 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 05635 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 05636 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 05637 } else 05638 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 05639 } 05640 res = send_packet(fr); 05641 } 05642 } 05643 return res; 05644 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3631 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03632 { 03633 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 03634 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 3626 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.
03627 { 03628 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 03629 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 3619 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03620 { 03621 03622 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 03623 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 03624 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4541 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
04542 { 04543 struct ast_option_header *h; 04544 int res; 04545 04546 switch (option) { 04547 case AST_OPTION_TXGAIN: 04548 case AST_OPTION_RXGAIN: 04549 /* these two cannot be sent, because they require a result */ 04550 errno = ENOSYS; 04551 return -1; 04552 default: 04553 { 04554 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04555 struct chan_iax2_pvt *pvt; 04556 04557 ast_mutex_lock(&iaxsl[callno]); 04558 pvt = iaxs[callno]; 04559 04560 if (wait_for_peercallno(pvt)) { 04561 ast_mutex_unlock(&iaxsl[callno]); 04562 return -1; 04563 } 04564 04565 ast_mutex_unlock(&iaxsl[callno]); 04566 04567 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 04568 return -1; 04569 } 04570 04571 h->flag = AST_OPTION_FLAG_REQUEST; 04572 h->option = htons(option); 04573 memcpy(h->data, data, datalen); 04574 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 04575 AST_CONTROL_OPTION, 0, (unsigned char *) h, 04576 datalen + sizeof(*h), -1); 04577 free(h); 04578 return res; 04579 } 04580 } 04581 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3304 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.
03305 { 03306 struct iax2_dpcache *dp; 03307 char tmp[1024], *pc; 03308 int s; 03309 int x,y; 03310 struct timeval tv; 03311 gettimeofday(&tv, NULL); 03312 ast_mutex_lock(&dpcache_lock); 03313 dp = dpcache; 03314 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03315 while(dp) { 03316 s = dp->expiry.tv_sec - tv.tv_sec; 03317 tmp[0] = '\0'; 03318 if (dp->flags & CACHE_FLAG_EXISTS) 03319 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03320 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03321 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03322 if (dp->flags & CACHE_FLAG_CANEXIST) 03323 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03324 if (dp->flags & CACHE_FLAG_PENDING) 03325 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03326 if (dp->flags & CACHE_FLAG_TIMEOUT) 03327 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03328 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03329 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03330 if (dp->flags & CACHE_FLAG_MATCHMORE) 03331 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03332 if (dp->flags & CACHE_FLAG_UNKNOWN) 03333 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03334 /* Trim trailing pipe */ 03335 if (!ast_strlen_zero(tmp)) 03336 tmp[strlen(tmp) - 1] = '\0'; 03337 else 03338 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03339 y=0; 03340 pc = strchr(dp->peercontext, '@'); 03341 if (!pc) 03342 pc = dp->peercontext; 03343 else 03344 pc++; 03345 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 03346 if (dp->waiters[x] > -1) 03347 y++; 03348 if (s > 0) 03349 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03350 else 03351 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03352 dp = dp->next; 03353 } 03354 ast_mutex_unlock(&dpcache_lock); 03355 return RESULT_SUCCESS; 03356 }
static int iax2_show_callnumber_usage | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2107 of file chan_iax2.c.
References peercnt::addr, ao2_iterator_init(), ao2_iterator_next(), ao2_ref(), ast_cli(), ast_inet_ntoa(), peercnt::cur, global_maxcallno_nonval, peercnt::limit, peercnts, RESULT_SHOWUSAGE, RESULT_SUCCESS, and total_nonval_callno_used.
02108 { 02109 struct ao2_iterator i; 02110 struct peercnt *peercnt; 02111 struct sockaddr_in sin; 02112 int found = 0; 02113 02114 if (argc < 4 || argc > 5) 02115 return RESULT_SHOWUSAGE; 02116 02117 ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02118 i = ao2_iterator_init(peercnts, 0); 02119 while ((peercnt = ao2_iterator_next(&i))) { 02120 sin.sin_addr.s_addr = peercnt->addr; 02121 if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02122 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02123 found = 1; 02124 break; 02125 } else { 02126 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02127 } 02128 ao2_ref(peercnt, -1); 02129 } 02130 if (argc == 4) { 02131 ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02132 } else if (argc == 5 && !found) { 02133 ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] ); 02134 } 02135 return RESULT_SUCCESS; 02136 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5988 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.
05989 { 05990 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 05991 #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" 05992 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 05993 int x; 05994 int numchans = 0; 05995 int usedchans = 0; 05996 char first_message[10] = { 0, }; 05997 char last_message[10] = { 0, }; 05998 05999 if (argc != 3) 06000 return RESULT_SHOWUSAGE; 06001 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06002 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06003 ast_mutex_lock(&iaxsl[x]); 06004 if (iaxs[x]) { 06005 int lag, jitter, localdelay; 06006 jb_info jbinfo; 06007 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06008 jb_getinfo(iaxs[x]->jb, &jbinfo); 06009 jitter = jbinfo.jitter; 06010 localdelay = jbinfo.current - jbinfo.min; 06011 } else { 06012 jitter = -1; 06013 localdelay = 0; 06014 } 06015 06016 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06017 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06018 lag = iaxs[x]->remote_rr.delay; 06019 ast_cli(fd, FORMAT, 06020 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06021 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06022 S_OR(iaxs[x]->username, "(None)"), 06023 iaxs[x]->callno, iaxs[x]->peercallno, 06024 iaxs[x]->oseqno, iaxs[x]->iseqno, 06025 lag, 06026 jitter, 06027 localdelay, 06028 ast_getformatname(iaxs[x]->voiceformat), 06029 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06030 first_message, 06031 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06032 last_message); 06033 numchans++; 06034 if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */ 06035 usedchans++; 06036 } 06037 } 06038 ast_mutex_unlock(&iaxsl[x]); 06039 } 06040 ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 06041 ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 06042 return RESULT_SUCCESS; 06043 #undef FORMAT 06044 #undef FORMAT2 06045 #undef FORMATB 06046 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5899 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.
05900 { 05901 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 05902 #if !defined(__FreeBSD__) 05903 #define FORMAT "%-15.15s %-15d %-15d\n" 05904 #else /* __FreeBSD__ */ 05905 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 05906 #endif /* __FreeBSD__ */ 05907 struct iax_firmware *cur; 05908 if ((argc != 3) && (argc != 4)) 05909 return RESULT_SHOWUSAGE; 05910 ast_mutex_lock(&waresl.lock); 05911 05912 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 05913 for (cur = waresl.wares;cur;cur = cur->next) { 05914 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 05915 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 05916 (int)ntohl(cur->fwh->datalen)); 05917 } 05918 ast_mutex_unlock(&waresl.lock); 05919 return RESULT_SUCCESS; 05920 #undef FORMAT 05921 #undef FORMAT2 05922 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 6135 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
06136 { 06137 int numchans = 0; 06138 if (argc != 3) 06139 return RESULT_SHOWUSAGE; 06140 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06141 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06142 numchans = ast_cli_netstats(NULL, fd, 1); 06143 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06144 return RESULT_SUCCESS; 06145 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 3189 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.
03190 { 03191 char status[30]; 03192 char cbuf[256]; 03193 struct iax2_peer *peer; 03194 char codec_buf[512]; 03195 int x = 0, codec = 0, load_realtime = 0; 03196 03197 if (argc < 4) 03198 return RESULT_SHOWUSAGE; 03199 03200 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 03201 03202 peer = find_peer(argv[3], load_realtime); 03203 if (peer) { 03204 ast_cli(fd,"\n\n"); 03205 ast_cli(fd, " * Name : %s\n", peer->name); 03206 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 03207 ast_cli(fd, " Context : %s\n", peer->context); 03208 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 03209 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 03210 ast_cli(fd, " Callnum limit: %d\n", peer->maxcallno); 03211 ast_cli(fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03212 03213 03214 ast_cli(fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03215 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03216 ast_cli(fd, " Expire : %d\n", peer->expire); 03217 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 03218 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)); 03219 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03220 ast_cli(fd, " Username : %s\n", peer->username); 03221 ast_cli(fd, " Codecs : "); 03222 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03223 ast_cli(fd, "%s\n", codec_buf); 03224 03225 ast_cli(fd, " Codec Order : ("); 03226 for(x = 0; x < 32 ; x++) { 03227 codec = ast_codec_pref_index(&peer->prefs,x); 03228 if(!codec) 03229 break; 03230 ast_cli(fd, "%s", ast_getformatname(codec)); 03231 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03232 ast_cli(fd, "|"); 03233 } 03234 03235 if (!x) 03236 ast_cli(fd, "none"); 03237 ast_cli(fd, ")\n"); 03238 03239 ast_cli(fd, " Status : "); 03240 peer_status(peer, status, sizeof(status)); 03241 ast_cli(fd, "%s\n",status); 03242 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03243 ast_cli(fd,"\n"); 03244 peer_unref(peer); 03245 } else { 03246 ast_cli(fd,"Peer %s not found.\n", argv[3]); 03247 ast_cli(fd,"\n"); 03248 } 03249 03250 return RESULT_SUCCESS; 03251 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5888 of file chan_iax2.c.
References __iax2_show_peers().
05889 { 05890 return __iax2_show_peers(0, fd, NULL, argc, argv); 05891 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5960 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.
05961 { 05962 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 05963 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 05964 struct iax2_registry *reg = NULL; 05965 05966 char host[80]; 05967 char perceived[80]; 05968 if (argc != 3) 05969 return RESULT_SHOWUSAGE; 05970 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 05971 AST_LIST_LOCK(®istrations); 05972 AST_LIST_TRAVERSE(®istrations, reg, entry) { 05973 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 05974 if (reg->us.sin_addr.s_addr) 05975 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05976 else 05977 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 05978 ast_cli(fd, FORMAT, host, 05979 (reg->dnsmgr) ? "Y" : "N", 05980 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 05981 } 05982 AST_LIST_UNLOCK(®istrations); 05983 return RESULT_SUCCESS; 05984 #undef FORMAT 05985 #undef FORMAT2 05986 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3278 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.
03279 { 03280 struct iax_frame *cur; 03281 int cnt = 0, dead=0, final=0; 03282 03283 if (argc != 3) 03284 return RESULT_SHOWUSAGE; 03285 03286 AST_LIST_LOCK(&iaxq.queue); 03287 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 03288 if (cur->retries < 0) 03289 dead++; 03290 if (cur->final) 03291 final++; 03292 cnt++; 03293 } 03294 AST_LIST_UNLOCK(&iaxq.queue); 03295 03296 ast_cli(fd, " IAX Statistics\n"); 03297 ast_cli(fd, "---------------------\n"); 03298 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03299 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03300 03301 return RESULT_SUCCESS; 03302 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5829 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.
05830 { 05831 struct iax2_thread *thread = NULL; 05832 time_t t; 05833 int threadcount = 0, dynamiccount = 0; 05834 char type; 05835 05836 if (argc != 3) 05837 return RESULT_SHOWUSAGE; 05838 05839 ast_cli(fd, "IAX2 Thread Information\n"); 05840 time(&t); 05841 ast_cli(fd, "Idle Threads:\n"); 05842 AST_LIST_LOCK(&idle_list); 05843 AST_LIST_TRAVERSE(&idle_list, thread, list) { 05844 #ifdef DEBUG_SCHED_MULTITHREAD 05845 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05846 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05847 #else 05848 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05849 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05850 #endif 05851 threadcount++; 05852 } 05853 AST_LIST_UNLOCK(&idle_list); 05854 ast_cli(fd, "Active Threads:\n"); 05855 AST_LIST_LOCK(&active_list); 05856 AST_LIST_TRAVERSE(&active_list, thread, list) { 05857 if (thread->type == IAX_TYPE_DYNAMIC) 05858 type = 'D'; 05859 else 05860 type = 'P'; 05861 #ifdef DEBUG_SCHED_MULTITHREAD 05862 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 05863 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05864 #else 05865 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 05866 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05867 #endif 05868 threadcount++; 05869 } 05870 AST_LIST_UNLOCK(&active_list); 05871 ast_cli(fd, "Dynamic Threads:\n"); 05872 AST_LIST_LOCK(&dynamic_list); 05873 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 05874 #ifdef DEBUG_SCHED_MULTITHREAD 05875 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 05876 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 05877 #else 05878 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 05879 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 05880 #endif 05881 dynamiccount++; 05882 } 05883 AST_LIST_UNLOCK(&dynamic_list); 05884 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 05885 return RESULT_SUCCESS; 05886 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5646 of file chan_iax2.c.
References 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, and user_unref().
05647 { 05648 regex_t regexbuf; 05649 int havepattern = 0; 05650 05651 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 05652 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 05653 05654 struct iax2_user *user = NULL; 05655 char auth[90]; 05656 char *pstr = ""; 05657 struct ao2_iterator i; 05658 05659 switch (argc) { 05660 case 5: 05661 if (!strcasecmp(argv[3], "like")) { 05662 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 05663 return RESULT_SHOWUSAGE; 05664 havepattern = 1; 05665 } else 05666 return RESULT_SHOWUSAGE; 05667 case 3: 05668 break; 05669 default: 05670 return RESULT_SHOWUSAGE; 05671 } 05672 05673 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 05674 i = ao2_iterator_init(users, 0); 05675 for (user = ao2_iterator_next(&i); user; 05676 user_unref(user), user = ao2_iterator_next(&i)) { 05677 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 05678 continue; 05679 05680 if (!ast_strlen_zero(user->secret)) { 05681 ast_copy_string(auth,user->secret,sizeof(auth)); 05682 } else if (!ast_strlen_zero(user->inkeys)) { 05683 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 05684 } else 05685 ast_copy_string(auth, "-no secret-", sizeof(auth)); 05686 05687 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 05688 pstr = "REQ Only"; 05689 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 05690 pstr = "Disabled"; 05691 else 05692 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 05693 05694 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 05695 user->contexts ? user->contexts->context : context, 05696 user->ha ? "Yes" : "No", pstr); 05697 } 05698 05699 if (havepattern) 05700 regfree(®exbuf); 05701 05702 return RESULT_SUCCESS; 05703 #undef FORMAT 05704 #undef FORMAT2 05705 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 4589 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.
04590 { 04591 int res; 04592 struct iax_ie_data ied0; 04593 struct iax_ie_data ied1; 04594 unsigned int transferid = (unsigned int)ast_random(); 04595 memset(&ied0, 0, sizeof(ied0)); 04596 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 04597 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 04598 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 04599 04600 memset(&ied1, 0, sizeof(ied1)); 04601 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 04602 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 04603 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 04604 04605 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 04606 if (res) 04607 return -1; 04608 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 04609 if (res) 04610 return -1; 04611 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04612 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 04613 return 0; 04614 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3120 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03121 { 03122 if (argc != 4) 03123 return RESULT_SHOWUSAGE; 03124 03125 test_losspct = atoi(argv[3]); 03126 03127 return RESULT_SUCCESS; 03128 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 4832 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.
04833 { 04834 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04835 struct iax_ie_data ied; 04836 char tmp[256], *context; 04837 ast_copy_string(tmp, dest, sizeof(tmp)); 04838 context = strchr(tmp, '@'); 04839 if (context) { 04840 *context = '\0'; 04841 context++; 04842 } 04843 memset(&ied, 0, sizeof(ied)); 04844 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 04845 if (context) 04846 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 04847 if (option_debug) 04848 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 04849 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 04850 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3590 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_iax2_queue::count, iaxq, ast_iax2_queue::queue, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
03591 { 03592 /* Lock the queue and place this packet at the end */ 03593 /* By setting this to 0, the network thread will send it for us, and 03594 queue retransmission if necessary */ 03595 fr->sentyet = 0; 03596 AST_LIST_LOCK(&iaxq.queue); 03597 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 03598 iaxq.count++; 03599 AST_LIST_UNLOCK(&iaxq.queue); 03600 /* Wake up the network and scheduler thread */ 03601 if (netthreadid != AST_PTHREADT_NULL) 03602 pthread_kill(netthreadid, SIGURG); 03603 signal_condition(&sched_lock, &sched_cond); 03604 return 0; 03605 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 7804 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
07805 { 07806 /* Drop when trunk is about 5 seconds idle */ 07807 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 07808 return 1; 07809 return 0; 07810 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 5201 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().
05202 { 05203 struct ast_frame *f; 05204 struct iax2_trunk_peer *tpeer; 05205 void *tmp, *ptr; 05206 struct ast_iax2_meta_trunk_entry *met; 05207 struct ast_iax2_meta_trunk_mini *mtm; 05208 05209 f = &fr->af; 05210 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05211 if (tpeer) { 05212 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05213 /* Need to reallocate space */ 05214 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 05215 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05216 ast_mutex_unlock(&tpeer->lock); 05217 return -1; 05218 } 05219 05220 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05221 tpeer->trunkdata = tmp; 05222 if (option_debug) 05223 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); 05224 } else { 05225 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)); 05226 ast_mutex_unlock(&tpeer->lock); 05227 return -1; 05228 } 05229 } 05230 05231 /* Append to meta frame */ 05232 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05233 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05234 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05235 mtm->len = htons(f->datalen); 05236 mtm->mini.callno = htons(pvt->callno); 05237 mtm->mini.ts = htons(0xffff & fr->ts); 05238 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05239 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05240 } else { 05241 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05242 /* Store call number and length in meta header */ 05243 met->callno = htons(pvt->callno); 05244 met->len = htons(f->datalen); 05245 /* Advance pointers/decrease length past trunk entry header */ 05246 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05247 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05248 } 05249 /* Copy actual trunk data */ 05250 memcpy(ptr, f->data, f->datalen); 05251 tpeer->trunkdatalen += f->datalen; 05252 05253 tpeer->calls++; 05254 ast_mutex_unlock(&tpeer->lock); 05255 } 05256 return 0; 05257 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 7721 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
07722 { 07723 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 07724 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 6202 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.
06203 { 06204 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 06205 int res = -1; 06206 ast_mutex_lock(&iaxsl[callno]); 06207 if (iaxs[callno]) { 06208 /* If there's an outstanding error, return failure now */ 06209 if (!iaxs[callno]->error) { 06210 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 06211 res = 0; 06212 /* Don't waste bandwidth sending null frames */ 06213 else if (f->frametype == AST_FRAME_NULL) 06214 res = 0; 06215 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 06216 res = 0; 06217 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 06218 res = 0; 06219 else 06220 /* Simple, just queue for transmission */ 06221 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 06222 } else { 06223 if (option_debug) 06224 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 06225 } 06226 } 06227 /* If it's already gone, just return */ 06228 ast_mutex_unlock(&iaxsl[callno]); 06229 return res; 06230 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2722 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().
02723 { 02724 int res = 0; 02725 struct iax_firmware *cur; 02726 if (!ast_strlen_zero(dev)) { 02727 ast_mutex_lock(&waresl.lock); 02728 cur = waresl.wares; 02729 while(cur) { 02730 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02731 res = ntohs(cur->fwh->version); 02732 break; 02733 } 02734 cur = cur->next; 02735 } 02736 ast_mutex_unlock(&waresl.lock); 02737 } 02738 return res; 02739 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 857 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00858 { 00859 if (iaxdebug) 00860 ast_verbose("%s", data); 00861 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 863 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00864 { 00865 ast_log(LOG_WARNING, "%s", data); 00866 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 2741 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().
02742 { 02743 int res = -1; 02744 unsigned int bs = desc & 0xff; 02745 unsigned int start = (desc >> 8) & 0xffffff; 02746 unsigned int bytes; 02747 struct iax_firmware *cur; 02748 if (!ast_strlen_zero((char *)dev) && bs) { 02749 start *= bs; 02750 ast_mutex_lock(&waresl.lock); 02751 cur = waresl.wares; 02752 while(cur) { 02753 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 02754 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02755 if (start < ntohl(cur->fwh->datalen)) { 02756 bytes = ntohl(cur->fwh->datalen) - start; 02757 if (bytes > bs) 02758 bytes = bs; 02759 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02760 } else { 02761 bytes = 0; 02762 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02763 } 02764 if (bytes == bs) 02765 res = 0; 02766 else 02767 res = 1; 02768 break; 02769 } 02770 cur = cur->next; 02771 } 02772 ast_mutex_unlock(&waresl.lock); 02773 } 02774 return res; 02775 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 7992 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().
07993 { 07994 struct iax_dual *d; 07995 struct ast_channel *chan1m, *chan2m; 07996 pthread_t th; 07997 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 07998 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 07999 if (chan2m && chan1m) { 08000 /* Make formats okay */ 08001 chan1m->readformat = chan1->readformat; 08002 chan1m->writeformat = chan1->writeformat; 08003 ast_channel_masquerade(chan1m, chan1); 08004 /* Setup the extensions and such */ 08005 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08006 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08007 chan1m->priority = chan1->priority; 08008 08009 /* We make a clone of the peer channel too, so we can play 08010 back the announcement */ 08011 /* Make formats okay */ 08012 chan2m->readformat = chan2->readformat; 08013 chan2m->writeformat = chan2->writeformat; 08014 ast_channel_masquerade(chan2m, chan2); 08015 /* Setup the extensions and such */ 08016 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08017 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08018 chan2m->priority = chan2->priority; 08019 if (ast_do_masquerade(chan2m)) { 08020 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08021 ast_hangup(chan2m); 08022 return -1; 08023 } 08024 } else { 08025 if (chan1m) 08026 ast_hangup(chan1m); 08027 if (chan2m) 08028 ast_hangup(chan2m); 08029 return -1; 08030 } 08031 if ((d = ast_calloc(1, sizeof(*d)))) { 08032 pthread_attr_t attr; 08033 08034 pthread_attr_init(&attr); 08035 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08036 08037 d->chan1 = chan1m; 08038 d->chan2 = chan2m; 08039 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 08040 pthread_attr_destroy(&attr); 08041 return 0; 08042 } 08043 pthread_attr_destroy(&attr); 08044 free(d); 08045 } 08046 return -1; 08047 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 7972 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().
07973 { 07974 struct ast_channel *chan1, *chan2; 07975 struct iax_dual *d; 07976 struct ast_frame *f; 07977 int ext; 07978 int res; 07979 d = stuff; 07980 chan1 = d->chan1; 07981 chan2 = d->chan2; 07982 free(d); 07983 f = ast_read(chan1); 07984 if (f) 07985 ast_frfree(f); 07986 res = ast_park_call(chan1, chan2, 0, &ext); 07987 ast_hangup(chan2); 07988 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 07989 return NULL; 07990 }
Definition at line 1590 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().
01591 { 01592 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01593 if (new) { 01594 size_t afdatalen = new->afdatalen; 01595 memcpy(new, fr, sizeof(*new)); 01596 iax_frame_wrap(new, &fr->af); 01597 new->afdatalen = afdatalen; 01598 new->data = NULL; 01599 new->datalen = 0; 01600 new->direction = DIRECTION_INGRESS; 01601 new->retrans = -1; 01602 } 01603 return new; 01604 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1001 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().
01002 { 01003 if (thread->type == IAX_TYPE_DYNAMIC) { 01004 AST_LIST_LOCK(&dynamic_list); 01005 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01006 AST_LIST_UNLOCK(&dynamic_list); 01007 } else { 01008 AST_LIST_LOCK(&idle_list); 01009 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01010 AST_LIST_UNLOCK(&idle_list); 01011 } 01012 01013 return; 01014 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 892 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00893 { 00894 va_list args; 00895 char buf[1024]; 00896 00897 va_start(args, fmt); 00898 vsnprintf(buf, 1024, fmt, args); 00899 va_end(args); 00900 00901 ast_verbose("%s", buf); 00902 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 868 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00869 { 00870 va_list args; 00871 char buf[1024]; 00872 00873 va_start(args, fmt); 00874 vsnprintf(buf, 1024, fmt, args); 00875 va_end(args); 00876 00877 ast_log(LOG_ERROR, "%s", buf); 00878 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 880 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00881 { 00882 va_list args; 00883 char buf[1024]; 00884 00885 va_start(args, fmt); 00886 vsnprintf(buf, 1024, fmt, args); 00887 va_end(args); 00888 00889 ast_log(LOG_WARNING, "%s", buf); 00890 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 12578 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(), ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), VERBOSE_PREFIX_2, and waresl.
12579 { 12580 static const char config[] = "iax.conf"; 12581 int res = 0; 12582 int x; 12583 struct iax2_registry *reg = NULL; 12584 12585 if (load_objects()) { 12586 return AST_MODULE_LOAD_FAILURE; 12587 } 12588 12589 randomcalltokendata = ast_random(); 12590 ast_custom_function_register(&iaxpeer_function); 12591 12592 iax_set_output(iax_debug_output); 12593 iax_set_error(iax_error_output); 12594 jb_setoutput(jb_error_output, jb_warning_output, NULL); 12595 12596 #ifdef HAVE_DAHDI 12597 #ifdef DAHDI_TIMERACK 12598 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 12599 if (timingfd < 0) 12600 #endif 12601 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 12602 if (timingfd < 0) 12603 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 12604 #endif 12605 12606 memset(iaxs, 0, sizeof(iaxs)); 12607 12608 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 12609 ast_mutex_init(&iaxsl[x]); 12610 } 12611 12612 ast_cond_init(&sched_cond, NULL); 12613 12614 io = io_context_create(); 12615 sched = sched_context_create(); 12616 12617 if (!io || !sched) { 12618 ast_log(LOG_ERROR, "Out of memory\n"); 12619 return -1; 12620 } 12621 12622 netsock = ast_netsock_list_alloc(); 12623 if (!netsock) { 12624 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 12625 return -1; 12626 } 12627 ast_netsock_init(netsock); 12628 12629 outsock = ast_netsock_list_alloc(); 12630 if (!outsock) { 12631 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12632 return -1; 12633 } 12634 ast_netsock_init(outsock); 12635 12636 ast_mutex_init(&waresl.lock); 12637 12638 AST_LIST_HEAD_INIT(&iaxq.queue); 12639 12640 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 12641 12642 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 12643 12644 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 12645 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 12646 12647 if(set_config(config, 0) == -1) 12648 return AST_MODULE_LOAD_DECLINE; 12649 12650 if (ast_channel_register(&iax2_tech)) { 12651 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 12652 __unload_module(); 12653 return -1; 12654 } 12655 12656 if (ast_register_switch(&iax2_switch)) 12657 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 12658 12659 res = start_network_thread(); 12660 if (!res) { 12661 if (option_verbose > 1) 12662 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 12663 } else { 12664 ast_log(LOG_ERROR, "Unable to start network thread\n"); 12665 ast_netsock_release(netsock); 12666 ast_netsock_release(outsock); 12667 } 12668 12669 AST_LIST_LOCK(®istrations); 12670 AST_LIST_TRAVERSE(®istrations, reg, entry) 12671 iax2_do_register(reg); 12672 AST_LIST_UNLOCK(®istrations); 12673 12674 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 12675 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 12676 12677 reload_firmware(0); 12678 iax_provision_reload(); 12679 return res; 12680 }
static int load_objects | ( | void | ) | [static] |
Definition at line 12521 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, callno_pool, callno_pool_trunk, 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, pvt_cmp_cb(), pvt_hash_cb(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), and user_hash_cb().
Referenced by load_module().
12522 { 12523 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 12524 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 12525 12526 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 12527 goto container_fail; 12528 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 12529 goto container_fail; 12530 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 12531 goto container_fail; 12532 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 12533 goto container_fail; 12534 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 12535 goto container_fail; 12536 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12537 goto container_fail; 12538 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 12539 goto container_fail; 12540 } else if (create_callno_pools()) { 12541 goto container_fail; 12542 } 12543 12544 return 0; 12545 12546 container_fail: 12547 if (peers) { 12548 ao2_ref(peers, -1); 12549 } 12550 if (users) { 12551 ao2_ref(users, -1); 12552 } 12553 if (iax_peercallno_pvts) { 12554 ao2_ref(iax_peercallno_pvts, -1); 12555 } 12556 if (iax_transfercallno_pvts) { 12557 ao2_ref(iax_transfercallno_pvts, -1); 12558 } 12559 if (peercnts) { 12560 ao2_ref(peercnts, -1); 12561 } 12562 if (callno_limits) { 12563 ao2_ref(callno_limits, -1); 12564 } 12565 if (calltoken_ignores) { 12566 ao2_ref(calltoken_ignores, -1); 12567 } 12568 if (callno_pool) { 12569 ao2_ref(callno_pool, -1); 12570 } 12571 if (callno_pool_trunk) { 12572 ao2_ref(callno_pool_trunk, -1); 12573 } 12574 return AST_MODULE_LOAD_FAILURE; 12575 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4616 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
04617 { 04618 ast_mutex_lock(&iaxsl[callno0]); 04619 while (ast_mutex_trylock(&iaxsl[callno1])) { 04620 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 04621 } 04622 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1654 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, 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().
01655 { 01656 int x; 01657 int res= 0; 01658 struct callno_entry *callno_entry; 01659 if (iaxs[callno]->oseqno) { 01660 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01661 return -1; 01662 } 01663 if (callno & TRUNK_CALL_START) { 01664 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01665 return -1; 01666 } 01667 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01668 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01669 return -1; 01670 } 01671 01672 x = callno_entry->callno; 01673 ast_mutex_lock(&iaxsl[x]); 01674 01675 /*! 01676 * \note We delete these before switching the slot, because if 01677 * they fire in the meantime, they will generate a warning. 01678 */ 01679 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01680 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01681 iaxs[x] = iaxs[callno]; 01682 iaxs[x]->callno = x; 01683 01684 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01685 * before assigning the new one */ 01686 if (iaxs[x]->callno_entry) { 01687 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01688 } 01689 iaxs[x]->callno_entry = callno_entry; 01690 01691 iaxs[callno] = NULL; 01692 /* Update the two timers that should have been started */ 01693 iaxs[x]->pingid = iax2_sched_add(sched, 01694 ping_time * 1000, send_ping, (void *)(long)x); 01695 iaxs[x]->lagid = iax2_sched_add(sched, 01696 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01697 01698 if (locked) 01699 ast_mutex_unlock(&iaxsl[callno]); 01700 res = x; 01701 if (!locked) 01702 ast_mutex_unlock(&iaxsl[x]); 01703 01704 if (option_debug) 01705 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01706 /* We move this call from a non-trunked to a trunked call */ 01707 update_max_trunk(); 01708 update_max_nontrunk(); 01709 return res; 01710 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 5892 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
05893 { 05894 ast_cli_netstats(s, -1, 0); 05895 astman_append(s, "\r\n"); 05896 return RESULT_SUCCESS; 05897 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 5925 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
05926 { 05927 char *a[] = { "iax2", "show", "users" }; 05928 int ret; 05929 const char *id = astman_get_header(m,"ActionID"); 05930 05931 if (!ast_strlen_zero(id)) 05932 astman_append(s, "ActionID: %s\r\n",id); 05933 ret = __iax2_show_peers(1, -1, s, 3, a ); 05934 astman_append(s, "\r\n\r\n" ); 05935 return ret; 05936 } /* /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 1620 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().
01621 { 01622 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01623 (cur->addr.sin_port == sin->sin_port)) { 01624 /* This is the main host */ 01625 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01626 (check_dcallno ? dcallno == cur->callno : 1) ) { 01627 /* That's us. Be sure we keep track of the peer call number */ 01628 return 1; 01629 } 01630 } 01631 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01632 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01633 /* We're transferring */ 01634 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01635 return 1; 01636 } 01637 return 0; 01638 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5287 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05288 { 05289 #if 0 05290 /* Debug with "fake encryption" */ 05291 int x; 05292 if (len % 16) 05293 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05294 for (x=0;x<len;x++) 05295 dst[x] = src[x] ^ 0xff; 05296 #else 05297 unsigned char lastblock[16] = { 0 }; 05298 int x; 05299 while(len > 0) { 05300 aes_decrypt(src, dst, dcx); 05301 for (x=0;x<16;x++) 05302 dst[x] ^= lastblock[x]; 05303 memcpy(lastblock, src, sizeof(lastblock)); 05304 dst += 16; 05305 src += 16; 05306 len -= 16; 05307 } 05308 #endif 05309 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 5311 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05312 { 05313 #if 0 05314 /* Debug with "fake encryption" */ 05315 int x; 05316 if (len % 16) 05317 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05318 for (x=0;x<len;x++) 05319 dst[x] = src[x] ^ 0xff; 05320 #else 05321 unsigned char curblock[16] = { 0 }; 05322 int x; 05323 while(len > 0) { 05324 for (x=0;x<16;x++) 05325 curblock[x] ^= src[x]; 05326 aes_encrypt(curblock, dst, ecx); 05327 memcpy(curblock, dst, sizeof(curblock)); 05328 dst += 16; 05329 src += 16; 05330 len -= 16; 05331 } 05332 #endif 05333 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 6536 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
06537 { 06538 /* Select exactly one common encryption if there are any */ 06539 p->encmethods &= enc; 06540 if (p->encmethods) { 06541 if (p->encmethods & IAX_ENCRYPT_AES128) 06542 p->encmethods = IAX_ENCRYPT_AES128; 06543 else 06544 p->encmethods = 0; 06545 } 06546 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 10400 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().
10401 { 10402 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 10403 from the network, and queue them for delivery to the channels */ 10404 int res, count, wakeup; 10405 struct iax_frame *f; 10406 10407 if (timingfd > -1) 10408 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 10409 10410 for(;;) { 10411 pthread_testcancel(); 10412 10413 /* Go through the queue, sending messages which have not yet been 10414 sent, and scheduling retransmissions if appropriate */ 10415 AST_LIST_LOCK(&iaxq.queue); 10416 count = 0; 10417 wakeup = -1; 10418 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 10419 if (f->sentyet) 10420 continue; 10421 10422 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 10423 if (ast_mutex_trylock(&iaxsl[f->callno])) { 10424 wakeup = 1; 10425 continue; 10426 } 10427 10428 f->sentyet++; 10429 10430 if (iaxs[f->callno]) { 10431 send_packet(f); 10432 count++; 10433 } 10434 10435 ast_mutex_unlock(&iaxsl[f->callno]); 10436 10437 if (f->retries < 0) { 10438 /* This is not supposed to be retransmitted */ 10439 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 10440 iaxq.count--; 10441 /* Free the iax frame */ 10442 iax_frame_free(f); 10443 } else { 10444 /* We need reliable delivery. Schedule a retransmission */ 10445 f->retries++; 10446 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 10447 } 10448 } 10449 AST_LIST_TRAVERSE_SAFE_END 10450 AST_LIST_UNLOCK(&iaxq.queue); 10451 10452 pthread_testcancel(); 10453 10454 if (option_debug && count >= 20) 10455 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 10456 10457 /* Now do the IO, and run scheduled tasks */ 10458 res = ast_io_wait(io, wakeup); 10459 if (res >= 0) { 10460 if (option_debug && res >= 20) 10461 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 10462 } 10463 } 10464 return NULL; 10465 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1551 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), 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().
01552 { 01553 struct chan_iax2_pvt *tmp; 01554 jb_conf jbconf; 01555 01556 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01557 return NULL; 01558 } 01559 01560 if (ast_string_field_init(tmp, 32)) { 01561 ao2_ref(tmp, -1); 01562 tmp = NULL; 01563 return NULL; 01564 } 01565 01566 tmp->prefs = prefs; 01567 tmp->callno = 0; 01568 tmp->peercallno = 0; 01569 tmp->transfercallno = 0; 01570 tmp->bridgecallno = 0; 01571 tmp->pingid = -1; 01572 tmp->lagid = -1; 01573 tmp->autoid = -1; 01574 tmp->authid = -1; 01575 tmp->initid = -1; 01576 01577 ast_string_field_set(tmp,exten, "s"); 01578 ast_string_field_set(tmp,host, host); 01579 01580 tmp->jb = jb_new(); 01581 tmp->jbid = -1; 01582 jbconf.max_jitterbuf = maxjitterbuffer; 01583 jbconf.resync_threshold = resyncthreshold; 01584 jbconf.max_contig_interp = maxjitterinterps; 01585 jb_setconf(tmp->jb,&jbconf); 01586 01587 return tmp; 01588 }
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 4286 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().
04287 { 04288 if (ast_strlen_zero(data)) 04289 return; 04290 04291 pds->peer = strsep(&data, "/"); 04292 pds->exten = strsep(&data, "/"); 04293 pds->options = data; 04294 04295 if (pds->exten) { 04296 data = pds->exten; 04297 pds->exten = strsep(&data, "@"); 04298 pds->context = data; 04299 } 04300 04301 if (strchr(pds->peer, '@')) { 04302 data = pds->peer; 04303 pds->username = strsep(&data, "@"); 04304 pds->peer = data; 04305 } 04306 04307 if (pds->username) { 04308 data = pds->username; 04309 pds->username = strsep(&data, ":"); 04310 pds->password = data; 04311 } 04312 04313 data = pds->peer; 04314 pds->peer = strsep(&data, ":"); 04315 pds->port = data; 04316 04317 /* check for a key name wrapped in [] in the secret position, if found, 04318 move it to the key field instead 04319 */ 04320 if (pds->password && (pds->password[0] == '[')) { 04321 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04322 pds->password = NULL; 04323 } 04324 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1230 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_objects().
01231 { 01232 struct iax2_peer *peer = obj, *peer2 = arg; 01233 01234 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01235 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11127 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11128 { 11129 struct iax2_peer *peer = obj; 11130 11131 ast_set_flag(peer, IAX_DELME); 11132 11133 return 0; 11134 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 10623 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().
10624 { 10625 struct iax2_peer *peer = obj; 10626 int callno = peer->callno; 10627 10628 ast_free_ha(peer->ha); 10629 10630 if (callno > 0) { 10631 ast_mutex_lock(&iaxsl[callno]); 10632 iax2_destroy(callno); 10633 ast_mutex_unlock(&iaxsl[callno]); 10634 } 10635 10636 register_peer_exten(peer, 0); 10637 10638 if (peer->dnsmgr) 10639 ast_dnsmgr_release(peer->dnsmgr); 10640 10641 ast_string_field_free_memory(peer); 10642 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1220 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_objects().
01221 { 01222 const struct iax2_peer *peer = obj; 01223 01224 return ast_str_hash(peer->name); 01225 }
Definition at line 1277 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().
01278 { 01279 ao2_ref(peer, +1); 01280 return peer; 01281 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12474 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
12475 { 12476 struct iax2_peer *peer = obj; 12477 12478 if (peer->sockfd < 0) 12479 peer->sockfd = defaultsockfd; 12480 12481 return 0; 12482 }
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 10550 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().
10551 { 10552 struct sockaddr_in sin; 10553 int nonlocal = 1; 10554 int port = IAX_DEFAULT_PORTNO; 10555 int sockfd = defaultsockfd; 10556 char *tmp; 10557 char *addr; 10558 char *portstr; 10559 10560 if (!(tmp = ast_strdupa(srcaddr))) 10561 return -1; 10562 10563 addr = strsep(&tmp, ":"); 10564 portstr = tmp; 10565 10566 if (portstr) { 10567 port = atoi(portstr); 10568 if (port < 1) 10569 port = IAX_DEFAULT_PORTNO; 10570 } 10571 10572 if (!ast_get_ip(&sin, addr)) { 10573 struct ast_netsock *sock; 10574 int res; 10575 10576 sin.sin_port = 0; 10577 sin.sin_family = AF_INET; 10578 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 10579 if (res == 0) { 10580 /* ip address valid. */ 10581 sin.sin_port = htons(port); 10582 if (!(sock = ast_netsock_find(netsock, &sin))) 10583 sock = ast_netsock_find(outsock, &sin); 10584 if (sock) { 10585 sockfd = ast_netsock_sockfd(sock); 10586 nonlocal = 0; 10587 } else { 10588 unsigned int orig_saddr = sin.sin_addr.s_addr; 10589 /* INADDR_ANY matches anyway! */ 10590 sin.sin_addr.s_addr = INADDR_ANY; 10591 if (ast_netsock_find(netsock, &sin)) { 10592 sin.sin_addr.s_addr = orig_saddr; 10593 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 10594 if (sock) { 10595 sockfd = ast_netsock_sockfd(sock); 10596 ast_netsock_unref(sock); 10597 nonlocal = 0; 10598 } else { 10599 nonlocal = 2; 10600 } 10601 } 10602 } 10603 } 10604 } 10605 10606 peer->sockfd = sockfd; 10607 10608 if (nonlocal == 1) { 10609 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 10610 srcaddr, peer->name); 10611 return -1; 10612 } else if (nonlocal == 2) { 10613 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 10614 srcaddr, peer->name); 10615 return -1; 10616 } else { 10617 if (option_debug) 10618 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 10619 return 0; 10620 } 10621 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3166 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().
03167 { 03168 int res = 0; 03169 if (peer->maxms) { 03170 if (peer->lastms < 0) { 03171 ast_copy_string(status, "UNREACHABLE", statuslen); 03172 } else if (peer->lastms > peer->maxms) { 03173 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03174 res = 1; 03175 } else if (peer->lastms) { 03176 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03177 res = 1; 03178 } else { 03179 ast_copy_string(status, "UNKNOWN", statuslen); 03180 } 03181 } else { 03182 ast_copy_string(status, "Unmonitored", statuslen); 03183 res = -1; 03184 } 03185 return res; 03186 }
Definition at line 1283 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().
01284 { 01285 ao2_ref(peer, -1); 01286 return NULL; 01287 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 1901 of file chan_iax2.c.
References peercnt::addr, ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_inet_ntoa(), ast_log(), LOG_ERROR, LOG_NOTICE, option_debug, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
01902 { 01903 struct peercnt *peercnt; 01904 unsigned long addr = sin->sin_addr.s_addr; 01905 int res = 0; 01906 struct peercnt tmp = { 01907 .addr = addr, 01908 }; 01909 01910 /* Reasoning for peercnts container lock: Two identical ip addresses 01911 * could be added by different threads at the "same time". Without the container 01912 * lock, both threads could alloc space for the same object and attempt 01913 * to link to table. With the lock, one would create the object and link 01914 * to table while the other would find the already created peercnt object 01915 * rather than creating a new one. */ 01916 ao2_lock(peercnts); 01917 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 01918 ao2_lock(peercnt); 01919 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 01920 ao2_lock(peercnt); 01921 /* create and set defaults */ 01922 peercnt->addr = addr; 01923 set_peercnt_limit(peercnt); 01924 /* guarantees it does not go away after unlocking table 01925 * ao2_find automatically adds this */ 01926 ao2_link(peercnts, peercnt); 01927 } else { 01928 ao2_unlock(peercnts); 01929 return -1; 01930 } 01931 01932 /* check to see if the address has hit its callno limit. If not increment cur. */ 01933 if (peercnt->limit > peercnt->cur) { 01934 peercnt->cur++; 01935 if (option_debug) { 01936 ast_log(LOG_NOTICE, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 01937 } 01938 } else { /* max num call numbers for this peer has been reached! */ 01939 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 01940 res = -1; 01941 } 01942 01943 /* clean up locks and ref count */ 01944 ao2_unlock(peercnt); 01945 ao2_unlock(peercnts); 01946 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 01947 01948 return res; 01949 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1739 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
01740 { 01741 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 01742 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 01743 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1733 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 1871 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), peercnt::limit, LOG_NOTICE, option_debug, peercnts, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
01872 { 01873 /* this function turns off and on custom callno limits set by peer registration */ 01874 struct peercnt *peercnt; 01875 struct peercnt tmp = { 01876 .addr = sin->sin_addr.s_addr, 01877 }; 01878 01879 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 01880 peercnt->reg = reg; 01881 if (limit) { 01882 peercnt->limit = limit; 01883 } else { 01884 set_peercnt_limit(peercnt); 01885 } 01886 if (option_debug) { 01887 ast_log(LOG_NOTICE, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 01888 } 01889 ao2_ref(peercnt, -1); /* decrement ref from find */ 01890 } 01891 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1955 of file chan_iax2.c.
References peercnt::addr, ao2_lock(), ao2_unlink(), ao2_unlock(), ast_inet_ntoa(), ast_log(), peercnt::cur, LOG_NOTICE, option_debug, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
01956 { 01957 struct sockaddr_in sin = { 01958 .sin_addr.s_addr = peercnt->addr, 01959 }; 01960 01961 if (peercnt) { 01962 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 01963 * peercnt_add could try and grab this entry from the table and modify it at the 01964 * "same time" this thread attemps to unlink it.*/ 01965 ao2_lock(peercnts); 01966 peercnt->cur--; 01967 if (option_debug) { 01968 ast_log(LOG_NOTICE, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 01969 } 01970 /* if this was the last connection from the peer remove it from table */ 01971 if (peercnt->cur == 0) { 01972 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 01973 } 01974 ao2_unlock(peercnts); 01975 } 01976 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 1996 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
01997 { 01998 struct peercnt *peercnt; 01999 struct peercnt tmp = { 02000 .addr = sin->sin_addr.s_addr, 02001 }; 02002 02003 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02004 peercnt_remove(peercnt); 02005 ao2_ref(peercnt, -1); /* decrement ref from find */ 02006 } 02007 return 0; 02008 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 1982 of file chan_iax2.c.
References ao2_ref(), and peercnt_remove().
Referenced by sched_delay_remove().
01983 { 01984 struct peercnt *peercnt = (struct peercnt *) obj; 01985 01986 peercnt_remove(peercnt); 01987 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 01988 01989 return 0; 01990 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 11609 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
11610 { 11611 struct ao2_iterator i; 11612 struct iax2_peer *peer; 11613 11614 i = ao2_iterator_init(peers, 0); 11615 while ((peer = ao2_iterator_next(&i))) { 11616 iax2_poke_peer(peer, 0); 11617 peer_unref(peer); 11618 } 11619 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1860 of file chan_iax2.c.
References addr_range::delme.
Referenced by reload_config().
01861 { 01862 struct addr_range *addr_range = obj; 01863 01864 return addr_range->delme ? CMP_MATCH : 0; 01865 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 11187 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
11188 { 11189 struct iax2_peer *peer; 11190 struct ao2_iterator i; 11191 11192 i = ao2_iterator_init(peers, 0); 11193 while ((peer = ao2_iterator_next(&i))) { 11194 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 11195 unlink_peer(peer); 11196 } 11197 peer_unref(peer); 11198 } 11199 }
static void prune_users | ( | void | ) | [static] |
Definition at line 11172 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by iax2_prune_realtime(), and reload_config().
11173 { 11174 struct iax2_user *user; 11175 struct ao2_iterator i; 11176 11177 i = ao2_iterator_init(users, 0); 11178 while ((user = ao2_iterator_next(&i))) { 11179 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 11180 ao2_unlink(users, user); 11181 } 11182 user_unref(user); 11183 } 11184 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12491 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12492 { 12493 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12494 12495 /* The frames_received field is used to hold whether we're matching 12496 * against a full frame or not ... */ 12497 12498 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 12499 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12500 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1510 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_LOCK, 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, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax_frame::list, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), and chan_iax2_pvt::vars.
Referenced by new_iax().
01511 { 01512 struct chan_iax2_pvt *pvt = obj; 01513 struct iax_frame *cur = NULL; 01514 01515 iax2_destroy_helper(pvt); 01516 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01517 pvt->callno_entry = NULL; 01518 01519 /* Already gone */ 01520 ast_set_flag(pvt, IAX_ALREADYGONE); 01521 01522 AST_LIST_LOCK(&iaxq.queue); 01523 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01524 /* Cancel any pending transmissions */ 01525 if (cur->callno == pvt->callno) { 01526 cur->retries = -1; 01527 } 01528 } 01529 AST_LIST_UNLOCK(&iaxq.queue); 01530 01531 if (pvt->reg) { 01532 pvt->reg->callno = 0; 01533 } 01534 01535 if (!pvt->owner) { 01536 jb_frame frame; 01537 if (pvt->vars) { 01538 ast_variables_destroy(pvt->vars); 01539 pvt->vars = NULL; 01540 } 01541 01542 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01543 iax2_frame_free(frame.data); 01544 } 01545 01546 jb_destroy(pvt->jb); 01547 ast_string_field_free_memory(pvt); 01548 } 01549 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12484 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
12485 { 12486 const struct chan_iax2_pvt *pvt = obj; 12487 12488 return pvt->peercallno; 12489 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 6518 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().
06519 { 06520 struct ast_iax2_full_hdr fh; 06521 fh.scallno = htons(src | IAX_FLAG_FULL); 06522 fh.dcallno = htons(dst); 06523 fh.ts = 0; 06524 fh.oseqno = 0; 06525 fh.iseqno = 0; 06526 fh.type = AST_FRAME_IAX; 06527 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 06528 if (iaxdebug) 06529 iax_showframe(NULL, &fh, 0, sin, 0); 06530 if (option_debug) 06531 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 06532 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 06533 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 06534 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3652 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.
03653 { 03654 struct ast_variable *var = NULL; 03655 struct ast_variable *tmp; 03656 struct iax2_peer *peer=NULL; 03657 time_t regseconds = 0, nowtime; 03658 int dynamic=0; 03659 03660 if (peername) { 03661 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 03662 if (!var && sin) 03663 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03664 } else if (sin) { 03665 char porta[25]; 03666 sprintf(porta, "%d", ntohs(sin->sin_port)); 03667 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03668 if (var) { 03669 /* We'll need the peer name in order to build the structure! */ 03670 for (tmp = var; tmp; tmp = tmp->next) { 03671 if (!strcasecmp(tmp->name, "name")) 03672 peername = tmp->value; 03673 } 03674 } 03675 } 03676 if (!var && peername) { /* Last ditch effort */ 03677 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 03678 /*!\note 03679 * If this one loaded something, then we need to ensure that the host 03680 * field matched. The only reason why we can't have this as a criteria 03681 * is because we only have the IP address and the host field might be 03682 * set as a name (and the reverse PTR might not match). 03683 */ 03684 if (var && sin) { 03685 for (tmp = var; tmp; tmp = tmp->next) { 03686 if (!strcasecmp(tmp->name, "host")) { 03687 struct ast_hostent ahp; 03688 struct hostent *hp; 03689 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03690 /* No match */ 03691 ast_variables_destroy(var); 03692 var = NULL; 03693 } 03694 break; 03695 } 03696 } 03697 } 03698 } 03699 if (!var) 03700 return NULL; 03701 03702 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 03703 03704 if (!peer) { 03705 ast_variables_destroy(var); 03706 return NULL; 03707 } 03708 03709 for (tmp = var; tmp; tmp = tmp->next) { 03710 /* Make sure it's not a user only... */ 03711 if (!strcasecmp(tmp->name, "type")) { 03712 if (strcasecmp(tmp->value, "friend") && 03713 strcasecmp(tmp->value, "peer")) { 03714 /* Whoops, we weren't supposed to exist! */ 03715 peer = peer_unref(peer); 03716 break; 03717 } 03718 } else if (!strcasecmp(tmp->name, "regseconds")) { 03719 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 03720 } else if (!strcasecmp(tmp->name, "ipaddr")) { 03721 inet_aton(tmp->value, &(peer->addr.sin_addr)); 03722 } else if (!strcasecmp(tmp->name, "port")) { 03723 peer->addr.sin_port = htons(atoi(tmp->value)); 03724 } else if (!strcasecmp(tmp->name, "host")) { 03725 if (!strcasecmp(tmp->value, "dynamic")) 03726 dynamic = 1; 03727 } 03728 } 03729 03730 ast_variables_destroy(var); 03731 03732 if (!peer) 03733 return NULL; 03734 03735 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03736 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 03737 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 03738 if (peer->expire > -1) { 03739 if (!ast_sched_del(sched, peer->expire)) { 03740 peer->expire = -1; 03741 peer_unref(peer); 03742 } 03743 } 03744 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 03745 if (peer->expire == -1) 03746 peer_unref(peer); 03747 } 03748 ao2_link(peers, peer); 03749 if (ast_test_flag(peer, IAX_DYNAMIC)) 03750 reg_source_db(peer); 03751 } else { 03752 ast_set_flag(peer, IAX_TEMPONLY); 03753 } 03754 03755 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 03756 time(&nowtime); 03757 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 03758 memset(&peer->addr, 0, sizeof(peer->addr)); 03759 realtime_update_peer(peer->name, &peer->addr, 0); 03760 if (option_debug) 03761 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 03762 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03763 } 03764 else { 03765 if (option_debug) 03766 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 03767 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03768 } 03769 } 03770 03771 return peer; 03772 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3845 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03846 { 03847 char port[10]; 03848 char regseconds[20]; 03849 03850 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03851 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03852 ast_update_realtime("iaxpeers", "name", peername, 03853 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03854 "regseconds", regseconds, NULL); 03855 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3774 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.
03775 { 03776 struct ast_variable *var; 03777 struct ast_variable *tmp; 03778 struct iax2_user *user=NULL; 03779 03780 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 03781 if (!var) 03782 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03783 if (!var && sin) { 03784 char porta[6]; 03785 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 03786 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03787 if (!var) 03788 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03789 } 03790 if (!var) { /* Last ditch effort */ 03791 var = ast_load_realtime("iaxusers", "name", username, NULL); 03792 /*!\note 03793 * If this one loaded something, then we need to ensure that the host 03794 * field matched. The only reason why we can't have this as a criteria 03795 * is because we only have the IP address and the host field might be 03796 * set as a name (and the reverse PTR might not match). 03797 */ 03798 if (var) { 03799 for (tmp = var; tmp; tmp = tmp->next) { 03800 if (!strcasecmp(tmp->name, "host")) { 03801 struct ast_hostent ahp; 03802 struct hostent *hp; 03803 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03804 /* No match */ 03805 ast_variables_destroy(var); 03806 var = NULL; 03807 } 03808 break; 03809 } 03810 } 03811 } 03812 } 03813 if (!var) 03814 return NULL; 03815 03816 tmp = var; 03817 while(tmp) { 03818 /* Make sure it's not a peer only... */ 03819 if (!strcasecmp(tmp->name, "type")) { 03820 if (strcasecmp(tmp->value, "friend") && 03821 strcasecmp(tmp->value, "user")) { 03822 return NULL; 03823 } 03824 } 03825 tmp = tmp->next; 03826 } 03827 03828 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03829 03830 ast_variables_destroy(var); 03831 03832 if (!user) 03833 return NULL; 03834 03835 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03836 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03837 ao2_link(users, user); 03838 } else { 03839 ast_set_flag(user, IAX_TEMPONLY); 03840 } 03841 03842 return user; 03843 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 7340 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().
07341 { 07342 char data[80]; 07343 struct in_addr in; 07344 char *c, *d; 07345 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 07346 c = strchr(data, ':'); 07347 if (c) { 07348 *c = '\0'; 07349 c++; 07350 if (inet_aton(data, &in)) { 07351 d = strchr(c, ':'); 07352 if (d) { 07353 *d = '\0'; 07354 d++; 07355 if (option_verbose > 2) 07356 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 07357 ast_inet_ntoa(in), atoi(c), atoi(d)); 07358 iax2_poke_peer(p, 0); 07359 p->expiry = atoi(d); 07360 memset(&p->addr, 0, sizeof(p->addr)); 07361 p->addr.sin_family = AF_INET; 07362 p->addr.sin_addr = in; 07363 p->addr.sin_port = htons(atoi(c)); 07364 if (p->expire > -1) { 07365 if (!ast_sched_del(sched, p->expire)) { 07366 p->expire = -1; 07367 peer_unref(p); 07368 } 07369 } 07370 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07371 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07372 if (p->expire == -1) 07373 peer_unref(p); 07374 if (iax2_regfunk) 07375 iax2_regfunk(p->name, 1); 07376 register_peer_exten(p, 1); 07377 } 07378 07379 } 07380 } 07381 } 07382 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 7258 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().
07259 { 07260 char multi[256]; 07261 char *stringp, *ext; 07262 if (!ast_strlen_zero(regcontext)) { 07263 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 07264 stringp = multi; 07265 while((ext = strsep(&stringp, "&"))) { 07266 if (onoff) { 07267 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 07268 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 07269 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 07270 } else 07271 ast_context_remove_extension(regcontext, ext, 1, NULL); 07272 } 07273 } 07274 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 6685 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().
06686 { 06687 char requeststr[256] = ""; 06688 char peer[256] = ""; 06689 char md5secret[256] = ""; 06690 char rsasecret[256] = ""; 06691 char secret[256] = ""; 06692 struct iax2_peer *p = NULL; 06693 struct ast_key *key; 06694 char *keyn; 06695 int x; 06696 int expire = 0; 06697 int res = -1; 06698 06699 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06700 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 06701 if (ies->username) 06702 ast_copy_string(peer, ies->username, sizeof(peer)); 06703 if (ies->password) 06704 ast_copy_string(secret, ies->password, sizeof(secret)); 06705 if (ies->md5_result) 06706 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 06707 if (ies->rsa_result) 06708 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 06709 if (ies->refresh) 06710 expire = ies->refresh; 06711 06712 if (ast_strlen_zero(peer)) { 06713 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 06714 return -1; 06715 } 06716 06717 /* SLD: first call to lookup peer during registration */ 06718 ast_mutex_unlock(&iaxsl[callno]); 06719 p = find_peer(peer, 1); 06720 ast_mutex_lock(&iaxsl[callno]); 06721 if (!p || !iaxs[callno]) { 06722 if (iaxs[callno]) { 06723 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 06724 06725 ast_string_field_set(iaxs[callno], secret, "badsecret"); 06726 06727 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 06728 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 06729 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 06730 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 06731 * to be plaintext, indicating it is an authmethod used by other peers on the system. 06732 * 06733 * If none of these cases exist, res will be returned as 0 without authentication indicating 06734 * an AUTHREQ needs to be sent out. */ 06735 06736 if (ast_strlen_zero(iaxs[callno]->challenge) && 06737 !(!ast_strlen_zero(secret) && plaintext)) { 06738 /* by setting res to 0, an REGAUTH will be sent */ 06739 res = 0; 06740 } 06741 } 06742 if (authdebug && !p) 06743 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06744 06745 goto return_unref; 06746 } 06747 06748 if (!ast_test_flag(p, IAX_DYNAMIC)) { 06749 if (authdebug) 06750 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 06751 goto return_unref; 06752 } 06753 06754 if (!ast_apply_ha(p->ha, sin)) { 06755 if (authdebug) 06756 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06757 goto return_unref; 06758 } 06759 ast_string_field_set(iaxs[callno], secret, p->secret); 06760 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 06761 /* Check secret against what we have on file */ 06762 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06763 if (!ast_strlen_zero(p->inkeys)) { 06764 char tmpkeys[256]; 06765 char *stringp=NULL; 06766 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 06767 stringp=tmpkeys; 06768 keyn = strsep(&stringp, ":"); 06769 while(keyn) { 06770 key = ast_key_get(keyn, AST_KEY_PUBLIC); 06771 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 06772 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06773 break; 06774 } else if (!key) 06775 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 06776 keyn = strsep(&stringp, ":"); 06777 } 06778 if (!keyn) { 06779 if (authdebug) 06780 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 06781 goto return_unref; 06782 } 06783 } else { 06784 if (authdebug) 06785 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 06786 goto return_unref; 06787 } 06788 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 06789 struct MD5Context md5; 06790 unsigned char digest[16]; 06791 char *tmppw, *stringp; 06792 06793 tmppw = ast_strdupa(p->secret); 06794 stringp = tmppw; 06795 while((tmppw = strsep(&stringp, ";"))) { 06796 MD5Init(&md5); 06797 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06798 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06799 MD5Final(digest, &md5); 06800 for (x=0;x<16;x++) 06801 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 06802 if (!strcasecmp(requeststr, md5secret)) 06803 break; 06804 } 06805 if (tmppw) { 06806 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06807 } else { 06808 if (authdebug) 06809 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 06810 goto return_unref; 06811 } 06812 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 06813 /* They've provided a plain text password and we support that */ 06814 if (strcmp(secret, p->secret)) { 06815 if (authdebug) 06816 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 06817 goto return_unref; 06818 } else 06819 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 06820 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 06821 /* if challenge has been sent, but no challenge response if given, reject. */ 06822 goto return_unref; 06823 } 06824 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06825 06826 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 06827 res = 0; 06828 return_unref: 06829 06830 if (iaxs[callno]) { 06831 ast_string_field_set(iaxs[callno], peer, peer); 06832 06833 /* Choose lowest expiry number */ 06834 if (expire && (expire < iaxs[callno]->expiry)) { 06835 iaxs[callno]->expiry = expire; 06836 } 06837 } 06838 06839 if (p) { 06840 peer_unref(p); 06841 } 06842 return res; 06843 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 7529 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().
07530 { 07531 struct iax_ie_data ied; 07532 struct iax2_peer *p; 07533 char challenge[10]; 07534 const char *peer_name; 07535 int sentauthmethod; 07536 07537 peer_name = ast_strdupa(iaxs[callno]->peer); 07538 07539 /* SLD: third call to find_peer in registration */ 07540 ast_mutex_unlock(&iaxsl[callno]); 07541 if ((p = find_peer(peer_name, 1))) { 07542 last_authmethod = p->authmethods; 07543 } 07544 07545 ast_mutex_lock(&iaxsl[callno]); 07546 if (!iaxs[callno]) 07547 goto return_unref; 07548 07549 memset(&ied, 0, sizeof(ied)); 07550 /* The selection of which delayed reject is sent may leak information, 07551 * if it sets a static response. For example, if a host is known to only 07552 * use MD5 authentication, then an RSA response would indicate that the 07553 * peer does not exist, and vice-versa. 07554 * Therefore, we use whatever the last peer used (which may vary over the 07555 * course of a server, which should leak minimal information). */ 07556 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07557 if (!p) { 07558 iaxs[callno]->authmethods = sentauthmethod; 07559 } 07560 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 07561 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 07562 /* Build the challenge */ 07563 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07564 ast_string_field_set(iaxs[callno], challenge, challenge); 07565 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 07566 } 07567 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 07568 07569 return_unref: 07570 if (p) { 07571 peer_unref(p); 07572 } 07573 07574 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 07575 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 7577 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().
07578 { 07579 struct iax2_registry *reg; 07580 /* Start pessimistic */ 07581 struct iax_ie_data ied; 07582 char peer[256] = ""; 07583 char challenge[256] = ""; 07584 int res; 07585 int authmethods = 0; 07586 if (ies->authmethods) 07587 authmethods = ies->authmethods; 07588 if (ies->username) 07589 ast_copy_string(peer, ies->username, sizeof(peer)); 07590 if (ies->challenge) 07591 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 07592 memset(&ied, 0, sizeof(ied)); 07593 reg = iaxs[callno]->reg; 07594 if (reg) { 07595 if (inaddrcmp(®->addr, sin)) { 07596 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07597 return -1; 07598 } 07599 if (ast_strlen_zero(reg->secret)) { 07600 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 07601 reg->regstate = REG_STATE_NOAUTH; 07602 return -1; 07603 } 07604 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07605 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07606 if (reg->secret[0] == '[') { 07607 char tmpkey[256]; 07608 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 07609 tmpkey[strlen(tmpkey) - 1] = '\0'; 07610 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 07611 } else 07612 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 07613 if (!res) { 07614 reg->regstate = REG_STATE_AUTHSENT; 07615 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 07616 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07617 } else 07618 return -1; 07619 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 07620 } else 07621 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 07622 return -1; 07623 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 5938 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().
05939 { 05940 switch(regstate) { 05941 case REG_STATE_UNREGISTERED: 05942 return "Unregistered"; 05943 case REG_STATE_REGSENT: 05944 return "Request Sent"; 05945 case REG_STATE_AUTHSENT: 05946 return "Auth. Sent"; 05947 case REG_STATE_REGISTERED: 05948 return "Registered"; 05949 case REG_STATE_REJECTED: 05950 return "Rejected"; 05951 case REG_STATE_TIMEOUT: 05952 return "Timeout"; 05953 case REG_STATE_NOAUTH: 05954 return "No Authentication"; 05955 default: 05956 return "Unknown"; 05957 } 05958 }
static int reload | ( | void | ) | [static] |
Definition at line 11649 of file chan_iax2.c.
References reload_config().
11650 { 11651 return reload_config(); 11652 }
static int reload_config | ( | void | ) | [static] |
Definition at line 11620 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().
11621 { 11622 static const char config[] = "iax.conf"; 11623 struct iax2_registry *reg; 11624 11625 if (set_config(config, 1) > 0) { 11626 prune_peers(); 11627 prune_users(); 11628 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11629 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 11630 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 11631 AST_LIST_LOCK(®istrations); 11632 AST_LIST_TRAVERSE(®istrations, reg, entry) 11633 iax2_do_register(reg); 11634 AST_LIST_UNLOCK(®istrations); 11635 /* Qualify hosts, too */ 11636 poke_all_peers(); 11637 } 11638 reload_firmware(0); 11639 iax_provision_reload(); 11640 11641 return 0; 11642 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2778 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().
02779 { 02780 struct iax_firmware *cur, *curl, *curp; 02781 DIR *fwd; 02782 struct dirent *de; 02783 char dir[256]; 02784 char fn[256]; 02785 /* Mark all as dead */ 02786 ast_mutex_lock(&waresl.lock); 02787 cur = waresl.wares; 02788 while(cur) { 02789 cur->dead = 1; 02790 cur = cur->next; 02791 } 02792 02793 /* Now that we've freed them, load the new ones */ 02794 if (!unload) { 02795 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02796 fwd = opendir(dir); 02797 if (fwd) { 02798 while((de = readdir(fwd))) { 02799 if (de->d_name[0] != '.') { 02800 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02801 if (!try_firmware(fn)) { 02802 if (option_verbose > 1) 02803 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02804 } 02805 } 02806 } 02807 closedir(fwd); 02808 } else 02809 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02810 } 02811 02812 /* Clean up leftovers */ 02813 cur = waresl.wares; 02814 curp = NULL; 02815 while(cur) { 02816 curl = cur; 02817 cur = cur->next; 02818 if (curl->dead) { 02819 if (curp) { 02820 curp->next = cur; 02821 } else { 02822 waresl.wares = cur; 02823 } 02824 destroy_firmware(curl); 02825 } else { 02826 curp = cur; 02827 } 02828 } 02829 ast_mutex_unlock(&waresl.lock); 02830 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1396 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().
01397 { 01398 if (!pvt->peercallno) { 01399 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01400 return; 01401 } 01402 01403 ao2_unlink(iax_peercallno_pvts, pvt); 01404 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1377 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().
01378 { 01379 if (!pvt->transfercallno) { 01380 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01381 return; 01382 } 01383 01384 ao2_unlink(iax_transfercallno_pvts, pvt); 01385 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2175 of file chan_iax2.c.
References ao2_lock(), ao2_ref(), ao2_unlock(), ast_log(), callno_entry::callno, callno_pool, callno_pool_trunk, LOG_ERROR, total_nonval_callno_used, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02176 { 02177 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02178 02179 /* the callno_pool container is locked here primarily to ensure thread 02180 * safety of the total_nonval_callno_used check and decrement */ 02181 ao2_lock(callno_pool); 02182 02183 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02184 total_nonval_callno_used--; 02185 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02186 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02187 } 02188 02189 if (callno_entry->callno < TRUNK_CALL_START) { 02190 ao2_link(callno_pool, callno_entry); 02191 } else { 02192 ao2_link(callno_pool_trunk, callno_entry); 02193 } 02194 ao2_ref(callno_entry, -1); /* only container ref remains */ 02195 02196 ao2_unlock(callno_pool); 02197 return 0; 02198 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4143 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().
04144 { 04145 struct iax2_user *user = NULL; 04146 struct iax2_peer *peer = NULL; 04147 04148 if (ast_strlen_zero(name)) { 04149 return; /* no username given */ 04150 } 04151 04152 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04153 user->calltoken_required = CALLTOKEN_YES; 04154 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04155 peer->calltoken_required = CALLTOKEN_YES; 04156 } 04157 04158 if (peer) { 04159 peer_unref(peer); 04160 } 04161 if (user) { 04162 user_unref(user); 04163 } 04164 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4059 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().
04060 { 04061 struct chan_iax2_pvt *pvt = iaxs[callno]; 04062 int frametype = f->af.frametype; 04063 int subclass = f->af.subclass; 04064 struct { 04065 struct ast_iax2_full_hdr fh; 04066 struct iax_ie_data ied; 04067 } data = { 04068 .ied.buf = { 0 }, 04069 .ied.pos = 0, 04070 }; 04071 /* total len - header len gives us the frame's IE len */ 04072 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04073 04074 if (!pvt) { 04075 return; /* this should not be possible if called from socket_process() */ 04076 } 04077 04078 /* 04079 * Check to make sure last frame sent is valid for call token resend 04080 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04081 * 2. Frame should _NOT_ already have a destination callno 04082 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04083 * 4. Pvt must have a calltoken_ie_len which represents the number of 04084 * bytes at the end of the frame used for the previous calltoken ie. 04085 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04086 * 6. Total length of f->data must be _LESS_ than size of our data struct 04087 * because f->data must be able to fit within data. 04088 */ 04089 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04090 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04091 (f->datalen > sizeof(data))) { 04092 04093 return; /* ignore resend, token was not valid for the dialog */ 04094 } 04095 04096 /* token is valid 04097 * 1. Copy frame data over 04098 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04099 * NOTE: Having the ie always be last is not protocol specified, 04100 * it is only an implementation choice. Since we only expect the ie to 04101 * be last for frames we have sent, this can no way be affected by 04102 * another end point. 04103 * 3. Remove frame from queue 04104 * 4. Free old frame 04105 * 5. Clear previous seqnos 04106 * 6. Resend with CALLTOKEN ie. 04107 */ 04108 04109 /* ---1.--- */ 04110 memcpy(&data, f->data, f->datalen); 04111 data.ied.pos = ie_data_pos; 04112 04113 /* ---2.--- */ 04114 /* move to the beginning of the calltoken ie so we can write over it */ 04115 data.ied.pos -= pvt->calltoken_ie_len; 04116 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04117 04118 /* make sure to update token length incase it ever has to be stripped off again */ 04119 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04120 04121 /* ---3.--- */ 04122 AST_LIST_LOCK(&iaxq.queue); 04123 AST_LIST_REMOVE(&iaxq.queue, f, list); 04124 AST_LIST_UNLOCK(&iaxq.queue); 04125 04126 /* ---4.--- */ 04127 iax2_frame_free(f); 04128 04129 /* ---5.--- */ 04130 pvt->oseqno = 0; 04131 pvt->rseqno = 0; 04132 pvt->iseqno = 0; 04133 pvt->aseqno = 0; 04134 if (pvt->peercallno) { 04135 remove_by_peercallno(pvt); 04136 pvt->peercallno = 0; 04137 } 04138 04139 /* ---6.--- */ 04140 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04141 }
Definition at line 8082 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().
08083 { 08084 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 08085 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 08086 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 08087 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 08088 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 08089 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 08090 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 08091 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2247 of file chan_iax2.c.
References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), iax2_sched_add(), LOG_NOTICE, MIN_REUSE_TIME, option_debug, peercnt_remove_cb(), peercnts, replace_callno(), and sched.
Referenced by pvt_destructor().
02248 { 02249 int i; 02250 struct peercnt *peercnt; 02251 struct peercnt tmp = { 02252 .addr = sin->sin_addr.s_addr, 02253 }; 02254 02255 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02256 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02257 if (option_debug) { 02258 ast_log(LOG_NOTICE, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02259 } 02260 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02261 if (i == -1) { 02262 ao2_ref(peercnt, -1); 02263 } 02264 } 02265 02266 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02267 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 10365 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), option_debug, sched, and sched_lock.
Referenced by start_network_thread().
10366 { 10367 for (;;) { 10368 int ms, count; 10369 struct timespec ts; 10370 10371 pthread_testcancel(); 10372 10373 ast_mutex_lock(&sched_lock); 10374 10375 ms = ast_sched_wait(sched); 10376 10377 if (ms == -1) { 10378 ast_cond_wait(&sched_cond, &sched_lock); 10379 } else { 10380 struct timeval tv; 10381 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 10382 ts.tv_sec = tv.tv_sec; 10383 ts.tv_nsec = tv.tv_usec * 1000; 10384 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 10385 } 10386 10387 ast_mutex_unlock(&sched_lock); 10388 10389 pthread_testcancel(); 10390 10391 count = ast_sched_runq(sched); 10392 if (option_debug && count >= 20) { 10393 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 10394 } 10395 } 10396 10397 return NULL; 10398 }
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 3505 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
03506 { 03507 int type, len; 03508 int ret; 03509 int needfree = 0; 03510 struct ast_channel *owner = NULL; 03511 struct ast_channel *bridge = NULL; 03512 03513 /* Attempt to recover wrapped timestamps */ 03514 unwrap_timestamp(fr); 03515 03516 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03517 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03518 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03519 else { 03520 #if 0 03521 if (option_debug) 03522 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03523 #endif 03524 fr->af.delivery = ast_tv(0,0); 03525 } 03526 03527 type = JB_TYPE_CONTROL; 03528 len = 0; 03529 03530 if(fr->af.frametype == AST_FRAME_VOICE) { 03531 type = JB_TYPE_VOICE; 03532 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03533 } else if(fr->af.frametype == AST_FRAME_CNG) { 03534 type = JB_TYPE_SILENCE; 03535 } 03536 03537 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 03538 if (tsout) 03539 *tsout = fr->ts; 03540 __do_deliver(fr); 03541 return -1; 03542 } 03543 03544 if ((owner = iaxs[fr->callno]->owner)) 03545 bridge = ast_bridged_channel(owner); 03546 03547 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 03548 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 03549 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 03550 jb_frame frame; 03551 03552 /* deliver any frames in the jb */ 03553 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 03554 __do_deliver(frame.data); 03555 /* __do_deliver() can make the call disappear */ 03556 if (!iaxs[fr->callno]) 03557 return -1; 03558 } 03559 03560 jb_reset(iaxs[fr->callno]->jb); 03561 03562 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 03563 03564 /* deliver this frame now */ 03565 if (tsout) 03566 *tsout = fr->ts; 03567 __do_deliver(fr); 03568 return -1; 03569 } 03570 03571 /* insert into jitterbuffer */ 03572 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 03573 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 03574 calc_rxstamp(iaxs[fr->callno],fr->ts)); 03575 if (ret == JB_DROP) { 03576 needfree++; 03577 } else if (ret == JB_SCHED) { 03578 update_jbsched(iaxs[fr->callno]); 03579 } 03580 if (tsout) 03581 *tsout = fr->ts; 03582 if (needfree) { 03583 /* Free our iax frame */ 03584 iax2_frame_free(fr); 03585 return -1; 03586 } 03587 return 0; 03588 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1496 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_destroy(), iaxs, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01497 { 01498 short callno = PTR_TO_CALLNO(vid); 01499 ast_mutex_lock(&iaxsl[callno]); 01500 if (iaxs[callno]) { 01501 if (option_debug) { 01502 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01503 } 01504 iax2_destroy(callno); 01505 } 01506 ast_mutex_unlock(&iaxsl[callno]); 01507 return 0; 01508 }
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 4023 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().
04026 { 04027 struct { 04028 struct ast_iax2_full_hdr f; 04029 struct iax_ie_data ied; 04030 } data; 04031 size_t size = sizeof(struct ast_iax2_full_hdr); 04032 04033 if (ied) { 04034 size += ied->pos; 04035 memcpy(&data.ied, ied->buf, ied->pos); 04036 } 04037 04038 data.f.scallno = htons(0x8000 | callno); 04039 data.f.dcallno = htons(dcallno); 04040 data.f.ts = htonl(ts); 04041 data.f.iseqno = seqno; 04042 data.f.oseqno = 0; 04043 data.f.type = AST_FRAME_IAX; 04044 data.f.csub = compress_subclass(command); 04045 04046 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04047 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6246 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().
06247 { 06248 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 06249 }
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 6265 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().
06266 { 06267 int call_num = i->callno; 06268 /* It is assumed that the callno has already been locked */ 06269 iax2_predestroy(i->callno); 06270 if (!iaxs[call_num]) 06271 return -1; 06272 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 06273 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6275 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
06276 { 06277 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 06278 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 6251 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().
06252 { 06253 int res; 06254 ast_mutex_lock(&iaxsl[callno]); 06255 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 06256 ast_mutex_unlock(&iaxsl[callno]); 06257 return res; 06258 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 6280 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
06281 { 06282 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 06283 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1173 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01174 { 01175 #ifdef SCHED_MULTITHREADED 01176 if (schedule_action(__send_lagrq, data)) 01177 #endif 01178 __send_lagrq(data); 01179 01180 return 0; 01181 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2903 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, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02904 { 02905 int res; 02906 int callno = f->callno; 02907 02908 /* Don't send if there was an error, but return error instead */ 02909 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02910 return -1; 02911 02912 /* Called with iaxsl held */ 02913 if (option_debug > 2 && iaxdebug) 02914 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)); 02915 if (f->transfer) { 02916 if (iaxdebug) 02917 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02918 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02919 sizeof(iaxs[callno]->transfer)); 02920 } else { 02921 if (iaxdebug) 02922 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02923 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02924 sizeof(iaxs[callno]->addr)); 02925 } 02926 if (res < 0) { 02927 if (option_debug && iaxdebug) 02928 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02929 handle_error(); 02930 } else 02931 res = 0; 02932 return res; 02933 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1128 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01129 { 01130 #ifdef SCHED_MULTITHREADED 01131 if (schedule_action(__send_ping, data)) 01132 #endif 01133 __send_ping(data); 01134 01135 return 0; 01136 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 7760 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().
07761 { 07762 int res = 0; 07763 struct iax_frame *fr; 07764 struct ast_iax2_meta_hdr *meta; 07765 struct ast_iax2_meta_trunk_hdr *mth; 07766 int calls = 0; 07767 07768 /* Point to frame */ 07769 fr = (struct iax_frame *)tpeer->trunkdata; 07770 /* Point to meta data */ 07771 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 07772 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 07773 if (tpeer->trunkdatalen) { 07774 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 07775 meta->zeros = 0; 07776 meta->metacmd = IAX_META_TRUNK; 07777 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 07778 meta->cmddata = IAX_META_TRUNK_MINI; 07779 else 07780 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 07781 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 07782 /* And the rest of the ast_iax2 header */ 07783 fr->direction = DIRECTION_OUTGRESS; 07784 fr->retrans = -1; 07785 fr->transfer = 0; 07786 /* Any appropriate call will do */ 07787 fr->data = fr->afdata; 07788 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 07789 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 07790 calls = tpeer->calls; 07791 #if 0 07792 if (option_debug) 07793 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)); 07794 #endif 07795 /* Reset transmit trunk side data */ 07796 tpeer->trunkdatalen = 0; 07797 tpeer->calls = 0; 07798 } 07799 if (res < 0) 07800 return res; 07801 return calls; 07802 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 11234 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_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_MAXCALLNO_LIMIT, DEFAULT_MAXCALLNO_LIMIT_NONVAL, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), global_maxcallno, global_maxcallno_nonval, 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_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(), portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
11235 { 11236 struct ast_config *cfg, *ucfg; 11237 int capability=iax2_capability; 11238 struct ast_variable *v; 11239 char *cat; 11240 const char *utype; 11241 const char *tosval; 11242 int format; 11243 int portno = IAX_DEFAULT_PORTNO; 11244 int x; 11245 struct iax2_user *user; 11246 struct iax2_peer *peer; 11247 struct ast_netsock *ns; 11248 #if 0 11249 static unsigned short int last_port=0; 11250 #endif 11251 11252 cfg = ast_config_load(config_file); 11253 11254 if (!cfg) { 11255 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 11256 return -1; 11257 } 11258 11259 if (reload) { 11260 set_config_destroy(); 11261 } 11262 11263 /* Reset global codec prefs */ 11264 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 11265 11266 /* Reset Global Flags */ 11267 memset(&globalflags, 0, sizeof(globalflags)); 11268 ast_set_flag(&globalflags, IAX_RTUPDATE); 11269 11270 #ifdef SO_NO_CHECK 11271 nochecksums = 0; 11272 #endif 11273 11274 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11275 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 11276 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 11277 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 11278 11279 maxauthreq = 3; 11280 11281 v = ast_variable_browse(cfg, "general"); 11282 11283 /* Seed initial tos value */ 11284 tosval = ast_variable_retrieve(cfg, "general", "tos"); 11285 if (tosval) { 11286 if (ast_str2tos(tosval, &tos)) 11287 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 11288 } 11289 while(v) { 11290 if (!strcasecmp(v->name, "bindport")){ 11291 if (reload) 11292 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 11293 else 11294 portno = atoi(v->value); 11295 } else if (!strcasecmp(v->name, "pingtime")) 11296 ping_time = atoi(v->value); 11297 else if (!strcasecmp(v->name, "iaxthreadcount")) { 11298 if (reload) { 11299 if (atoi(v->value) != iaxthreadcount) 11300 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 11301 } else { 11302 iaxthreadcount = atoi(v->value); 11303 if (iaxthreadcount < 1) { 11304 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 11305 iaxthreadcount = 1; 11306 } else if (iaxthreadcount > 256) { 11307 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 11308 iaxthreadcount = 256; 11309 } 11310 } 11311 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 11312 if (reload) { 11313 AST_LIST_LOCK(&dynamic_list); 11314 iaxmaxthreadcount = atoi(v->value); 11315 AST_LIST_UNLOCK(&dynamic_list); 11316 } else { 11317 iaxmaxthreadcount = atoi(v->value); 11318 if (iaxmaxthreadcount < 0) { 11319 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 11320 iaxmaxthreadcount = 0; 11321 } else if (iaxmaxthreadcount > 256) { 11322 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 11323 iaxmaxthreadcount = 256; 11324 } 11325 } 11326 } else if (!strcasecmp(v->name, "nochecksums")) { 11327 #ifdef SO_NO_CHECK 11328 if (ast_true(v->value)) 11329 nochecksums = 1; 11330 else 11331 nochecksums = 0; 11332 #else 11333 if (ast_true(v->value)) 11334 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 11335 #endif 11336 } 11337 else if (!strcasecmp(v->name, "maxjitterbuffer")) 11338 maxjitterbuffer = atoi(v->value); 11339 else if (!strcasecmp(v->name, "resyncthreshold")) 11340 resyncthreshold = atoi(v->value); 11341 else if (!strcasecmp(v->name, "maxjitterinterps")) 11342 maxjitterinterps = atoi(v->value); 11343 else if (!strcasecmp(v->name, "lagrqtime")) 11344 lagrq_time = atoi(v->value); 11345 else if (!strcasecmp(v->name, "maxregexpire")) 11346 max_reg_expire = atoi(v->value); 11347 else if (!strcasecmp(v->name, "minregexpire")) 11348 min_reg_expire = atoi(v->value); 11349 else if (!strcasecmp(v->name, "bindaddr")) { 11350 if (reload) { 11351 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 11352 } else { 11353 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 11354 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 11355 } else { 11356 if (option_verbose > 1) { 11357 if (strchr(v->value, ':')) 11358 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 11359 else 11360 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 11361 } 11362 if (defaultsockfd < 0) 11363 defaultsockfd = ast_netsock_sockfd(ns); 11364 ast_netsock_unref(ns); 11365 } 11366 } 11367 } else if (!strcasecmp(v->name, "authdebug")) 11368 authdebug = ast_true(v->value); 11369 else if (!strcasecmp(v->name, "encryption")) 11370 iax2_encryption = get_encrypt_methods(v->value); 11371 else if (!strcasecmp(v->name, "notransfer")) { 11372 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 11373 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11374 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 11375 } else if (!strcasecmp(v->name, "transfer")) { 11376 if (!strcasecmp(v->value, "mediaonly")) { 11377 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11378 } else if (ast_true(v->value)) { 11379 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11380 } else 11381 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11382 } else if (!strcasecmp(v->name, "codecpriority")) { 11383 if(!strcasecmp(v->value, "caller")) 11384 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 11385 else if(!strcasecmp(v->value, "disabled")) 11386 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11387 else if(!strcasecmp(v->value, "reqonly")) { 11388 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 11389 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 11390 } 11391 } else if (!strcasecmp(v->name, "jitterbuffer")) 11392 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 11393 else if (!strcasecmp(v->name, "forcejitterbuffer")) 11394 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 11395 else if (!strcasecmp(v->name, "delayreject")) 11396 delayreject = ast_true(v->value); 11397 else if (!strcasecmp(v->name, "allowfwdownload")) 11398 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 11399 else if (!strcasecmp(v->name, "rtcachefriends")) 11400 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 11401 else if (!strcasecmp(v->name, "rtignoreregexpire")) 11402 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 11403 else if (!strcasecmp(v->name, "rtupdate")) 11404 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 11405 else if (!strcasecmp(v->name, "trunktimestamps")) 11406 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 11407 else if (!strcasecmp(v->name, "rtautoclear")) { 11408 int i = atoi(v->value); 11409 if(i > 0) 11410 global_rtautoclear = i; 11411 else 11412 i = 0; 11413 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 11414 } else if (!strcasecmp(v->name, "trunkfreq")) { 11415 trunkfreq = atoi(v->value); 11416 if (trunkfreq < 10) 11417 trunkfreq = 10; 11418 } else if (!strcasecmp(v->name, "autokill")) { 11419 if (sscanf(v->value, "%30d", &x) == 1) { 11420 if (x >= 0) 11421 autokill = x; 11422 else 11423 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 11424 } else if (ast_true(v->value)) { 11425 autokill = DEFAULT_MAXMS; 11426 } else { 11427 autokill = 0; 11428 } 11429 } else if (!strcasecmp(v->name, "bandwidth")) { 11430 if (!strcasecmp(v->value, "low")) { 11431 capability = IAX_CAPABILITY_LOWBANDWIDTH; 11432 } else if (!strcasecmp(v->value, "medium")) { 11433 capability = IAX_CAPABILITY_MEDBANDWIDTH; 11434 } else if (!strcasecmp(v->value, "high")) { 11435 capability = IAX_CAPABILITY_FULLBANDWIDTH; 11436 } else 11437 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 11438 } else if (!strcasecmp(v->name, "allow")) { 11439 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 11440 } else if (!strcasecmp(v->name, "disallow")) { 11441 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 11442 } else if (!strcasecmp(v->name, "register")) { 11443 iax2_register(v->value, v->lineno); 11444 } else if (!strcasecmp(v->name, "iaxcompat")) { 11445 iaxcompat = ast_true(v->value); 11446 } else if (!strcasecmp(v->name, "regcontext")) { 11447 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 11448 /* Create context if it doesn't exist already */ 11449 if (!ast_context_find(regcontext)) 11450 ast_context_create(NULL, regcontext, "IAX2"); 11451 } else if (!strcasecmp(v->name, "tos")) { 11452 if (ast_str2tos(v->value, &tos)) 11453 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 11454 } else if (!strcasecmp(v->name, "accountcode")) { 11455 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 11456 } else if (!strcasecmp(v->name, "mohinterpret")) { 11457 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 11458 } else if (!strcasecmp(v->name, "mohsuggest")) { 11459 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 11460 } else if (!strcasecmp(v->name, "amaflags")) { 11461 format = ast_cdr_amaflags2int(v->value); 11462 if (format < 0) { 11463 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11464 } else { 11465 amaflags = format; 11466 } 11467 } else if (!strcasecmp(v->name, "language")) { 11468 ast_copy_string(language, v->value, sizeof(language)); 11469 } else if (!strcasecmp(v->name, "maxauthreq")) { 11470 maxauthreq = atoi(v->value); 11471 if (maxauthreq < 0) 11472 maxauthreq = 0; 11473 } else if (!strcasecmp(v->name, "adsi")) { 11474 adsi = ast_true(v->value); 11475 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11476 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 11477 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 11478 } 11479 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 11480 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 11481 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); 11482 } 11483 } else if(!strcasecmp(v->name, "calltokenoptional")) { 11484 if (add_calltoken_ignore(v->value)) { 11485 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 11486 } 11487 }/*else if (strcasecmp(v->name,"type")) */ 11488 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11489 v = v->next; 11490 } 11491 11492 if (defaultsockfd < 0) { 11493 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 11494 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 11495 } else { 11496 if (option_verbose > 1) 11497 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 11498 defaultsockfd = ast_netsock_sockfd(ns); 11499 ast_netsock_unref(ns); 11500 } 11501 } 11502 if (reload) { 11503 ast_netsock_release(outsock); 11504 outsock = ast_netsock_list_alloc(); 11505 if (!outsock) { 11506 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11507 return -1; 11508 } 11509 ast_netsock_init(outsock); 11510 } 11511 11512 if (min_reg_expire > max_reg_expire) { 11513 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 11514 min_reg_expire, max_reg_expire, max_reg_expire); 11515 min_reg_expire = max_reg_expire; 11516 } 11517 iax2_capability = capability; 11518 11519 ucfg = ast_config_load("users.conf"); 11520 if (ucfg) { 11521 struct ast_variable *gen; 11522 int genhasiax; 11523 int genregisteriax; 11524 const char *hasiax, *registeriax; 11525 11526 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 11527 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 11528 gen = ast_variable_browse(ucfg, "general"); 11529 cat = ast_category_browse(ucfg, NULL); 11530 while (cat) { 11531 if (strcasecmp(cat, "general")) { 11532 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 11533 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 11534 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 11535 /* Start with general parameters, then specific parameters, user and peer */ 11536 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 11537 if (user) { 11538 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11539 user = user_unref(user); 11540 } 11541 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 11542 if (peer) { 11543 if (ast_test_flag(peer, IAX_DYNAMIC)) 11544 reg_source_db(peer); 11545 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11546 peer = peer_unref(peer); 11547 } 11548 } 11549 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 11550 char tmp[256]; 11551 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 11552 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 11553 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 11554 if (!host) 11555 host = ast_variable_retrieve(ucfg, "general", "host"); 11556 if (!username) 11557 username = ast_variable_retrieve(ucfg, "general", "username"); 11558 if (!secret) 11559 secret = ast_variable_retrieve(ucfg, "general", "secret"); 11560 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 11561 if (!ast_strlen_zero(secret)) 11562 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 11563 else 11564 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 11565 iax2_register(tmp, 0); 11566 } 11567 } 11568 } 11569 cat = ast_category_browse(ucfg, cat); 11570 } 11571 ast_config_destroy(ucfg); 11572 } 11573 11574 cat = ast_category_browse(cfg, NULL); 11575 while(cat) { 11576 if (strcasecmp(cat, "general")) { 11577 utype = ast_variable_retrieve(cfg, cat, "type"); 11578 if (!strcasecmp(cat, "callnumberlimits")) { 11579 build_callno_limits(ast_variable_browse(cfg, cat)); 11580 } else if (utype) { 11581 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 11582 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 11583 if (user) { 11584 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11585 user = user_unref(user); 11586 } 11587 } 11588 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 11589 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 11590 if (peer) { 11591 if (ast_test_flag(peer, IAX_DYNAMIC)) 11592 reg_source_db(peer); 11593 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 11594 peer = peer_unref(peer); 11595 } 11596 } else if (strcasecmp(utype, "user")) { 11597 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 11598 } 11599 } else 11600 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 11601 } 11602 cat = ast_category_browse(cfg, cat); 11603 } 11604 ast_config_destroy(cfg); 11605 set_timing(); 11606 return 1; 11607 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 11216 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().
11217 { 11218 strcpy(accountcode, ""); 11219 strcpy(language, ""); 11220 strcpy(mohinterpret, "default"); 11221 strcpy(mohsuggest, ""); 11222 amaflags = 0; 11223 delayreject = 0; 11224 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 11225 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 11226 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 11227 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 11228 delete_users(); 11229 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 11230 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 11231 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1817 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), callno_limits, global_maxcallno, addr_range::limit, peercnt::limit, LOG_NOTICE, option_debug, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
01818 { 01819 uint16_t limit = global_maxcallno; 01820 struct addr_range *addr_range; 01821 struct sockaddr_in sin = { 01822 .sin_addr.s_addr = peercnt->addr, 01823 }; 01824 01825 01826 if (peercnt->reg && peercnt->limit) { 01827 return; /* this peercnt has a custom limit set by a registration */ 01828 } 01829 01830 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 01831 limit = addr_range->limit; 01832 if (option_debug) { 01833 ast_log(LOG_NOTICE, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 01834 } 01835 ao2_ref(addr_range, -1); 01836 } 01837 01838 peercnt->limit = limit; 01839 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1845 of file chan_iax2.c.
References ast_log(), LOG_NOTICE, option_debug, and set_peercnt_limit().
Referenced by reload_config().
01846 { 01847 struct peercnt *peercnt = obj; 01848 01849 set_peercnt_limit(peercnt); 01850 if (option_debug) { 01851 ast_log(LOG_NOTICE, "Reset limits for peercnts table\n"); 01852 } 01853 return 0; 01854 }
static void set_timing | ( | void | ) | [static] |
Definition at line 11201 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
11202 { 11203 #ifdef HAVE_DAHDI 11204 int bs = trunkfreq * 8; 11205 if (timingfd > -1) { 11206 if ( 11207 #ifdef DAHDI_TIMERACK 11208 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 11209 #endif 11210 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 11211 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 11212 } 11213 #endif 11214 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 850 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().
00851 { 00852 ast_mutex_lock(lock); 00853 ast_cond_signal(cond); 00854 ast_mutex_unlock(lock); 00855 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 8234 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_tvzero(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), dpcache_lock, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), chan_iax2_pvt::first_iax_message, fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, iax_frame::list, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, ast_iax2_queue::queue, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), 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().
08235 { 08236 struct sockaddr_in sin; 08237 int res; 08238 int updatehistory=1; 08239 int new = NEW_PREVENT; 08240 void *ptr; 08241 int dcallno = 0; 08242 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 08243 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 08244 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 08245 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 08246 struct ast_iax2_meta_trunk_hdr *mth; 08247 struct ast_iax2_meta_trunk_entry *mte; 08248 struct ast_iax2_meta_trunk_mini *mtm; 08249 struct iax_frame *fr; 08250 struct iax_frame *cur; 08251 struct ast_frame f = { 0, }; 08252 struct ast_channel *c; 08253 struct iax2_dpcache *dp; 08254 struct iax2_peer *peer; 08255 struct iax2_trunk_peer *tpeer; 08256 struct timeval rxtrunktime; 08257 struct iax_ies ies; 08258 struct iax_ie_data ied0, ied1; 08259 int format; 08260 int fd; 08261 int exists; 08262 int minivid = 0; 08263 unsigned int ts; 08264 char empty[32]=""; /* Safety measure */ 08265 struct iax_frame *duped_fr; 08266 char host_pref_buf[128]; 08267 char caller_pref_buf[128]; 08268 struct ast_codec_pref pref; 08269 char *using_prefs = "mine"; 08270 08271 /* allocate an iax_frame with 4096 bytes of data buffer */ 08272 fr = alloca(sizeof(*fr) + 4096); 08273 memset(fr, 0, sizeof(*fr)); 08274 fr->afdatalen = 4096; /* From alloca() above */ 08275 08276 /* Copy frequently used parameters to the stack */ 08277 res = thread->buf_len; 08278 fd = thread->iofd; 08279 memcpy(&sin, &thread->iosin, sizeof(sin)); 08280 08281 if (res < sizeof(*mh)) { 08282 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 08283 return 1; 08284 } 08285 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 08286 if (res < sizeof(*vh)) { 08287 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)); 08288 return 1; 08289 } 08290 08291 /* This is a video frame, get call number */ 08292 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 08293 minivid = 1; 08294 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 08295 unsigned char metatype; 08296 08297 if (res < sizeof(*meta)) { 08298 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)); 08299 return 1; 08300 } 08301 08302 /* This is a meta header */ 08303 switch(meta->metacmd) { 08304 case IAX_META_TRUNK: 08305 if (res < (sizeof(*meta) + sizeof(*mth))) { 08306 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 08307 sizeof(*meta) + sizeof(*mth)); 08308 return 1; 08309 } 08310 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 08311 ts = ntohl(mth->ts); 08312 metatype = meta->cmddata; 08313 res -= (sizeof(*meta) + sizeof(*mth)); 08314 ptr = mth->data; 08315 tpeer = find_tpeer(&sin, fd); 08316 if (!tpeer) { 08317 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)); 08318 return 1; 08319 } 08320 tpeer->trunkact = ast_tvnow(); 08321 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 08322 tpeer->rxtrunktime = tpeer->trunkact; 08323 rxtrunktime = tpeer->rxtrunktime; 08324 ast_mutex_unlock(&tpeer->lock); 08325 while(res >= sizeof(*mte)) { 08326 /* Process channels */ 08327 unsigned short callno, trunked_ts, len; 08328 08329 if (metatype == IAX_META_TRUNK_MINI) { 08330 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 08331 ptr += sizeof(*mtm); 08332 res -= sizeof(*mtm); 08333 len = ntohs(mtm->len); 08334 callno = ntohs(mtm->mini.callno); 08335 trunked_ts = ntohs(mtm->mini.ts); 08336 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 08337 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 08338 ptr += sizeof(*mte); 08339 res -= sizeof(*mte); 08340 len = ntohs(mte->len); 08341 callno = ntohs(mte->callno); 08342 trunked_ts = 0; 08343 } else { 08344 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 08345 break; 08346 } 08347 /* Stop if we don't have enough data */ 08348 if (len > res) 08349 break; 08350 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 08351 if (fr->callno) { 08352 /* If it's a valid call, deliver the contents. If not, we 08353 drop it, since we don't have a scallno to use for an INVAL */ 08354 /* Process as a mini frame */ 08355 memset(&f, 0, sizeof(f)); 08356 f.frametype = AST_FRAME_VOICE; 08357 if (iaxs[fr->callno]) { 08358 if (iaxs[fr->callno]->voiceformat > 0) { 08359 f.subclass = iaxs[fr->callno]->voiceformat; 08360 f.datalen = len; 08361 if (f.datalen >= 0) { 08362 if (f.datalen) 08363 f.data = ptr; 08364 if(trunked_ts) { 08365 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 08366 } else 08367 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 08368 /* Don't pass any packets until we're started */ 08369 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08370 /* Common things */ 08371 f.src = "IAX2"; 08372 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 08373 f.samples = ast_codec_get_samples(&f); 08374 iax_frame_wrap(fr, &f); 08375 duped_fr = iaxfrdup2(fr); 08376 if (duped_fr) { 08377 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 08378 } 08379 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 08380 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08381 iaxs[fr->callno]->last = fr->ts; 08382 #if 1 08383 if (option_debug && iaxdebug) 08384 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08385 #endif 08386 } 08387 } 08388 } else { 08389 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08390 } 08391 } else { 08392 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 08393 iax2_vnak(fr->callno); 08394 } 08395 } 08396 ast_mutex_unlock(&iaxsl[fr->callno]); 08397 } 08398 ptr += len; 08399 res -= len; 08400 } 08401 08402 } 08403 return 1; 08404 } 08405 08406 #ifdef DEBUG_SUPPORT 08407 if (iaxdebug && (res >= sizeof(*fh))) 08408 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 08409 #endif 08410 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08411 if (res < sizeof(*fh)) { 08412 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)); 08413 return 1; 08414 } 08415 08416 /* Get the destination call number */ 08417 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 08418 /* Retrieve the type and subclass */ 08419 f.frametype = fh->type; 08420 if (f.frametype == AST_FRAME_VIDEO) { 08421 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 08422 } else { 08423 f.subclass = uncompress_subclass(fh->csub); 08424 } 08425 08426 /* Deal with POKE/PONG without allocating a callno */ 08427 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 08428 /* Reply back with a PONG, but don't care about the result. */ 08429 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08430 return 1; 08431 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 08432 /* Ignore */ 08433 return 1; 08434 } 08435 08436 f.datalen = res - sizeof(*fh); 08437 if (f.datalen) { 08438 if (f.frametype == AST_FRAME_IAX) { 08439 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 08440 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 08441 ast_mutex_unlock(&iaxsl[fr->callno]); 08442 return 1; 08443 } 08444 f.data = NULL; 08445 f.datalen = 0; 08446 } else { 08447 f.data = thread->buf + sizeof(*fh); 08448 memset(&ies, 0, sizeof(ies)); 08449 } 08450 } else { 08451 if (f.frametype == AST_FRAME_IAX) 08452 f.data = NULL; 08453 else 08454 f.data = empty; 08455 memset(&ies, 0, sizeof(ies)); 08456 } 08457 08458 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 08459 /* only set NEW_ALLOW if calltoken checks out */ 08460 if (handle_call_token(fh, &ies, &sin, fd)) { 08461 return 1; 08462 } 08463 08464 if (ies.calltoken && ies.calltokendata) { 08465 /* if we've gotten this far, and the calltoken ie data exists, 08466 * then calltoken validation _MUST_ have taken place. If calltoken 08467 * data is provided, it is always validated reguardless of any 08468 * calltokenoptional or requirecalltoken options */ 08469 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 08470 } else { 08471 new = NEW_ALLOW; 08472 } 08473 } 08474 } else { 08475 /* Don't know anything about it yet */ 08476 f.frametype = AST_FRAME_NULL; 08477 f.subclass = 0; 08478 } 08479 08480 if (!fr->callno) { 08481 int check_dcallno = 0; 08482 08483 /* 08484 * We enforce accurate destination call numbers for all full frames except 08485 * LAGRQ and PING commands. This is because older versions of Asterisk 08486 * schedule these commands to get sent very quickly, and they will sometimes 08487 * be sent before they receive the first frame from the other side. When 08488 * that happens, it doesn't contain the destination call number. However, 08489 * not checking it for these frames is safe. 08490 * 08491 * Discussed in the following thread: 08492 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 08493 */ 08494 08495 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08496 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 08497 } 08498 08499 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 08500 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 08501 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08502 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 08503 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 08504 } 08505 return 1; 08506 } 08507 } 08508 08509 if (fr->callno > 0) 08510 ast_mutex_lock(&iaxsl[fr->callno]); 08511 08512 if (!fr->callno || !iaxs[fr->callno]) { 08513 /* A call arrived for a nonexistent destination. Unless it's an "inval" 08514 frame, reply with an inval */ 08515 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08516 /* We can only raw hangup control frames */ 08517 if (((f.subclass != IAX_COMMAND_INVAL) && 08518 (f.subclass != IAX_COMMAND_TXCNT) && 08519 (f.subclass != IAX_COMMAND_TXACC) && 08520 (f.subclass != IAX_COMMAND_FWDOWNL))|| 08521 (f.frametype != AST_FRAME_IAX)) 08522 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 08523 fd); 08524 } 08525 if (fr->callno > 0) 08526 ast_mutex_unlock(&iaxsl[fr->callno]); 08527 return 1; 08528 } 08529 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 08530 if (decrypt_frame(fr->callno, fh, &f, &res)) { 08531 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 08532 ast_mutex_unlock(&iaxsl[fr->callno]); 08533 return 1; 08534 } 08535 #ifdef DEBUG_SUPPORT 08536 else if (iaxdebug) 08537 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 08538 #endif 08539 } 08540 08541 /* count this frame */ 08542 iaxs[fr->callno]->frames_received++; 08543 08544 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 08545 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 08546 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 08547 unsigned short new_peercallno; 08548 08549 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 08550 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 08551 if (iaxs[fr->callno]->peercallno) { 08552 remove_by_peercallno(iaxs[fr->callno]); 08553 } 08554 iaxs[fr->callno]->peercallno = new_peercallno; 08555 store_by_peercallno(iaxs[fr->callno]); 08556 } 08557 } 08558 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 08559 if (option_debug && iaxdebug) 08560 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 08561 /* Check if it's out of order (and not an ACK or INVAL) */ 08562 fr->oseqno = fh->oseqno; 08563 fr->iseqno = fh->iseqno; 08564 fr->ts = ntohl(fh->ts); 08565 #ifdef IAXTESTS 08566 if (test_resync) { 08567 if (option_debug) 08568 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 08569 fr->ts += test_resync; 08570 } 08571 #endif /* IAXTESTS */ 08572 #if 0 08573 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 08574 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 08575 (f.subclass == IAX_COMMAND_NEW || 08576 f.subclass == IAX_COMMAND_AUTHREQ || 08577 f.subclass == IAX_COMMAND_ACCEPT || 08578 f.subclass == IAX_COMMAND_REJECT)) ) ) 08579 #endif 08580 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 08581 updatehistory = 0; 08582 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 08583 (iaxs[fr->callno]->iseqno || 08584 ((f.subclass != IAX_COMMAND_TXCNT) && 08585 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08586 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08587 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08588 (f.subclass != IAX_COMMAND_TXACC)) || 08589 (f.frametype != AST_FRAME_IAX))) { 08590 if ( 08591 ((f.subclass != IAX_COMMAND_ACK) && 08592 (f.subclass != IAX_COMMAND_INVAL) && 08593 (f.subclass != IAX_COMMAND_TXCNT) && 08594 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 08595 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 08596 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 08597 (f.subclass != IAX_COMMAND_TXACC) && 08598 (f.subclass != IAX_COMMAND_VNAK)) || 08599 (f.frametype != AST_FRAME_IAX)) { 08600 /* If it's not an ACK packet, it's out of order. */ 08601 if (option_debug) 08602 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 08603 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 08604 /* Check to see if we need to request retransmission, 08605 * and take sequence number wraparound into account */ 08606 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 08607 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 08608 if ((f.frametype != AST_FRAME_IAX) || 08609 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 08610 if (option_debug) 08611 ast_log(LOG_DEBUG, "Acking anyway\n"); 08612 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 08613 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 08614 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08615 } 08616 } else { 08617 /* Send a VNAK requesting retransmission */ 08618 iax2_vnak(fr->callno); 08619 } 08620 ast_mutex_unlock(&iaxsl[fr->callno]); 08621 return 1; 08622 } 08623 } else { 08624 /* Increment unless it's an ACK or VNAK */ 08625 if (((f.subclass != IAX_COMMAND_ACK) && 08626 (f.subclass != IAX_COMMAND_INVAL) && 08627 (f.subclass != IAX_COMMAND_TXCNT) && 08628 (f.subclass != IAX_COMMAND_TXACC) && 08629 (f.subclass != IAX_COMMAND_VNAK)) || 08630 (f.frametype != AST_FRAME_IAX)) 08631 iaxs[fr->callno]->iseqno++; 08632 } 08633 /* Ensure text frames are NULL-terminated */ 08634 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 08635 if (res < thread->buf_size) 08636 thread->buf[res++] = '\0'; 08637 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 08638 thread->buf[res - 1] = '\0'; 08639 } 08640 08641 /* Handle implicit ACKing unless this is an INVAL, and only if this is 08642 from the real peer, not the transfer peer */ 08643 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08644 ((f.subclass != IAX_COMMAND_INVAL) || 08645 (f.frametype != AST_FRAME_IAX))) { 08646 unsigned char x; 08647 int call_to_destroy; 08648 /* XXX This code is not very efficient. Surely there is a better way which still 08649 properly handles boundary conditions? XXX */ 08650 /* First we have to qualify that the ACKed value is within our window */ 08651 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 08652 if (fr->iseqno == x) 08653 break; 08654 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 08655 /* The acknowledgement is within our window. Time to acknowledge everything 08656 that it says to */ 08657 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 08658 /* Ack the packet with the given timestamp */ 08659 if (option_debug && iaxdebug) 08660 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 08661 call_to_destroy = 0; 08662 AST_LIST_LOCK(&iaxq.queue); 08663 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08664 /* If it's our call, and our timestamp, mark -1 retries */ 08665 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 08666 cur->retries = -1; 08667 /* Destroy call if this is the end */ 08668 if (cur->final) 08669 call_to_destroy = fr->callno; 08670 } 08671 } 08672 AST_LIST_UNLOCK(&iaxq.queue); 08673 if (call_to_destroy) { 08674 if (iaxdebug && option_debug) 08675 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 08676 ast_mutex_lock(&iaxsl[call_to_destroy]); 08677 iax2_destroy(call_to_destroy); 08678 ast_mutex_unlock(&iaxsl[call_to_destroy]); 08679 } 08680 } 08681 /* Note how much we've received acknowledgement for */ 08682 if (iaxs[fr->callno]) 08683 iaxs[fr->callno]->rseqno = fr->iseqno; 08684 else { 08685 /* Stop processing now */ 08686 ast_mutex_unlock(&iaxsl[fr->callno]); 08687 return 1; 08688 } 08689 } else if (option_debug) 08690 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 08691 } 08692 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 08693 ((f.frametype != AST_FRAME_IAX) || 08694 ((f.subclass != IAX_COMMAND_TXACC) && 08695 (f.subclass != IAX_COMMAND_TXCNT)))) { 08696 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 08697 ast_mutex_unlock(&iaxsl[fr->callno]); 08698 return 1; 08699 } 08700 08701 /* when we receive the first full frame for a new incoming channel, 08702 it is safe to start the PBX on the channel because we have now 08703 completed a 3-way handshake with the peer */ 08704 if ((f.frametype == AST_FRAME_VOICE) || 08705 (f.frametype == AST_FRAME_VIDEO) || 08706 (f.frametype == AST_FRAME_IAX)) { 08707 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 08708 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 08709 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 08710 ast_mutex_unlock(&iaxsl[fr->callno]); 08711 return 1; 08712 } 08713 } 08714 } 08715 08716 if (f.frametype == AST_FRAME_VOICE) { 08717 if (f.subclass != iaxs[fr->callno]->voiceformat) { 08718 iaxs[fr->callno]->voiceformat = f.subclass; 08719 if (option_debug) 08720 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 08721 if (iaxs[fr->callno]->owner) { 08722 int orignative; 08723 retryowner: 08724 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 08725 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 08726 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 08727 } 08728 if (iaxs[fr->callno]) { 08729 if (iaxs[fr->callno]->owner) { 08730 orignative = iaxs[fr->callno]->owner->nativeformats; 08731 iaxs[fr->callno]->owner->nativeformats = f.subclass; 08732 if (iaxs[fr->callno]->owner->readformat) 08733 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08734 iaxs[fr->callno]->owner->nativeformats = orignative; 08735 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08736 } 08737 } else { 08738 if (option_debug) 08739 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 08740 ast_mutex_unlock(&iaxsl[fr->callno]); 08741 return 1; 08742 } 08743 } 08744 } 08745 } 08746 if (f.frametype == AST_FRAME_VIDEO) { 08747 if (f.subclass != iaxs[fr->callno]->videoformat) { 08748 if (option_debug) 08749 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 08750 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 08751 } 08752 } 08753 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 08754 if (f.subclass == AST_CONTROL_BUSY) { 08755 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 08756 } else if (f.subclass == AST_CONTROL_CONGESTION) { 08757 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 08758 } 08759 } 08760 if (f.frametype == AST_FRAME_IAX) { 08761 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 08762 /* Handle the IAX pseudo frame itself */ 08763 if (option_debug && iaxdebug) { 08764 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 08765 } 08766 08767 /* Update last ts unless the frame's timestamp originated with us. */ 08768 if (iaxs[fr->callno]->last < fr->ts && 08769 f.subclass != IAX_COMMAND_ACK && 08770 f.subclass != IAX_COMMAND_PONG && 08771 f.subclass != IAX_COMMAND_LAGRP) { 08772 iaxs[fr->callno]->last = fr->ts; 08773 if (option_debug && iaxdebug) { 08774 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08775 } 08776 } 08777 iaxs[fr->callno]->last_iax_message = f.subclass; 08778 if (!iaxs[fr->callno]->first_iax_message) { 08779 iaxs[fr->callno]->first_iax_message = f.subclass; 08780 } 08781 switch(f.subclass) { 08782 case IAX_COMMAND_ACK: 08783 /* Do nothing */ 08784 break; 08785 case IAX_COMMAND_QUELCH: 08786 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08787 /* Generate Manager Hold event, if necessary*/ 08788 if (iaxs[fr->callno]->owner) { 08789 manager_event(EVENT_FLAG_CALL, "Hold", 08790 "Channel: %s\r\n" 08791 "Uniqueid: %s\r\n", 08792 iaxs[fr->callno]->owner->name, 08793 iaxs[fr->callno]->owner->uniqueid); 08794 } 08795 08796 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 08797 if (ies.musiconhold) { 08798 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 08799 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 08800 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 08801 S_OR(mohsuggest, NULL), 08802 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 08803 if (!iaxs[fr->callno]) { 08804 ast_mutex_unlock(&iaxsl[fr->callno]); 08805 return 1; 08806 } 08807 } 08808 } 08809 } 08810 break; 08811 case IAX_COMMAND_UNQUELCH: 08812 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08813 /* Generate Manager Unhold event, if necessary*/ 08814 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 08815 manager_event(EVENT_FLAG_CALL, "Unhold", 08816 "Channel: %s\r\n" 08817 "Uniqueid: %s\r\n", 08818 iaxs[fr->callno]->owner->name, 08819 iaxs[fr->callno]->owner->uniqueid); 08820 } 08821 08822 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 08823 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 08824 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 08825 if (!iaxs[fr->callno]) { 08826 ast_mutex_unlock(&iaxsl[fr->callno]); 08827 return 1; 08828 } 08829 } 08830 } 08831 break; 08832 case IAX_COMMAND_TXACC: 08833 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 08834 /* Ack the packet with the given timestamp */ 08835 AST_LIST_LOCK(&iaxq.queue); 08836 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08837 /* Cancel any outstanding txcnt's */ 08838 if ((fr->callno == cur->callno) && (cur->transfer)) 08839 cur->retries = -1; 08840 } 08841 AST_LIST_UNLOCK(&iaxq.queue); 08842 memset(&ied1, 0, sizeof(ied1)); 08843 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 08844 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 08845 iaxs[fr->callno]->transferring = TRANSFER_READY; 08846 } 08847 break; 08848 case IAX_COMMAND_NEW: 08849 /* Ignore if it's already up */ 08850 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 08851 break; 08852 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08853 ast_mutex_unlock(&iaxsl[fr->callno]); 08854 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08855 ast_mutex_lock(&iaxsl[fr->callno]); 08856 if (!iaxs[fr->callno]) { 08857 ast_mutex_unlock(&iaxsl[fr->callno]); 08858 return 1; 08859 } 08860 } 08861 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 08862 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 08863 int new_callno; 08864 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 08865 fr->callno = new_callno; 08866 } 08867 /* For security, always ack immediately */ 08868 if (delayreject) 08869 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08870 if (check_access(fr->callno, &sin, &ies)) { 08871 /* They're not allowed on */ 08872 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08873 if (authdebug) 08874 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); 08875 break; 08876 } 08877 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08878 const char *context, *exten, *cid_num; 08879 08880 context = ast_strdupa(iaxs[fr->callno]->context); 08881 exten = ast_strdupa(iaxs[fr->callno]->exten); 08882 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 08883 08884 /* This might re-enter the IAX code and need the lock */ 08885 ast_mutex_unlock(&iaxsl[fr->callno]); 08886 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 08887 ast_mutex_lock(&iaxsl[fr->callno]); 08888 08889 if (!iaxs[fr->callno]) { 08890 ast_mutex_unlock(&iaxsl[fr->callno]); 08891 return 1; 08892 } 08893 } else 08894 exists = 0; 08895 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 08896 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08897 memset(&ied0, 0, sizeof(ied0)); 08898 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08899 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08900 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08901 if (!iaxs[fr->callno]) { 08902 ast_mutex_unlock(&iaxsl[fr->callno]); 08903 return 1; 08904 } 08905 if (authdebug) 08906 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); 08907 } else { 08908 /* Select an appropriate format */ 08909 08910 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08911 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08912 using_prefs = "reqonly"; 08913 } else { 08914 using_prefs = "disabled"; 08915 } 08916 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08917 memset(&pref, 0, sizeof(pref)); 08918 strcpy(caller_pref_buf, "disabled"); 08919 strcpy(host_pref_buf, "disabled"); 08920 } else { 08921 using_prefs = "mine"; 08922 /* If the information elements are in here... use them */ 08923 if (ies.codec_prefs) 08924 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08925 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08926 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 08927 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08928 pref = iaxs[fr->callno]->rprefs; 08929 using_prefs = "caller"; 08930 } else { 08931 pref = iaxs[fr->callno]->prefs; 08932 } 08933 } else 08934 pref = iaxs[fr->callno]->prefs; 08935 08936 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08937 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08938 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08939 } 08940 if (!format) { 08941 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08942 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08943 if (!format) { 08944 memset(&ied0, 0, sizeof(ied0)); 08945 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08946 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08947 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08948 if (!iaxs[fr->callno]) { 08949 ast_mutex_unlock(&iaxsl[fr->callno]); 08950 return 1; 08951 } 08952 if (authdebug) { 08953 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08954 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); 08955 else 08956 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); 08957 } 08958 } else { 08959 /* Pick one... */ 08960 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08961 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08962 format = 0; 08963 } else { 08964 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08965 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08966 memset(&pref, 0, sizeof(pref)); 08967 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08968 strcpy(caller_pref_buf,"disabled"); 08969 strcpy(host_pref_buf,"disabled"); 08970 } else { 08971 using_prefs = "mine"; 08972 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08973 /* Do the opposite of what we tried above. */ 08974 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08975 pref = iaxs[fr->callno]->prefs; 08976 } else { 08977 pref = iaxs[fr->callno]->rprefs; 08978 using_prefs = "caller"; 08979 } 08980 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08981 08982 } else /* if no codec_prefs IE do it the old way */ 08983 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08984 } 08985 } 08986 08987 if (!format) { 08988 memset(&ied0, 0, sizeof(ied0)); 08989 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08990 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08991 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08992 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08993 if (!iaxs[fr->callno]) { 08994 ast_mutex_unlock(&iaxsl[fr->callno]); 08995 return 1; 08996 } 08997 if (authdebug) 08998 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); 08999 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09000 break; 09001 } 09002 } 09003 } 09004 if (format) { 09005 /* No authentication required, let them in */ 09006 memset(&ied1, 0, sizeof(ied1)); 09007 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09008 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09009 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09010 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09011 if (option_verbose > 2) 09012 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 09013 "%srequested format = %s,\n" 09014 "%srequested prefs = %s,\n" 09015 "%sactual format = %s,\n" 09016 "%shost prefs = %s,\n" 09017 "%spriority = %s\n", 09018 ast_inet_ntoa(sin.sin_addr), 09019 VERBOSE_PREFIX_4, 09020 ast_getformatname(iaxs[fr->callno]->peerformat), 09021 VERBOSE_PREFIX_4, 09022 caller_pref_buf, 09023 VERBOSE_PREFIX_4, 09024 ast_getformatname(format), 09025 VERBOSE_PREFIX_4, 09026 host_pref_buf, 09027 VERBOSE_PREFIX_4, 09028 using_prefs); 09029 09030 iaxs[fr->callno]->chosenformat = format; 09031 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09032 } else { 09033 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09034 /* If this is a TBD call, we're ready but now what... */ 09035 if (option_verbose > 2) 09036 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09037 } 09038 } 09039 } 09040 break; 09041 } 09042 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 09043 merge_encryption(iaxs[fr->callno],ies.encmethods); 09044 else 09045 iaxs[fr->callno]->encmethods = 0; 09046 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 09047 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 09048 if (!iaxs[fr->callno]) { 09049 ast_mutex_unlock(&iaxsl[fr->callno]); 09050 return 1; 09051 } 09052 break; 09053 case IAX_COMMAND_DPREQ: 09054 /* Request status in the dialplan */ 09055 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 09056 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 09057 if (iaxcompat) { 09058 /* Spawn a thread for the lookup */ 09059 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 09060 } else { 09061 /* Just look it up */ 09062 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 09063 } 09064 } 09065 break; 09066 case IAX_COMMAND_HANGUP: 09067 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09068 if (option_debug) 09069 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 09070 /* Set hangup cause according to remote */ 09071 if (ies.causecode && iaxs[fr->callno]->owner) 09072 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09073 /* Send ack immediately, before we destroy */ 09074 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09075 iax2_destroy(fr->callno); 09076 break; 09077 case IAX_COMMAND_REJECT: 09078 /* Set hangup cause according to remote */ 09079 if (ies.causecode && iaxs[fr->callno]->owner) 09080 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 09081 09082 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09083 if (iaxs[fr->callno]->owner && authdebug) 09084 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 09085 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 09086 ies.cause ? ies.cause : "<Unknown>"); 09087 if (option_debug) 09088 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 09089 fr->callno); 09090 } 09091 /* Send ack immediately, before we destroy */ 09092 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 09093 fr->ts, NULL, 0, fr->iseqno); 09094 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 09095 iaxs[fr->callno]->error = EPERM; 09096 iax2_destroy(fr->callno); 09097 break; 09098 case IAX_COMMAND_TRANSFER: 09099 { 09100 struct ast_channel *bridged_chan; 09101 09102 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 09103 /* Set BLINDTRANSFER channel variables */ 09104 09105 ast_mutex_unlock(&iaxsl[fr->callno]); 09106 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 09107 ast_mutex_lock(&iaxsl[fr->callno]); 09108 if (!iaxs[fr->callno]) { 09109 ast_mutex_unlock(&iaxsl[fr->callno]); 09110 return 1; 09111 } 09112 09113 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 09114 if (!strcmp(ies.called_number, ast_parking_ext())) { 09115 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 09116 ast_mutex_unlock(&iaxsl[fr->callno]); 09117 if (iax_park(bridged_chan, saved_channel)) { 09118 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 09119 } else { 09120 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 09121 } 09122 ast_mutex_lock(&iaxsl[fr->callno]); 09123 } else { 09124 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 09125 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 09126 ies.called_number, iaxs[fr->callno]->context); 09127 else 09128 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 09129 ies.called_number, iaxs[fr->callno]->context); 09130 } 09131 } else 09132 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 09133 09134 break; 09135 } 09136 case IAX_COMMAND_ACCEPT: 09137 /* Ignore if call is already up or needs authentication or is a TBD */ 09138 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 09139 break; 09140 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 09141 /* Send ack immediately, before we destroy */ 09142 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09143 iax2_destroy(fr->callno); 09144 break; 09145 } 09146 if (ies.format) { 09147 iaxs[fr->callno]->peerformat = ies.format; 09148 } else { 09149 if (iaxs[fr->callno]->owner) 09150 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 09151 else 09152 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 09153 } 09154 if (option_verbose > 2) 09155 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)); 09156 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 09157 memset(&ied0, 0, sizeof(ied0)); 09158 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09159 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09160 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09161 if (!iaxs[fr->callno]) { 09162 ast_mutex_unlock(&iaxsl[fr->callno]); 09163 return 1; 09164 } 09165 if (authdebug) 09166 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); 09167 } else { 09168 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09169 if (iaxs[fr->callno]->owner) { 09170 /* Switch us to use a compatible format */ 09171 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 09172 if (option_verbose > 2) 09173 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 09174 retryowner2: 09175 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 09176 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 09177 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 09178 } 09179 09180 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 09181 /* Setup read/write formats properly. */ 09182 if (iaxs[fr->callno]->owner->writeformat) 09183 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 09184 if (iaxs[fr->callno]->owner->readformat) 09185 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09186 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 09187 } 09188 } 09189 } 09190 if (iaxs[fr->callno]) { 09191 ast_mutex_lock(&dpcache_lock); 09192 dp = iaxs[fr->callno]->dpentries; 09193 while(dp) { 09194 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 09195 iax2_dprequest(dp, fr->callno); 09196 } 09197 dp = dp->peer; 09198 } 09199 ast_mutex_unlock(&dpcache_lock); 09200 } 09201 break; 09202 case IAX_COMMAND_POKE: 09203 /* Send back a pong packet with the original timestamp */ 09204 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 09205 if (!iaxs[fr->callno]) { 09206 ast_mutex_unlock(&iaxsl[fr->callno]); 09207 return 1; 09208 } 09209 break; 09210 case IAX_COMMAND_PING: 09211 { 09212 struct iax_ie_data pingied; 09213 construct_rr(iaxs[fr->callno], &pingied); 09214 /* Send back a pong packet with the original timestamp */ 09215 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 09216 } 09217 break; 09218 case IAX_COMMAND_PONG: 09219 /* Calculate ping time */ 09220 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 09221 /* save RR info */ 09222 save_rr(fr, &ies); 09223 09224 if (iaxs[fr->callno]->peerpoke) { 09225 peer = iaxs[fr->callno]->peerpoke; 09226 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 09227 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 09228 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 09229 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09230 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09231 } 09232 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 09233 if (iaxs[fr->callno]->pingtime > peer->maxms) { 09234 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 09235 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 09236 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09237 } 09238 } 09239 peer->lastms = iaxs[fr->callno]->pingtime; 09240 if (peer->smoothing && (peer->lastms > -1)) 09241 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 09242 else if (peer->smoothing && peer->lastms < 0) 09243 peer->historicms = (0 + peer->historicms) / 2; 09244 else 09245 peer->historicms = iaxs[fr->callno]->pingtime; 09246 09247 /* Remove scheduled iax2_poke_noanswer */ 09248 if (peer->pokeexpire > -1) { 09249 if (!ast_sched_del(sched, peer->pokeexpire)) { 09250 peer_unref(peer); 09251 peer->pokeexpire = -1; 09252 } 09253 } 09254 /* Schedule the next cycle */ 09255 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 09256 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 09257 else 09258 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 09259 if (peer->pokeexpire == -1) 09260 peer_unref(peer); 09261 /* and finally send the ack */ 09262 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09263 /* And wrap up the qualify call */ 09264 iax2_destroy(fr->callno); 09265 peer->callno = 0; 09266 if (option_debug) 09267 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 09268 } 09269 break; 09270 case IAX_COMMAND_LAGRQ: 09271 case IAX_COMMAND_LAGRP: 09272 f.src = "LAGRQ"; 09273 f.mallocd = 0; 09274 f.offset = 0; 09275 f.samples = 0; 09276 iax_frame_wrap(fr, &f); 09277 if(f.subclass == IAX_COMMAND_LAGRQ) { 09278 /* Received a LAGRQ - echo back a LAGRP */ 09279 fr->af.subclass = IAX_COMMAND_LAGRP; 09280 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 09281 } else { 09282 /* Received LAGRP in response to our LAGRQ */ 09283 unsigned int ts; 09284 /* This is a reply we've been given, actually measure the difference */ 09285 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 09286 iaxs[fr->callno]->lag = ts - fr->ts; 09287 if (option_debug && iaxdebug) 09288 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 09289 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 09290 } 09291 break; 09292 case IAX_COMMAND_AUTHREQ: 09293 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09294 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>"); 09295 break; 09296 } 09297 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 09298 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 09299 .subclass = AST_CONTROL_HANGUP, 09300 }; 09301 ast_log(LOG_WARNING, 09302 "I don't know how to authenticate %s to %s\n", 09303 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 09304 iax2_queue_frame(fr->callno, &hangup_fr); 09305 } 09306 if (!iaxs[fr->callno]) { 09307 ast_mutex_unlock(&iaxsl[fr->callno]); 09308 return 1; 09309 } 09310 break; 09311 case IAX_COMMAND_AUTHREP: 09312 /* For security, always ack immediately */ 09313 if (delayreject) 09314 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09315 /* Ignore once we've started */ 09316 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 09317 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>"); 09318 break; 09319 } 09320 if (authenticate_verify(iaxs[fr->callno], &ies)) { 09321 if (authdebug) 09322 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); 09323 memset(&ied0, 0, sizeof(ied0)); 09324 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09325 break; 09326 } 09327 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09328 /* This might re-enter the IAX code and need the lock */ 09329 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 09330 } else 09331 exists = 0; 09332 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09333 if (authdebug) 09334 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); 09335 memset(&ied0, 0, sizeof(ied0)); 09336 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09337 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09338 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09339 if (!iaxs[fr->callno]) { 09340 ast_mutex_unlock(&iaxsl[fr->callno]); 09341 return 1; 09342 } 09343 } else { 09344 /* Select an appropriate format */ 09345 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09346 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09347 using_prefs = "reqonly"; 09348 } else { 09349 using_prefs = "disabled"; 09350 } 09351 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09352 memset(&pref, 0, sizeof(pref)); 09353 strcpy(caller_pref_buf, "disabled"); 09354 strcpy(host_pref_buf, "disabled"); 09355 } else { 09356 using_prefs = "mine"; 09357 if (ies.codec_prefs) 09358 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09359 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09360 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09361 pref = iaxs[fr->callno]->rprefs; 09362 using_prefs = "caller"; 09363 } else { 09364 pref = iaxs[fr->callno]->prefs; 09365 } 09366 } else /* if no codec_prefs IE do it the old way */ 09367 pref = iaxs[fr->callno]->prefs; 09368 09369 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09370 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09371 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09372 } 09373 if (!format) { 09374 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09375 if (option_debug) 09376 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); 09377 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09378 } 09379 if (!format) { 09380 if (authdebug) { 09381 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09382 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); 09383 else 09384 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); 09385 } 09386 memset(&ied0, 0, sizeof(ied0)); 09387 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09388 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09389 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09390 if (!iaxs[fr->callno]) { 09391 ast_mutex_unlock(&iaxsl[fr->callno]); 09392 return 1; 09393 } 09394 } else { 09395 /* Pick one... */ 09396 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09397 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09398 format = 0; 09399 } else { 09400 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09401 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09402 memset(&pref, 0, sizeof(pref)); 09403 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 09404 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09405 strcpy(caller_pref_buf,"disabled"); 09406 strcpy(host_pref_buf,"disabled"); 09407 } else { 09408 using_prefs = "mine"; 09409 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09410 /* Do the opposite of what we tried above. */ 09411 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09412 pref = iaxs[fr->callno]->prefs; 09413 } else { 09414 pref = iaxs[fr->callno]->rprefs; 09415 using_prefs = "caller"; 09416 } 09417 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 09418 } else /* if no codec_prefs IE do it the old way */ 09419 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09420 } 09421 } 09422 if (!format) { 09423 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09424 if (authdebug) { 09425 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09426 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); 09427 else 09428 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); 09429 } 09430 memset(&ied0, 0, sizeof(ied0)); 09431 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09432 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09433 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09434 if (!iaxs[fr->callno]) { 09435 ast_mutex_unlock(&iaxsl[fr->callno]); 09436 return 1; 09437 } 09438 } 09439 } 09440 } 09441 if (format) { 09442 /* Authentication received */ 09443 memset(&ied1, 0, sizeof(ied1)); 09444 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 09445 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 09446 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 09447 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09448 if (option_verbose > 2) 09449 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 09450 "%srequested format = %s,\n" 09451 "%srequested prefs = %s,\n" 09452 "%sactual format = %s,\n" 09453 "%shost prefs = %s,\n" 09454 "%spriority = %s\n", 09455 ast_inet_ntoa(sin.sin_addr), 09456 VERBOSE_PREFIX_4, 09457 ast_getformatname(iaxs[fr->callno]->peerformat), 09458 VERBOSE_PREFIX_4, 09459 caller_pref_buf, 09460 VERBOSE_PREFIX_4, 09461 ast_getformatname(format), 09462 VERBOSE_PREFIX_4, 09463 host_pref_buf, 09464 VERBOSE_PREFIX_4, 09465 using_prefs); 09466 09467 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09468 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 09469 iax2_destroy(fr->callno); 09470 } else { 09471 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09472 /* If this is a TBD call, we're ready but now what... */ 09473 if (option_verbose > 2) 09474 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 09475 } 09476 } 09477 } 09478 break; 09479 case IAX_COMMAND_DIAL: 09480 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 09481 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 09482 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 09483 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 09484 if (authdebug) 09485 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); 09486 memset(&ied0, 0, sizeof(ied0)); 09487 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09488 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09489 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09490 if (!iaxs[fr->callno]) { 09491 ast_mutex_unlock(&iaxsl[fr->callno]); 09492 return 1; 09493 } 09494 } else { 09495 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09496 if (option_verbose > 2) 09497 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 09498 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 09499 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 09500 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 09501 iax2_destroy(fr->callno); 09502 } 09503 } 09504 break; 09505 case IAX_COMMAND_INVAL: 09506 iaxs[fr->callno]->error = ENOTCONN; 09507 if (option_debug) 09508 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 09509 iax2_destroy(fr->callno); 09510 if (option_debug) 09511 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 09512 break; 09513 case IAX_COMMAND_VNAK: 09514 if (option_debug) 09515 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 09516 /* Force retransmission */ 09517 vnak_retransmit(fr->callno, fr->iseqno); 09518 break; 09519 case IAX_COMMAND_REGREQ: 09520 case IAX_COMMAND_REGREL: 09521 /* For security, always ack immediately */ 09522 if (delayreject) 09523 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09524 if (register_verify(fr->callno, &sin, &ies)) { 09525 if (!iaxs[fr->callno]) { 09526 ast_mutex_unlock(&iaxsl[fr->callno]); 09527 return 1; 09528 } 09529 /* Send delayed failure */ 09530 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 09531 break; 09532 } 09533 if (!iaxs[fr->callno]) { 09534 ast_mutex_unlock(&iaxsl[fr->callno]); 09535 return 1; 09536 } 09537 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 09538 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 09539 09540 if (f.subclass == IAX_COMMAND_REGREL) 09541 memset(&sin, 0, sizeof(sin)); 09542 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 09543 ast_log(LOG_WARNING, "Registry error\n"); 09544 if (!iaxs[fr->callno]) { 09545 ast_mutex_unlock(&iaxsl[fr->callno]); 09546 return 1; 09547 } 09548 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09549 ast_mutex_unlock(&iaxsl[fr->callno]); 09550 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09551 ast_mutex_lock(&iaxsl[fr->callno]); 09552 if (!iaxs[fr->callno]) { 09553 ast_mutex_unlock(&iaxsl[fr->callno]); 09554 return 1; 09555 } 09556 } 09557 break; 09558 } 09559 registry_authrequest(fr->callno); 09560 if (!iaxs[fr->callno]) { 09561 ast_mutex_unlock(&iaxsl[fr->callno]); 09562 return 1; 09563 } 09564 break; 09565 case IAX_COMMAND_REGACK: 09566 if (iax2_ack_registry(&ies, &sin, fr->callno)) 09567 ast_log(LOG_WARNING, "Registration failure\n"); 09568 /* Send ack immediately, before we destroy */ 09569 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09570 iax2_destroy(fr->callno); 09571 break; 09572 case IAX_COMMAND_REGREJ: 09573 if (iaxs[fr->callno]->reg) { 09574 if (authdebug) { 09575 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)); 09576 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>"); 09577 } 09578 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 09579 } 09580 /* Send ack immediately, before we destroy */ 09581 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09582 iax2_destroy(fr->callno); 09583 break; 09584 case IAX_COMMAND_REGAUTH: 09585 /* Authentication request */ 09586 if (registry_rerequest(&ies, fr->callno, &sin)) { 09587 memset(&ied0, 0, sizeof(ied0)); 09588 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 09589 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09590 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09591 if (!iaxs[fr->callno]) { 09592 ast_mutex_unlock(&iaxsl[fr->callno]); 09593 return 1; 09594 } 09595 } 09596 break; 09597 case IAX_COMMAND_TXREJ: 09598 iaxs[fr->callno]->transferring = 0; 09599 if (option_verbose > 2) 09600 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09601 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 09602 if (iaxs[fr->callno]->bridgecallno) { 09603 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 09604 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 09605 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 09606 } 09607 } 09608 break; 09609 case IAX_COMMAND_TXREADY: 09610 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 09611 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 09612 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 09613 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 09614 else 09615 iaxs[fr->callno]->transferring = TRANSFER_READY; 09616 if (option_verbose > 2) 09617 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 09618 if (iaxs[fr->callno]->bridgecallno) { 09619 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 09620 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 09621 /* They're both ready, now release them. */ 09622 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 09623 if (option_verbose > 2) 09624 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09625 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09626 09627 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 09628 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 09629 09630 memset(&ied0, 0, sizeof(ied0)); 09631 memset(&ied1, 0, sizeof(ied1)); 09632 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09633 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09634 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 09635 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 09636 } else { 09637 if (option_verbose > 2) 09638 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 09639 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 09640 09641 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 09642 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 09643 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 09644 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 09645 09646 /* Stop doing lag & ping requests */ 09647 stop_stuff(fr->callno); 09648 stop_stuff(iaxs[fr->callno]->bridgecallno); 09649 09650 memset(&ied0, 0, sizeof(ied0)); 09651 memset(&ied1, 0, sizeof(ied1)); 09652 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 09653 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 09654 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 09655 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 09656 } 09657 09658 } 09659 } 09660 } 09661 break; 09662 case IAX_COMMAND_TXREQ: 09663 try_transfer(iaxs[fr->callno], &ies); 09664 break; 09665 case IAX_COMMAND_TXCNT: 09666 if (iaxs[fr->callno]->transferring) 09667 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 09668 break; 09669 case IAX_COMMAND_TXREL: 09670 /* Send ack immediately, rather than waiting until we've changed addresses */ 09671 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09672 complete_transfer(fr->callno, &ies); 09673 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 09674 break; 09675 case IAX_COMMAND_TXMEDIA: 09676 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 09677 AST_LIST_LOCK(&iaxq.queue); 09678 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09679 /* Cancel any outstanding frames and start anew */ 09680 if ((fr->callno == cur->callno) && (cur->transfer)) { 09681 cur->retries = -1; 09682 } 09683 } 09684 AST_LIST_UNLOCK(&iaxq.queue); 09685 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 09686 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 09687 } 09688 break; 09689 case IAX_COMMAND_DPREP: 09690 complete_dpreply(iaxs[fr->callno], &ies); 09691 break; 09692 case IAX_COMMAND_UNSUPPORT: 09693 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 09694 break; 09695 case IAX_COMMAND_FWDOWNL: 09696 /* Firmware download */ 09697 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 09698 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 09699 break; 09700 } 09701 memset(&ied0, 0, sizeof(ied0)); 09702 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 09703 if (res < 0) 09704 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09705 else if (res > 0) 09706 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09707 else 09708 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 09709 if (!iaxs[fr->callno]) { 09710 ast_mutex_unlock(&iaxsl[fr->callno]); 09711 return 1; 09712 } 09713 break; 09714 case IAX_COMMAND_CALLTOKEN: 09715 { 09716 struct iax_frame *cur; 09717 AST_LIST_LOCK(&iaxq.queue); 09718 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 09719 /* find the last sent frame in our frame queue for this callno. 09720 * There are many things to take into account before resending this frame. 09721 * All of these are taken care of in resend_with_token() */ 09722 if (cur->callno == fr->callno) { 09723 break; 09724 } 09725 } 09726 AST_LIST_UNLOCK(&iaxq.queue); 09727 09728 /* find last sent frame */ 09729 if (cur && ies.calltoken && ies.calltokendata) { 09730 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 09731 } 09732 break; 09733 } 09734 default: 09735 if (option_debug) 09736 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 09737 memset(&ied0, 0, sizeof(ied0)); 09738 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 09739 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 09740 } 09741 /* Don't actually pass these frames along */ 09742 if ((f.subclass != IAX_COMMAND_ACK) && 09743 (f.subclass != IAX_COMMAND_TXCNT) && 09744 (f.subclass != IAX_COMMAND_TXACC) && 09745 (f.subclass != IAX_COMMAND_INVAL) && 09746 (f.subclass != IAX_COMMAND_VNAK)) { 09747 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09748 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09749 } 09750 ast_mutex_unlock(&iaxsl[fr->callno]); 09751 return 1; 09752 } 09753 /* Unless this is an ACK or INVAL frame, ack it */ 09754 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 09755 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09756 } else if (minivid) { 09757 f.frametype = AST_FRAME_VIDEO; 09758 if (iaxs[fr->callno]->videoformat > 0) 09759 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 09760 else { 09761 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 09762 iax2_vnak(fr->callno); 09763 ast_mutex_unlock(&iaxsl[fr->callno]); 09764 return 1; 09765 } 09766 f.datalen = res - sizeof(*vh); 09767 if (f.datalen) 09768 f.data = thread->buf + sizeof(*vh); 09769 else 09770 f.data = NULL; 09771 #ifdef IAXTESTS 09772 if (test_resync) { 09773 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 09774 } else 09775 #endif /* IAXTESTS */ 09776 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 09777 } else { 09778 /* A mini frame */ 09779 f.frametype = AST_FRAME_VOICE; 09780 if (iaxs[fr->callno]->voiceformat > 0) 09781 f.subclass = iaxs[fr->callno]->voiceformat; 09782 else { 09783 if (option_debug) 09784 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 09785 iax2_vnak(fr->callno); 09786 ast_mutex_unlock(&iaxsl[fr->callno]); 09787 return 1; 09788 } 09789 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 09790 if (f.datalen < 0) { 09791 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09792 ast_mutex_unlock(&iaxsl[fr->callno]); 09793 return 1; 09794 } 09795 if (f.datalen) 09796 f.data = thread->buf + sizeof(*mh); 09797 else 09798 f.data = NULL; 09799 #ifdef IAXTESTS 09800 if (test_resync) { 09801 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 09802 } else 09803 #endif /* IAXTESTS */ 09804 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 09805 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 09806 } 09807 /* Don't pass any packets until we're started */ 09808 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09809 ast_mutex_unlock(&iaxsl[fr->callno]); 09810 return 1; 09811 } 09812 /* Common things */ 09813 f.src = "IAX2"; 09814 f.mallocd = 0; 09815 f.offset = 0; 09816 f.len = 0; 09817 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 09818 f.samples = ast_codec_get_samples(&f); 09819 /* We need to byteswap incoming slinear samples from network byte order */ 09820 if (f.subclass == AST_FORMAT_SLINEAR) 09821 ast_frame_byteswap_be(&f); 09822 } else 09823 f.samples = 0; 09824 iax_frame_wrap(fr, &f); 09825 09826 /* If this is our most recent packet, use it as our basis for timestamping */ 09827 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 09828 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 09829 fr->outoforder = 0; 09830 } else { 09831 if (option_debug && iaxdebug && iaxs[fr->callno]) 09832 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); 09833 fr->outoforder = -1; 09834 } 09835 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 09836 duped_fr = iaxfrdup2(fr); 09837 if (duped_fr) { 09838 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 09839 } 09840 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 09841 iaxs[fr->callno]->last = fr->ts; 09842 #if 1 09843 if (option_debug && iaxdebug) 09844 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 09845 #endif 09846 } 09847 09848 /* Always run again */ 09849 ast_mutex_unlock(&iaxsl[fr->callno]); 09850 return 1; 09851 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 8156 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
08157 { 08158 struct iax2_thread *thread; 08159 socklen_t len; 08160 time_t t; 08161 static time_t last_errtime = 0; 08162 struct ast_iax2_full_hdr *fh; 08163 08164 if (!(thread = find_idle_thread())) { 08165 time(&t); 08166 if (t != last_errtime && option_debug) 08167 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 08168 last_errtime = t; 08169 usleep(1); 08170 return 1; 08171 } 08172 08173 len = sizeof(thread->iosin); 08174 thread->iofd = fd; 08175 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 08176 thread->buf_size = sizeof(thread->readbuf); 08177 thread->buf = thread->readbuf; 08178 if (thread->buf_len < 0) { 08179 if (errno != ECONNREFUSED && errno != EAGAIN) 08180 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 08181 handle_error(); 08182 thread->iostate = IAX_IOSTATE_IDLE; 08183 signal_condition(&thread->lock, &thread->cond); 08184 return 1; 08185 } 08186 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 08187 thread->iostate = IAX_IOSTATE_IDLE; 08188 signal_condition(&thread->lock, &thread->cond); 08189 return 1; 08190 } 08191 08192 /* Determine if this frame is a full frame; if so, and any thread is currently 08193 processing a full frame for the same callno from this peer, then drop this 08194 frame (and the peer will retransmit it) */ 08195 fh = (struct ast_iax2_full_hdr *) thread->buf; 08196 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 08197 struct iax2_thread *cur = NULL; 08198 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 08199 08200 AST_LIST_LOCK(&active_list); 08201 AST_LIST_TRAVERSE(&active_list, cur, list) { 08202 if ((cur->ffinfo.callno == callno) && 08203 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 08204 break; 08205 } 08206 if (cur) { 08207 /* we found another thread processing a full frame for this call, 08208 so queue it up for processing later. */ 08209 defer_full_frame(thread, cur); 08210 AST_LIST_UNLOCK(&active_list); 08211 thread->iostate = IAX_IOSTATE_IDLE; 08212 signal_condition(&thread->lock, &thread->cond); 08213 return 1; 08214 } else { 08215 /* this thread is going to process this frame, so mark it */ 08216 thread->ffinfo.callno = callno; 08217 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 08218 thread->ffinfo.type = fh->type; 08219 thread->ffinfo.csub = fh->csub; 08220 } 08221 AST_LIST_UNLOCK(&active_list); 08222 } 08223 08224 /* Mark as ready and send on its way */ 08225 thread->iostate = IAX_IOSTATE_READY; 08226 #ifdef DEBUG_SCHED_MULTITHREAD 08227 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 08228 #endif 08229 signal_condition(&thread->lock, &thread->cond); 08230 08231 return 1; 08232 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 7943 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().
07944 { 07945 pthread_t newthread; 07946 struct dpreq_data *dpr; 07947 pthread_attr_t attr; 07948 07949 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 07950 return; 07951 07952 pthread_attr_init(&attr); 07953 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07954 07955 dpr->callno = callno; 07956 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 07957 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 07958 if (callerid) 07959 dpr->callerid = ast_strdup(callerid); 07960 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 07961 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 07962 } 07963 07964 pthread_attr_destroy(&attr); 07965 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 10467 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().
10468 { 10469 pthread_attr_t attr; 10470 int threadcount = 0; 10471 int x; 10472 for (x = 0; x < iaxthreadcount; x++) { 10473 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 10474 if (thread) { 10475 thread->type = IAX_TYPE_POOL; 10476 thread->threadnum = ++threadcount; 10477 ast_mutex_init(&thread->lock); 10478 ast_cond_init(&thread->cond, NULL); 10479 pthread_attr_init(&attr); 10480 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10481 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 10482 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 10483 free(thread); 10484 thread = NULL; 10485 } 10486 AST_LIST_LOCK(&idle_list); 10487 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 10488 AST_LIST_UNLOCK(&idle_list); 10489 } 10490 } 10491 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 10492 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 10493 if (option_verbose > 1) 10494 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 10495 return 0; 10496 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 7625 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
07626 { 07627 iax2_destroy_helper(iaxs[callno]); 07628 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1386 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().
01387 { 01388 if (!pvt->peercallno) { 01389 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01390 return; 01391 } 01392 01393 ao2_link(iax_peercallno_pvts, pvt); 01394 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1367 of file chan_iax2.c.
References ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01368 { 01369 if (!pvt->transfercallno) { 01370 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01371 return; 01372 } 01373 01374 ao2_link(iax_transfercallno_pvts, pvt); 01375 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7812 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().
07813 { 07814 char buf[1024]; 07815 int res; 07816 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 07817 int processed = 0; 07818 int totalcalls = 0; 07819 #ifdef DAHDI_TIMERACK 07820 int x = 1; 07821 #endif 07822 struct timeval now; 07823 if (iaxtrunkdebug) 07824 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 07825 gettimeofday(&now, NULL); 07826 if (events & AST_IO_PRI) { 07827 #ifdef DAHDI_TIMERACK 07828 /* Great, this is a timing interface, just call the ioctl */ 07829 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 07830 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 07831 usleep(1); 07832 return -1; 07833 } 07834 #endif 07835 } else { 07836 /* Read and ignore from the pseudo channel for timing */ 07837 res = read(fd, buf, sizeof(buf)); 07838 if (res < 1) { 07839 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 07840 return 1; 07841 } 07842 } 07843 /* For each peer that supports trunking... */ 07844 ast_mutex_lock(&tpeerlock); 07845 tpeer = tpeers; 07846 while(tpeer) { 07847 processed++; 07848 res = 0; 07849 ast_mutex_lock(&tpeer->lock); 07850 /* We can drop a single tpeer per pass. That makes all this logic 07851 substantially easier */ 07852 if (!drop && iax2_trunk_expired(tpeer, &now)) { 07853 /* Take it out of the list, but don't free it yet, because it 07854 could be in use */ 07855 if (prev) 07856 prev->next = tpeer->next; 07857 else 07858 tpeers = tpeer->next; 07859 drop = tpeer; 07860 } else { 07861 res = send_trunk(tpeer, &now); 07862 if (iaxtrunkdebug) 07863 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); 07864 } 07865 totalcalls += res; 07866 res = 0; 07867 ast_mutex_unlock(&tpeer->lock); 07868 prev = tpeer; 07869 tpeer = tpeer->next; 07870 } 07871 ast_mutex_unlock(&tpeerlock); 07872 if (drop) { 07873 ast_mutex_lock(&drop->lock); 07874 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 07875 because by the time they could get tpeerlock, we've already grabbed it */ 07876 if (option_debug) 07877 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 07878 if (drop->trunkdata) { 07879 free(drop->trunkdata); 07880 drop->trunkdata = NULL; 07881 } 07882 ast_mutex_unlock(&drop->lock); 07883 ast_mutex_destroy(&drop->lock); 07884 free(drop); 07885 07886 } 07887 if (iaxtrunkdebug) 07888 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 07889 iaxtrunkdebug =0; 07890 return 1; 07891 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12509 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
12510 { 12511 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 12512 12513 /* The frames_received field is used to hold whether we're matching 12514 * against a full frame or not ... */ 12515 12516 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 12517 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 12518 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 12502 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
12503 { 12504 const struct chan_iax2_pvt *pvt = obj; 12505 12506 return pvt->transfercallno; 12507 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2889 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02890 { 02891 int res; 02892 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02893 sizeof(*sin)); 02894 if (res < 0) { 02895 if (option_debug) 02896 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02897 handle_error(); 02898 } else 02899 res = 0; 02900 return res; 02901 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2577 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().
02578 { 02579 struct stat stbuf; 02580 struct iax_firmware *cur; 02581 int ifd; 02582 int fd; 02583 int res; 02584 02585 struct ast_iax2_firmware_header *fwh, fwh2; 02586 struct MD5Context md5; 02587 unsigned char sum[16]; 02588 unsigned char buf[1024]; 02589 int len, chunk; 02590 char *s2; 02591 char *last; 02592 s2 = alloca(strlen(s) + 100); 02593 if (!s2) { 02594 ast_log(LOG_WARNING, "Alloca failed!\n"); 02595 return -1; 02596 } 02597 last = strrchr(s, '/'); 02598 if (last) 02599 last++; 02600 else 02601 last = s; 02602 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02603 res = stat(s, &stbuf); 02604 if (res < 0) { 02605 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02606 return -1; 02607 } 02608 /* Make sure it's not a directory */ 02609 if (S_ISDIR(stbuf.st_mode)) 02610 return -1; 02611 ifd = open(s, O_RDONLY); 02612 if (ifd < 0) { 02613 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02614 return -1; 02615 } 02616 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 02617 if (fd < 0) { 02618 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02619 close(ifd); 02620 return -1; 02621 } 02622 /* Unlink our newly created file */ 02623 unlink(s2); 02624 02625 /* Now copy the firmware into it */ 02626 len = stbuf.st_size; 02627 while(len) { 02628 chunk = len; 02629 if (chunk > sizeof(buf)) 02630 chunk = sizeof(buf); 02631 res = read(ifd, buf, chunk); 02632 if (res != chunk) { 02633 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02634 close(ifd); 02635 close(fd); 02636 return -1; 02637 } 02638 res = write(fd, buf, chunk); 02639 if (res != chunk) { 02640 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02641 close(ifd); 02642 close(fd); 02643 return -1; 02644 } 02645 len -= chunk; 02646 } 02647 close(ifd); 02648 /* Return to the beginning */ 02649 lseek(fd, 0, SEEK_SET); 02650 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02651 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02652 close(fd); 02653 return -1; 02654 } 02655 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02656 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02657 close(fd); 02658 return -1; 02659 } 02660 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02661 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02662 close(fd); 02663 return -1; 02664 } 02665 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02666 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02667 close(fd); 02668 return -1; 02669 } 02670 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02671 if (fwh == MAP_FAILED) { 02672 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02673 close(fd); 02674 return -1; 02675 } 02676 MD5Init(&md5); 02677 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02678 MD5Final(sum, &md5); 02679 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02680 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02681 munmap((void*)fwh, stbuf.st_size); 02682 close(fd); 02683 return -1; 02684 } 02685 cur = waresl.wares; 02686 while(cur) { 02687 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02688 /* Found a candidate */ 02689 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02690 /* The version we have on loaded is older, load this one instead */ 02691 break; 02692 /* This version is no newer than what we have. Don't worry about it. 02693 We'll consider it a proper load anyhow though */ 02694 munmap((void*)fwh, stbuf.st_size); 02695 close(fd); 02696 return 0; 02697 } 02698 cur = cur->next; 02699 } 02700 if (!cur) { 02701 /* Allocate a new one and link it */ 02702 if ((cur = ast_calloc(1, sizeof(*cur)))) { 02703 cur->fd = -1; 02704 cur->next = waresl.wares; 02705 waresl.wares = cur; 02706 } 02707 } 02708 if (cur) { 02709 if (cur->fwh) { 02710 munmap((void*)cur->fwh, cur->mmaplen); 02711 } 02712 if (cur->fd > -1) 02713 close(cur->fd); 02714 cur->fwh = fwh; 02715 cur->fd = fd; 02716 cur->mmaplen = stbuf.st_size; 02717 cur->dead = 0; 02718 } 02719 return 0; 02720 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6993 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
06994 { 06995 int newcall = 0; 06996 char newip[256]; 06997 struct iax_ie_data ied; 06998 struct sockaddr_in new; 06999 07000 07001 memset(&ied, 0, sizeof(ied)); 07002 if (ies->apparent_addr) 07003 bcopy(ies->apparent_addr, &new, sizeof(new)); 07004 if (ies->callno) 07005 newcall = ies->callno; 07006 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07007 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07008 return -1; 07009 } 07010 pvt->transfercallno = newcall; 07011 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07012 inet_aton(newip, &pvt->transfer.sin_addr); 07013 pvt->transfer.sin_family = AF_INET; 07014 pvt->transferring = TRANSFER_BEGIN; 07015 pvt->transferid = ies->transferid; 07016 store_by_transfercallno(pvt); 07017 if (ies->transferid) 07018 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07019 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07020 return 0; 07021 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1203 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01204 { 01205 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01206 if (csub & IAX_FLAG_SC_LOG) { 01207 /* special case for 'compressed' -1 */ 01208 if (csub == 0xff) 01209 return -1; 01210 else 01211 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01212 } 01213 else 01214 return csub; 01215 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 7277 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
07278 { 07279 if (peer->expire > -1) { 07280 if (!ast_sched_del(sched, peer->expire)) { 07281 peer->expire = -1; 07282 peer_unref(peer); 07283 } 07284 } 07285 07286 if (peer->pokeexpire > -1) { 07287 if (!ast_sched_del(sched, peer->pokeexpire)) { 07288 peer->pokeexpire = -1; 07289 peer_unref(peer); 07290 } 07291 } 07292 07293 ao2_unlink(peers, peer); 07294 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12468 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
12469 { 12470 ast_custom_function_unregister(&iaxpeer_function); 12471 return __unload_module(); 12472 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 4624 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
04625 { 04626 ast_mutex_unlock(&iaxsl[callno1]); 04627 ast_mutex_unlock(&iaxsl[callno0]); 04628 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3360 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().
03361 { 03362 /* Video mini frames only encode the lower 15 bits of the session 03363 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03364 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03365 const int lower_mask = (1 << ts_shift) - 1; 03366 const int upper_mask = ~lower_mask; 03367 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03368 03369 if ( (fr->ts & upper_mask) == last_upper ) { 03370 const int x = fr->ts - iaxs[fr->callno]->last; 03371 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03372 03373 if (x < -threshold) { 03374 /* Sudden big jump backwards in timestamp: 03375 What likely happened here is that miniframe timestamp has circled but we haven't 03376 gotten the update from the main packet. We'll just pretend that we did, and 03377 update the timestamp appropriately. */ 03378 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03379 if (option_debug && iaxdebug) 03380 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 03381 } else if (x > threshold) { 03382 /* Sudden apparent big jump forwards in timestamp: 03383 What's likely happened is this is an old miniframe belonging to the previous 03384 top 15 or 16-bit timestamp that has turned up out of order. 03385 Adjust the timestamp appropriately. */ 03386 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03387 if (option_debug && iaxdebug) 03388 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 03389 } 03390 } 03391 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3395 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().
03396 { 03397 int when; 03398 03399 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03400 03401 when = jb_next(pvt->jb) - when; 03402 03403 AST_SCHED_DEL(sched, pvt->jbid); 03404 03405 if(when <= 0) { 03406 /* XXX should really just empty until when > 0.. */ 03407 when = 1; 03408 } 03409 03410 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 03411 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1640 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01641 { 01642 int max = 1; 01643 int x; 01644 /* XXX Prolly don't need locks here XXX */ 01645 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01646 if (iaxs[x]) 01647 max = x + 1; 01648 } 01649 maxnontrunkcall = max; 01650 if (option_debug && iaxdebug) 01651 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01652 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1406 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01407 { 01408 int max = TRUNK_CALL_START; 01409 int x; 01410 01411 /* XXX Prolly don't need locks here XXX */ 01412 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01413 if (iaxs[x]) { 01414 max = x + 1; 01415 } 01416 } 01417 01418 maxtrunkcall = max; 01419 if (option_debug && iaxdebug) 01420 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01421 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2960 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().
02961 { 02962 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02963 struct ast_iax2_full_hdr *fh = f->data; 02964 struct ast_frame af; 02965 02966 /* if frame is encrypted. decrypt before updating it. */ 02967 if (f->encmethods) { 02968 decode_frame(&f->mydcx, fh, &af, &f->datalen); 02969 } 02970 /* Mark this as a retransmission */ 02971 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02972 /* Update iseqno */ 02973 f->iseqno = iaxs[f->callno]->iseqno; 02974 fh->iseqno = f->iseqno; 02975 02976 /* Now re-encrypt the frame */ 02977 if (f->encmethods) { 02978 /* since this is a retransmit frame, create a new random padding 02979 * before re-encrypting. */ 02980 build_rand_pad(f->semirand, sizeof(f->semirand)); 02981 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 02982 } 02983 return 0; 02984 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 7390 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().
07391 { 07392 /* Called from IAX thread only, with proper iaxsl lock */ 07393 struct iax_ie_data ied; 07394 struct iax2_peer *p; 07395 int msgcount; 07396 char data[80]; 07397 int version; 07398 const char *peer_name; 07399 int res = -1; 07400 07401 memset(&ied, 0, sizeof(ied)); 07402 07403 peer_name = ast_strdupa(iaxs[callno]->peer); 07404 07405 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 07406 ast_mutex_unlock(&iaxsl[callno]); 07407 if (!(p = find_peer(peer_name, 1))) { 07408 ast_mutex_lock(&iaxsl[callno]); 07409 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 07410 return -1; 07411 } 07412 ast_mutex_lock(&iaxsl[callno]); 07413 if (!iaxs[callno]) 07414 goto return_unref; 07415 07416 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 07417 if (sin->sin_addr.s_addr) { 07418 time_t nowtime; 07419 time(&nowtime); 07420 realtime_update_peer(peer_name, sin, nowtime); 07421 } else { 07422 realtime_update_peer(peer_name, sin, 0); 07423 } 07424 } 07425 if (inaddrcmp(&p->addr, sin)) { 07426 if (iax2_regfunk) 07427 iax2_regfunk(p->name, 1); 07428 07429 /* modify entry in peercnts table as _not_ registered */ 07430 peercnt_modify(0, 0, &p->addr); 07431 07432 /* Stash the IP address from which they registered */ 07433 memcpy(&p->addr, sin, sizeof(p->addr)); 07434 07435 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 07436 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 07437 ast_db_put("IAX/Registry", p->name, data); 07438 if (option_verbose > 2) 07439 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 07440 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 07441 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 07442 register_peer_exten(p, 1); 07443 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07444 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 07445 if (option_verbose > 2) 07446 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 07447 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 07448 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 07449 register_peer_exten(p, 0); 07450 ast_db_del("IAX/Registry", p->name); 07451 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 07452 } 07453 /* Update the host */ 07454 /* Verify that the host is really there */ 07455 iax2_poke_peer(p, callno); 07456 } 07457 07458 /* modify entry in peercnts table as registered */ 07459 if (p->maxcallno) { 07460 peercnt_modify(1, p->maxcallno, &p->addr); 07461 } 07462 07463 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 07464 if (!iaxs[callno]) { 07465 res = -1; 07466 goto return_unref; 07467 } 07468 07469 /* Store socket fd */ 07470 p->sockfd = fd; 07471 /* Setup the expiry */ 07472 if (p->expire > -1) { 07473 if (!ast_sched_del(sched, p->expire)) { 07474 p->expire = -1; 07475 peer_unref(p); 07476 } 07477 } 07478 /* treat an unspecified refresh interval as the minimum */ 07479 if (!refresh) 07480 refresh = min_reg_expire; 07481 if (refresh > max_reg_expire) { 07482 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07483 p->name, max_reg_expire, refresh); 07484 p->expiry = max_reg_expire; 07485 } else if (refresh < min_reg_expire) { 07486 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 07487 p->name, min_reg_expire, refresh); 07488 p->expiry = min_reg_expire; 07489 } else { 07490 p->expiry = refresh; 07491 } 07492 if (p->expiry && sin->sin_addr.s_addr) { 07493 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 07494 if (p->expire == -1) 07495 peer_unref(p); 07496 } 07497 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 07498 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 07499 if (sin->sin_addr.s_addr) { 07500 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 07501 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 07502 if (!ast_strlen_zero(p->mailbox)) { 07503 int new, old; 07504 ast_app_inboxcount(p->mailbox, &new, &old); 07505 if (new > 255) 07506 new = 255; 07507 if (old > 255) 07508 old = 255; 07509 msgcount = (old << 8) | new; 07510 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 07511 } 07512 if (ast_test_flag(p, IAX_HASCALLERID)) { 07513 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 07514 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 07515 } 07516 } 07517 version = iax_check_version(devtype); 07518 if (version) 07519 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 07520 07521 res = 0; 07522 07523 return_unref: 07524 peer_unref(p); 07525 07526 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 07527 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1250 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_objects().
01251 { 01252 struct iax2_user *user = obj, *user2 = arg; 01253 01254 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01255 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11136 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
11137 { 11138 struct iax2_user *user = obj; 11139 11140 ast_set_flag(user, IAX_DELME); 11141 11142 return 0; 11143 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 10885 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().
10886 { 10887 struct iax2_user *user = obj; 10888 10889 ast_free_ha(user->ha); 10890 free_context(user->contexts); 10891 if(user->vars) { 10892 ast_variables_destroy(user->vars); 10893 user->vars = NULL; 10894 } 10895 ast_string_field_free_memory(user); 10896 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1240 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_objects().
01241 { 01242 const struct iax2_user *user = obj; 01243 01244 return ast_str_hash(user->name); 01245 }
Definition at line 1298 of file chan_iax2.c.
References ao2_ref().
01299 { 01300 ao2_ref(user, +1); 01301 return user; 01302 }
Definition at line 1304 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().
01305 { 01306 ao2_ref(user, -1); 01307 return NULL; 01308 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 7726 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().
07727 { 07728 struct iax_frame *f; 07729 07730 AST_LIST_LOCK(&iaxq.queue); 07731 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 07732 /* Send a copy immediately */ 07733 if ((f->callno == callno) && iaxs[f->callno] && 07734 ((unsigned char ) (f->oseqno - last) < 128) && 07735 (f->retries >= 0)) { 07736 send_packet(f); 07737 } 07738 } 07739 AST_LIST_UNLOCK(&iaxq.queue); 07740 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4522 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().
04523 { 04524 unsigned short callno = pvt->callno; 04525 04526 if (!pvt->peercallno) { 04527 /* We don't know the remote side's call number, yet. :( */ 04528 int count = 10; 04529 while (count-- && pvt && !pvt->peercallno) { 04530 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 04531 pvt = iaxs[callno]; 04532 } 04533 if (!pvt->peercallno) { 04534 return -1; 04535 } 04536 } 04537 04538 return 0; 04539 }
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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 12686 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 216 of file chan_iax2.c.
Referenced by __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), dahdi_new(), disa_exec(), features_call(), 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 12686 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 156 of file chan_iax2.c.
struct ao2_container* callno_limits [static] |
Table containing custom callno limit rules for a range of ip addresses.
Definition at line 701 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 661 of file chan_iax2.c.
Referenced by __unload_module(), create_callno_pools(), get_unused_callno(), load_objects(), and replace_callno().
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 664 of file chan_iax2.c.
Referenced by __unload_module(), create_callno_pools(), get_unused_callno(), load_objects(), and replace_callno().
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 704 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 12254 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 12259 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 12269 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 12264 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 12249 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 142 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 12223 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 12215 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 12207 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
int defaultsockfd = -1 [static] |
Definition at line 173 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 221 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 782 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] |
uint16_t global_maxcallno_nonval [static] |
Total num of call numbers allowed to be allocated without calltoken validation
Definition at line 713 of file chan_iax2.c.
Referenced by get_unused_callno(), iax2_show_callnumber_usage(), and set_config().
int global_rtautoclear = 120 [static] |
Definition at line 274 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 224 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 202 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 222 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 175 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 12165 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 973 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 12231 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 917 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 924 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 471 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 157 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 204 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 469 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 905 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_frame_subclass2str(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 906 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __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_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(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 467 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 199 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 150 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 144 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 158 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 675 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 167 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 148 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 147 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 153 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 931 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 930 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 166 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 217 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 171 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 226 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 12227 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 12219 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 12211 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 172 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 10102 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 10104 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 698 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 691 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 149 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 138 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 12161 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 10103 of file chan_iax2.c.
int randomcalltokendata [static] |
Definition at line 673 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 200 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 229 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 228 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 227 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 12149 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 12157 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 12181 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 12199 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 12185 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 12153 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 12193 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 12169 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 12203 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 12145 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 12189 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 12176 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 140 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 208 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 169 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 164 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 715 of file chan_iax2.c.
Referenced by get_unused_callno(), iax2_show_callnumber_usage(), and replace_callno().
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 154 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 694 of file chan_iax2.c.
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().