#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 "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"
Include dependency graph for chan_iax2.c:
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
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 | parsed_dial_string |
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 | 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\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\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 |
#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 | 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 | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#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), IAX_STATE_UNCHANGED = (1 << 3) } |
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) } |
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 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 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 | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (sched_lock) | |
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, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
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 struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
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 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 | 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 | 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 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 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 | 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_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 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 void | poke_all_peers (void) |
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 | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
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 (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
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 int | timing_read (int *id, int fd, short events, void *cbdata) |
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) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
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 int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
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 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 | 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 struct timeval | lastused [ARRAY_LEN(iaxs)] |
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 * | 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 char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static char | show_cache_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 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 664 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 660 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 674 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 662 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 666 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 668 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 670 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 672 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 126 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 114 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 134 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 199 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 198 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 197 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 128 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 441 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\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\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 139 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 |
Definition at line 180 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 188 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 193 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 182 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 697 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 701 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 117 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 438 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 646 of file chan_iax2.c.
Referenced by load_module(), 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 444 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 442 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 131 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 439 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define NEW_ALLOW 1 |
#define NEW_FORCE 2 |
Definition at line 1429 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request().
#define NEW_PREVENT 0 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 125 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(), and iax2_write().
#define SCHED_MULTITHREADED |
Definition at line 110 of file chan_iax2.c.
Definition at line 982 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 828 of file chan_iax2.c.
Referenced by __find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 447 of file chan_iax2.c.
anonymous enum |
Definition at line 233 of file chan_iax2.c.
00233 { 00234 IAX_STATE_STARTED = (1 << 0), 00235 IAX_STATE_AUTHENTICATED = (1 << 1), 00236 IAX_STATE_TBD = (1 << 2), 00237 IAX_STATE_UNCHANGED = (1 << 3), 00238 } iax2_state;
anonymous enum |
Definition at line 245 of file chan_iax2.c.
00245 { 00246 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00247 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00248 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00249 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00250 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00251 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00252 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00253 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00254 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00255 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00256 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00257 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00258 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00259 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00260 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00261 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00262 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00263 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00264 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00265 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00266 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00267 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00268 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00269 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00270 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00271 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00272 response, so that we've achieved a three-way handshake with 00273 them before sending voice or anything else*/ 00274 } iax2_flags;
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 393 of file chan_iax2.c.
00393 { 00394 REG_STATE_UNREGISTERED = 0, 00395 REG_STATE_REGSENT, 00396 REG_STATE_AUTHSENT, 00397 REG_STATE_REGISTERED, 00398 REG_STATE_REJECTED, 00399 REG_STATE_TIMEOUT, 00400 REG_STATE_NOAUTH 00401 };
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 403 of file chan_iax2.c.
00403 { 00404 TRANSFER_NONE = 0, 00405 TRANSFER_BEGIN, 00406 TRANSFER_READY, 00407 TRANSFER_RELEASED, 00408 TRANSFER_PASSTHROUGH, 00409 TRANSFER_MBEGIN, 00410 TRANSFER_MREADY, 00411 TRANSFER_MRELEASED, 00412 TRANSFER_MPASSTHROUGH, 00413 TRANSFER_MEDIA, 00414 TRANSFER_MEDIAPASS 00415 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2148 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, ast_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, chan_iax2_pvt::owner, 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().
02149 { 02150 /* Attempt to transmit the frame to the remote peer... 02151 Called without iaxsl held. */ 02152 struct iax_frame *f = (struct iax_frame *)data; 02153 int freeme=0; 02154 int callno = f->callno; 02155 /* Make sure this call is still active */ 02156 if (callno) 02157 ast_mutex_lock(&iaxsl[callno]); 02158 if (callno && iaxs[callno]) { 02159 if ((f->retries < 0) /* Already ACK'd */ || 02160 (f->retries >= max_retries) /* Too many attempts */) { 02161 /* Record an error if we've transmitted too many times */ 02162 if (f->retries >= max_retries) { 02163 if (f->transfer) { 02164 /* Transfer timeout */ 02165 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02166 } else if (f->final) { 02167 if (f->final) 02168 iax2_destroy(callno); 02169 } else { 02170 if (iaxs[callno]->owner) 02171 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); 02172 iaxs[callno]->error = ETIMEDOUT; 02173 if (iaxs[callno]->owner) { 02174 struct ast_frame fr = { 0, }; 02175 /* Hangup the fd */ 02176 fr.frametype = AST_FRAME_CONTROL; 02177 fr.subclass = AST_CONTROL_HANGUP; 02178 iax2_queue_frame(callno, &fr); // XXX 02179 /* Remember, owner could disappear */ 02180 if (iaxs[callno] && iaxs[callno]->owner) 02181 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02182 } else { 02183 if (iaxs[callno]->reg) { 02184 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02185 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02186 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02187 } 02188 iax2_destroy(callno); 02189 } 02190 } 02191 02192 } 02193 freeme++; 02194 } else { 02195 /* Update it if it needs it */ 02196 update_packet(f); 02197 /* Attempt transmission */ 02198 send_packet(f); 02199 f->retries++; 02200 /* Try again later after 10 times as long */ 02201 f->retrytime *= 10; 02202 if (f->retrytime > MAX_RETRY_TIME) 02203 f->retrytime = MAX_RETRY_TIME; 02204 /* Transfer messages max out at one second */ 02205 if (f->transfer && (f->retrytime > 1000)) 02206 f->retrytime = 1000; 02207 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02208 } 02209 } else { 02210 /* Make sure it gets freed */ 02211 f->retries = -1; 02212 freeme++; 02213 } 02214 if (callno) 02215 ast_mutex_unlock(&iaxsl[callno]); 02216 /* Do not try again */ 02217 if (freeme) { 02218 /* Don't attempt delivery, just remove it from the queue */ 02219 AST_LIST_LOCK(&iaxq.queue); 02220 AST_LIST_REMOVE(&iaxq.queue, f, list); 02221 iaxq.count--; 02222 AST_LIST_UNLOCK(&iaxq.queue); 02223 f->retrans = -1; 02224 /* Free the IAX frame */ 02225 iax2_frame_free(f); 02226 } 02227 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6338 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().
06339 { 06340 /* Called from IAX thread only, without iaxs lock */ 06341 int callno = (int)(long)(nothing); 06342 struct iax_ie_data ied; 06343 ast_mutex_lock(&iaxsl[callno]); 06344 if (iaxs[callno]) { 06345 memset(&ied, 0, sizeof(ied)); 06346 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06347 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06348 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06349 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06350 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06351 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06352 } 06353 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06354 } 06355 ast_mutex_unlock(&iaxsl[callno]); 06356 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3103 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().
03104 { 03105 int callno = PTR_TO_CALLNO(nothing); 03106 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03107 ast_mutex_lock(&iaxsl[callno]); 03108 if (iaxs[callno]) { 03109 iaxs[callno]->initid = -1; 03110 iax2_queue_frame(callno, &f); 03111 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03112 } 03113 ast_mutex_unlock(&iaxsl[callno]); 03114 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6387 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().
06388 { 06389 /* Called from IAX thread only, without iaxs lock */ 06390 int callno = (int)(long)(nothing); 06391 struct iax_ie_data ied; 06392 ast_mutex_lock(&iaxsl[callno]); 06393 if (iaxs[callno]) { 06394 memset(&ied, 0, sizeof(ied)); 06395 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06396 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06397 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06398 } 06399 ast_mutex_unlock(&iaxsl[callno]); 06400 }
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 2015 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().
02016 { 02017 /* Just deliver the packet by using queueing. This is called by 02018 the IAX thread with the iaxsl lock held. */ 02019 struct iax_frame *fr = data; 02020 fr->retrans = -1; 02021 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02022 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02023 iax2_queue_frame(fr->callno, &fr->af); 02024 /* Free our iax frame */ 02025 iax2_frame_free(fr); 02026 /* And don't run again */ 02027 return 0; 02028 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6026 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(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
06027 { 06028 struct iax2_peer *peer = (struct iax2_peer *) data; 06029 06030 if (!peer) 06031 return; 06032 06033 peer->expire = -1; 06034 06035 if (option_debug) 06036 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06037 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06038 realtime_update_peer(peer->name, &peer->addr, 0); 06039 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06040 /* Reset the address */ 06041 memset(&peer->addr, 0, sizeof(peer->addr)); 06042 /* Reset expiry value */ 06043 peer->expiry = min_reg_expire; 06044 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06045 ast_db_del("IAX/Registry", peer->name); 06046 register_peer_exten(peer, 0); 06047 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06048 if (iax2_regfunk) 06049 iax2_regfunk(peer->name, 0); 06050 06051 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06052 unlink_peer(peer); 06053 06054 peer_unref(peer); 06055 }
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 1514 of file chan_iax2.c.
References chan_iax2_pvt::addr, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxsl, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, sched, send_lagrq(), send_ping(), store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01515 { 01516 int res = 0; 01517 int x; 01518 struct timeval now; 01519 char host[80]; 01520 01521 if (new <= NEW_ALLOW) { 01522 if (callno) { 01523 struct chan_iax2_pvt *pvt; 01524 struct chan_iax2_pvt tmp_pvt = { 01525 .callno = dcallno, 01526 .peercallno = callno, 01527 /* hack!! */ 01528 .frames_received = check_dcallno, 01529 }; 01530 01531 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01532 01533 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01534 if (return_locked) { 01535 ast_mutex_lock(&iaxsl[pvt->callno]); 01536 } 01537 res = pvt->callno; 01538 ao2_ref(pvt, -1); 01539 pvt = NULL; 01540 return res; 01541 } 01542 } 01543 01544 /* Look for an existing connection first */ 01545 for (x = 1; !res && x < maxnontrunkcall; x++) { 01546 ast_mutex_lock(&iaxsl[x]); 01547 if (iaxs[x]) { 01548 /* Look for an exact match */ 01549 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01550 res = x; 01551 } 01552 } 01553 if (!res || !return_locked) 01554 ast_mutex_unlock(&iaxsl[x]); 01555 } 01556 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01557 ast_mutex_lock(&iaxsl[x]); 01558 if (iaxs[x]) { 01559 /* Look for an exact match */ 01560 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01561 res = x; 01562 } 01563 } 01564 if (!res || !return_locked) 01565 ast_mutex_unlock(&iaxsl[x]); 01566 } 01567 } 01568 if (!res && (new >= NEW_ALLOW)) { 01569 int start, found = 0; 01570 01571 /* It may seem odd that we look through the peer list for a name for 01572 * this *incoming* call. Well, it is weird. However, users don't 01573 * have an IP address/port number that we can match against. So, 01574 * this is just checking for a peer that has that IP/port and 01575 * assuming that we have a user of the same name. This isn't always 01576 * correct, but it will be changed if needed after authentication. */ 01577 if (!iax2_getpeername(*sin, host, sizeof(host))) 01578 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01579 01580 now = ast_tvnow(); 01581 start = 1 + (ast_random() % (TRUNK_CALL_START - 1)); 01582 for (x = start; 1; x++) { 01583 if (x == TRUNK_CALL_START) { 01584 x = 0; 01585 continue; 01586 } 01587 01588 /* Find first unused call number that hasn't been used in a while */ 01589 ast_mutex_lock(&iaxsl[x]); 01590 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01591 found = 1; 01592 break; 01593 } 01594 ast_mutex_unlock(&iaxsl[x]); 01595 01596 if (x == start - 1) { 01597 break; 01598 } 01599 } 01600 /* We've still got lock held if we found a spot */ 01601 if (x == start - 1 && !found) { 01602 ast_log(LOG_WARNING, "No more space\n"); 01603 return 0; 01604 } 01605 iaxs[x] = new_iax(sin, host); 01606 update_max_nontrunk(); 01607 if (iaxs[x]) { 01608 if (option_debug && iaxdebug) 01609 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01610 iaxs[x]->sockfd = sockfd; 01611 iaxs[x]->addr.sin_port = sin->sin_port; 01612 iaxs[x]->addr.sin_family = sin->sin_family; 01613 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01614 iaxs[x]->peercallno = callno; 01615 iaxs[x]->callno = x; 01616 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01617 iaxs[x]->expiry = min_reg_expire; 01618 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01619 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01620 iaxs[x]->amaflags = amaflags; 01621 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01622 01623 ast_string_field_set(iaxs[x], accountcode, accountcode); 01624 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01625 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01626 01627 if (iaxs[x]->peercallno) { 01628 store_by_peercallno(iaxs[x]); 01629 } 01630 } else { 01631 ast_log(LOG_WARNING, "Out of resources\n"); 01632 ast_mutex_unlock(&iaxsl[x]); 01633 return 0; 01634 } 01635 if (!return_locked) 01636 ast_mutex_unlock(&iaxsl[x]); 01637 res = x; 01638 } 01639 return res; 01640 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2545 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), 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, 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().
02546 { 02547 int callno = PTR_TO_CALLNO(p); 02548 struct chan_iax2_pvt *pvt = NULL; 02549 struct iax_frame *fr; 02550 jb_frame frame; 02551 int ret; 02552 long now; 02553 long next; 02554 struct timeval tv; 02555 02556 /* Make sure we have a valid private structure before going on */ 02557 ast_mutex_lock(&iaxsl[callno]); 02558 pvt = iaxs[callno]; 02559 if (!pvt) { 02560 /* No go! */ 02561 ast_mutex_unlock(&iaxsl[callno]); 02562 return; 02563 } 02564 02565 pvt->jbid = -1; 02566 02567 gettimeofday(&tv,NULL); 02568 /* round up a millisecond since ast_sched_runq does; */ 02569 /* prevents us from spinning while waiting for our now */ 02570 /* to catch up with runq's now */ 02571 tv.tv_usec += 1000; 02572 02573 now = ast_tvdiff_ms(tv, pvt->rxcore); 02574 02575 if(now >= (next = jb_next(pvt->jb))) { 02576 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02577 switch(ret) { 02578 case JB_OK: 02579 fr = frame.data; 02580 __do_deliver(fr); 02581 /* __do_deliver() can cause the call to disappear */ 02582 pvt = iaxs[callno]; 02583 break; 02584 case JB_INTERP: 02585 { 02586 struct ast_frame af = { 0, }; 02587 02588 /* create an interpolation frame */ 02589 af.frametype = AST_FRAME_VOICE; 02590 af.subclass = pvt->voiceformat; 02591 af.samples = frame.ms * 8; 02592 af.src = "IAX2 JB interpolation"; 02593 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02594 af.offset = AST_FRIENDLY_OFFSET; 02595 02596 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02597 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02598 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02599 iax2_queue_frame(callno, &af); 02600 /* iax2_queue_frame() could cause the call to disappear */ 02601 pvt = iaxs[callno]; 02602 } 02603 } 02604 break; 02605 case JB_DROP: 02606 iax2_frame_free(frame.data); 02607 break; 02608 case JB_NOFRAME: 02609 case JB_EMPTY: 02610 /* do nothing */ 02611 break; 02612 default: 02613 /* shouldn't happen */ 02614 break; 02615 } 02616 } 02617 if (pvt) 02618 update_jbsched(pvt); 02619 ast_mutex_unlock(&iaxsl[callno]); 02620 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5719 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05720 { 05721 struct iax2_registry *reg = (struct iax2_registry *)data; 05722 reg->expire = -1; 05723 iax2_do_register(reg); 05724 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8805 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(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
08806 { 08807 struct iax2_peer *peer = (struct iax2_peer *)data; 08808 int callno; 08809 08810 if (peer->lastms > -1) { 08811 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08812 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08813 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08814 } 08815 if ((callno = peer->callno) > 0) { 08816 ast_mutex_lock(&iaxsl[callno]); 08817 iax2_destroy(callno); 08818 ast_mutex_unlock(&iaxsl[callno]); 08819 } 08820 peer->callno = 0; 08821 peer->lastms = -1; 08822 /* Try again quickly */ 08823 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08824 if (peer->pokeexpire == -1) 08825 peer_unref(peer); 08826 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6450 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06451 { 06452 struct iax2_peer *peer = (struct iax2_peer *)data; 06453 iax2_poke_peer(peer, 0); 06454 peer_unref(peer); 06455 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4509 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04510 { 04511 regex_t regexbuf; 04512 int havepattern = 0; 04513 int total_peers = 0; 04514 int online_peers = 0; 04515 int offline_peers = 0; 04516 int unmonitored_peers = 0; 04517 struct ao2_iterator i; 04518 04519 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04520 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04521 04522 struct iax2_peer *peer = NULL; 04523 char name[256]; 04524 int registeredonly=0; 04525 char *term = manager ? "\r\n" : "\n"; 04526 04527 switch (argc) { 04528 case 6: 04529 if (!strcasecmp(argv[3], "registered")) 04530 registeredonly = 1; 04531 else 04532 return RESULT_SHOWUSAGE; 04533 if (!strcasecmp(argv[4], "like")) { 04534 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04535 return RESULT_SHOWUSAGE; 04536 havepattern = 1; 04537 } else 04538 return RESULT_SHOWUSAGE; 04539 break; 04540 case 5: 04541 if (!strcasecmp(argv[3], "like")) { 04542 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04543 return RESULT_SHOWUSAGE; 04544 havepattern = 1; 04545 } else 04546 return RESULT_SHOWUSAGE; 04547 break; 04548 case 4: 04549 if (!strcasecmp(argv[3], "registered")) 04550 registeredonly = 1; 04551 else 04552 return RESULT_SHOWUSAGE; 04553 break; 04554 case 3: 04555 break; 04556 default: 04557 return RESULT_SHOWUSAGE; 04558 } 04559 04560 04561 if (s) 04562 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04563 else 04564 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04565 04566 i = ao2_iterator_init(peers, 0); 04567 for (peer = ao2_iterator_next(&i); peer; 04568 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04569 char nm[20]; 04570 char status[20]; 04571 char srch[2000]; 04572 int retstatus; 04573 04574 if (registeredonly && !peer->addr.sin_addr.s_addr) 04575 continue; 04576 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04577 continue; 04578 04579 if (!ast_strlen_zero(peer->username)) 04580 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04581 else 04582 ast_copy_string(name, peer->name, sizeof(name)); 04583 04584 retstatus = peer_status(peer, status, sizeof(status)); 04585 if (retstatus > 0) 04586 online_peers++; 04587 else if (!retstatus) 04588 offline_peers++; 04589 else 04590 unmonitored_peers++; 04591 04592 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04593 04594 snprintf(srch, sizeof(srch), FORMAT, name, 04595 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04596 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04597 nm, 04598 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04599 peer->encmethods ? "(E)" : " ", status, term); 04600 04601 if (s) 04602 astman_append(s, FORMAT, name, 04603 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04604 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04605 nm, 04606 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04607 peer->encmethods ? "(E)" : " ", status, term); 04608 else 04609 ast_cli(fd, FORMAT, name, 04610 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04611 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04612 nm, 04613 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04614 peer->encmethods ? "(E)" : " ", status, term); 04615 total_peers++; 04616 } 04617 04618 if (s) 04619 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04620 else 04621 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04622 04623 if (havepattern) 04624 regfree(®exbuf); 04625 04626 return RESULT_SUCCESS; 04627 #undef FORMAT 04628 #undef FORMAT2 04629 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 957 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00958 { 00959 struct iax2_thread *thread = NULL; 00960 static time_t lasterror; 00961 static time_t t; 00962 00963 thread = find_idle_thread(); 00964 00965 if (thread != NULL) { 00966 thread->schedfunc = func; 00967 thread->scheddata = data; 00968 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00969 #ifdef DEBUG_SCHED_MULTITHREAD 00970 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00971 #endif 00972 signal_condition(&thread->lock, &thread->cond); 00973 return 0; 00974 } 00975 time(&t); 00976 if (t != lasterror && option_debug) 00977 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00978 lasterror = t; 00979 00980 return -1; 00981 }
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 5010 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05012 { 05013 struct ast_frame f = { 0, }; 05014 05015 f.frametype = type; 05016 f.subclass = command; 05017 f.datalen = datalen; 05018 f.src = __FUNCTION__; 05019 f.data = (void *) data; 05020 05021 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05022 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1037 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxsl, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01038 { 01039 int callno = (long) data; 01040 01041 ast_mutex_lock(&iaxsl[callno]); 01042 01043 while (iaxs[callno] && iaxs[callno]->lagid > -1) { 01044 if (iaxs[callno]->peercallno) { 01045 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01046 } 01047 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01048 break; 01049 } 01050 01051 ast_mutex_unlock(&iaxsl[callno]); 01052 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 997 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxsl, sched, send_command(), and send_ping().
Referenced by send_ping().
00998 { 00999 int callno = (long) data; 01000 01001 ast_mutex_lock(&iaxsl[callno]); 01002 01003 while (iaxs[callno] && iaxs[callno]->pingid != -1) { 01004 if (iaxs[callno]->peercallno) { 01005 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01006 } 01007 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01008 break; 01009 } 01010 01011 ast_mutex_unlock(&iaxsl[callno]); 01012 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10930 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(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, netsock, outsock, peers, reload_firmware(), sched, sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10931 { 10932 struct iax2_thread *thread = NULL; 10933 int x; 10934 10935 /* Make sure threads do not hold shared resources when they are canceled */ 10936 10937 /* Grab the sched lock resource to keep it away from threads about to die */ 10938 /* Cancel the network thread, close the net socket */ 10939 if (netthreadid != AST_PTHREADT_NULL) { 10940 AST_LIST_LOCK(&iaxq.queue); 10941 ast_mutex_lock(&sched_lock); 10942 pthread_cancel(netthreadid); 10943 ast_cond_signal(&sched_cond); 10944 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10945 AST_LIST_UNLOCK(&iaxq.queue); 10946 pthread_join(netthreadid, NULL); 10947 } 10948 if (schedthreadid != AST_PTHREADT_NULL) { 10949 ast_mutex_lock(&sched_lock); 10950 pthread_cancel(schedthreadid); 10951 ast_cond_signal(&sched_cond); 10952 ast_mutex_unlock(&sched_lock); 10953 pthread_join(schedthreadid, NULL); 10954 } 10955 10956 /* Call for all threads to halt */ 10957 AST_LIST_LOCK(&idle_list); 10958 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10959 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10960 pthread_cancel(thread->threadid); 10961 } 10962 AST_LIST_TRAVERSE_SAFE_END 10963 AST_LIST_UNLOCK(&idle_list); 10964 10965 AST_LIST_LOCK(&active_list); 10966 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10967 AST_LIST_REMOVE_CURRENT(&active_list, list); 10968 pthread_cancel(thread->threadid); 10969 } 10970 AST_LIST_TRAVERSE_SAFE_END 10971 AST_LIST_UNLOCK(&active_list); 10972 10973 AST_LIST_LOCK(&dynamic_list); 10974 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10975 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10976 pthread_cancel(thread->threadid); 10977 } 10978 AST_LIST_TRAVERSE_SAFE_END 10979 AST_LIST_UNLOCK(&dynamic_list); 10980 10981 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10982 10983 /* Wait for threads to exit */ 10984 while(0 < iaxactivethreadcount) 10985 usleep(10000); 10986 10987 ast_netsock_release(netsock); 10988 ast_netsock_release(outsock); 10989 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10990 if (iaxs[x]) { 10991 iax2_destroy(x); 10992 } 10993 } 10994 ast_manager_unregister( "IAXpeers" ); 10995 ast_manager_unregister( "IAXnetstats" ); 10996 ast_unregister_application(papp); 10997 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10998 ast_unregister_switch(&iax2_switch); 10999 ast_channel_unregister(&iax2_tech); 11000 delete_users(); 11001 iax_provision_unload(); 11002 sched_context_destroy(sched); 11003 reload_firmware(1); 11004 11005 ast_mutex_destroy(&waresl.lock); 11006 11007 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11008 ast_mutex_destroy(&iaxsl[x]); 11009 } 11010 11011 ao2_ref(peers, -1); 11012 ao2_ref(users, -1); 11013 ao2_ref(iax_peercallno_pvts, -1); 11014 11015 return 0; 11016 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5063 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05064 { 05065 while(con) { 05066 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05067 return -1; 05068 con = con->next; 05069 } 05070 return 0; 05071 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4837 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, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, 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().
04838 { 04839 int x; 04840 int numchans = 0; 04841 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04842 ast_mutex_lock(&iaxsl[x]); 04843 if (iaxs[x]) { 04844 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04845 char *fmt; 04846 jb_info jbinfo; 04847 04848 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04849 jb_getinfo(iaxs[x]->jb, &jbinfo); 04850 localjitter = jbinfo.jitter; 04851 localdelay = jbinfo.current - jbinfo.min; 04852 locallost = jbinfo.frames_lost; 04853 locallosspct = jbinfo.losspct/1000; 04854 localdropped = jbinfo.frames_dropped; 04855 localooo = jbinfo.frames_ooo; 04856 } else { 04857 localjitter = -1; 04858 localdelay = 0; 04859 locallost = -1; 04860 locallosspct = -1; 04861 localdropped = 0; 04862 localooo = -1; 04863 } 04864 if (limit_fmt) 04865 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04866 else 04867 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04868 if (s) 04869 04870 astman_append(s, fmt, 04871 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04872 iaxs[x]->pingtime, 04873 localjitter, 04874 localdelay, 04875 locallost, 04876 locallosspct, 04877 localdropped, 04878 localooo, 04879 iaxs[x]->frames_received/1000, 04880 iaxs[x]->remote_rr.jitter, 04881 iaxs[x]->remote_rr.delay, 04882 iaxs[x]->remote_rr.losscnt, 04883 iaxs[x]->remote_rr.losspct, 04884 iaxs[x]->remote_rr.dropped, 04885 iaxs[x]->remote_rr.ooo, 04886 iaxs[x]->remote_rr.packets/1000); 04887 else 04888 ast_cli(fd, fmt, 04889 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04890 iaxs[x]->pingtime, 04891 localjitter, 04892 localdelay, 04893 locallost, 04894 locallosspct, 04895 localdropped, 04896 localooo, 04897 iaxs[x]->frames_received/1000, 04898 iaxs[x]->remote_rr.jitter, 04899 iaxs[x]->remote_rr.delay, 04900 iaxs[x]->remote_rr.losscnt, 04901 iaxs[x]->remote_rr.losspct, 04902 iaxs[x]->remote_rr.dropped, 04903 iaxs[x]->remote_rr.ooo, 04904 iaxs[x]->remote_rr.packets/1000 04905 ); 04906 numchans++; 04907 } 04908 ast_mutex_unlock(&iaxsl[x]); 04909 } 04910 return numchans; 04911 }
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 3715 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_channel_free(), 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, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, iax2_tech, iaxs, iaxsl, 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::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().
03716 { 03717 struct ast_channel *tmp; 03718 struct chan_iax2_pvt *i; 03719 struct ast_variable *v = NULL; 03720 03721 if (!(i = iaxs[callno])) { 03722 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03723 return NULL; 03724 } 03725 03726 /* Don't hold call lock */ 03727 ast_mutex_unlock(&iaxsl[callno]); 03728 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); 03729 ast_mutex_lock(&iaxsl[callno]); 03730 if (!iaxs[callno]) { 03731 if (tmp) { 03732 ast_channel_free(tmp); 03733 } 03734 ast_mutex_unlock(&iaxsl[callno]); 03735 return NULL; 03736 } 03737 03738 if (!tmp) 03739 return NULL; 03740 tmp->tech = &iax2_tech; 03741 /* We can support any format by default, until we get restricted */ 03742 tmp->nativeformats = capability; 03743 tmp->readformat = ast_best_codec(capability); 03744 tmp->writeformat = ast_best_codec(capability); 03745 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03746 03747 /* Don't use ast_set_callerid() here because it will 03748 * generate a NewCallerID event before the NewChannel event */ 03749 if (!ast_strlen_zero(i->ani)) 03750 tmp->cid.cid_ani = ast_strdup(i->ani); 03751 else 03752 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03753 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03754 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03755 tmp->cid.cid_pres = i->calling_pres; 03756 tmp->cid.cid_ton = i->calling_ton; 03757 tmp->cid.cid_tns = i->calling_tns; 03758 if (!ast_strlen_zero(i->language)) 03759 ast_string_field_set(tmp, language, i->language); 03760 if (!ast_strlen_zero(i->accountcode)) 03761 ast_string_field_set(tmp, accountcode, i->accountcode); 03762 if (i->amaflags) 03763 tmp->amaflags = i->amaflags; 03764 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03765 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03766 if (i->adsi) 03767 tmp->adsicpe = i->peeradsicpe; 03768 else 03769 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03770 i->owner = tmp; 03771 i->capability = capability; 03772 03773 for (v = i->vars ; v ; v = v->next) 03774 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03775 03776 if (state != AST_STATE_DOWN) { 03777 if (ast_pbx_start(tmp)) { 03778 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03779 ast_hangup(tmp); 03780 i->owner = NULL; 03781 return NULL; 03782 } 03783 } 03784 03785 ast_module_ref(ast_module_info->self); 03786 03787 return tmp; 03788 }
static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | active_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | registrations | , | |
iax2_registry | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Inter Asterisk eXchange (Ver 2)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | sched_lock | ) |
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2229 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02230 { 02231 #ifdef SCHED_MULTITHREADED 02232 if (schedule_action(__attempt_transmit, data)) 02233 #endif 02234 __attempt_transmit(data); 02235 return 0; 02236 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6372 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().
06373 { 06374 /* Schedule sending the authentication failure in one second, to prevent 06375 guessing */ 06376 if (iaxs[callno]) { 06377 iaxs[callno]->authfail = failcode; 06378 if (delayreject) { 06379 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06380 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06381 } else 06382 auth_reject((void *)(long)callno); 06383 } 06384 return 0; 06385 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6358 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().
06359 { 06360 int callno = (int)(long)(data); 06361 ast_mutex_lock(&iaxsl[callno]); 06362 if (iaxs[callno]) 06363 iaxs[callno]->authid = -1; 06364 ast_mutex_unlock(&iaxsl[callno]); 06365 #ifdef SCHED_MULTITHREADED 06366 if (schedule_action(__auth_reject, data)) 06367 #endif 06368 __auth_reject(data); 06369 return 0; 06370 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5588 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_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().
05589 { 05590 int res = -1; 05591 int x; 05592 if (!ast_strlen_zero(keyn)) { 05593 if (!(authmethods & IAX_AUTH_RSA)) { 05594 if (ast_strlen_zero(secret)) 05595 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)); 05596 } else if (ast_strlen_zero(challenge)) { 05597 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05598 } else { 05599 char sig[256]; 05600 struct ast_key *key; 05601 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05602 if (!key) { 05603 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05604 } else { 05605 if (ast_sign(key, (char*)challenge, sig)) { 05606 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05607 res = -1; 05608 } else { 05609 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05610 res = 0; 05611 } 05612 } 05613 } 05614 } 05615 /* Fall back */ 05616 if (res && !ast_strlen_zero(secret)) { 05617 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05618 struct MD5Context md5; 05619 unsigned char digest[16]; 05620 char digres[128]; 05621 MD5Init(&md5); 05622 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05623 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05624 MD5Final(digest, &md5); 05625 /* If they support md5, authenticate with it. */ 05626 for (x=0;x<16;x++) 05627 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05628 if (ecx && dcx) 05629 build_enc_keys(digest, ecx, dcx); 05630 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05631 res = 0; 05632 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05633 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05634 res = 0; 05635 } else 05636 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05637 } 05638 return res; 05639 }
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 5645 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(), peer_unref(), peers, realtime_peer(), and send_command().
Referenced by socket_process().
05646 { 05647 struct iax2_peer *peer = NULL; 05648 /* Start pessimistic */ 05649 int res = -1; 05650 int authmethods = 0; 05651 struct iax_ie_data ied; 05652 uint16_t callno = p->callno; 05653 05654 memset(&ied, 0, sizeof(ied)); 05655 05656 if (ies->username) 05657 ast_string_field_set(p, username, ies->username); 05658 if (ies->challenge) 05659 ast_string_field_set(p, challenge, ies->challenge); 05660 if (ies->authmethods) 05661 authmethods = ies->authmethods; 05662 if (authmethods & IAX_AUTH_MD5) 05663 merge_encryption(p, ies->encmethods); 05664 else 05665 p->encmethods = 0; 05666 05667 /* Check for override RSA authentication first */ 05668 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05669 /* Normal password authentication */ 05670 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05671 } else { 05672 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05673 while ((peer = ao2_iterator_next(&i))) { 05674 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05675 /* No peer specified at our end, or this is the peer */ 05676 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05677 /* No username specified in peer rule, or this is the right username */ 05678 && (!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))) 05679 /* No specified host, or this is our host */ 05680 ) { 05681 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05682 if (!res) { 05683 peer_unref(peer); 05684 break; 05685 } 05686 } 05687 peer_unref(peer); 05688 } 05689 if (!peer) { 05690 /* We checked our list and didn't find one. It's unlikely, but possible, 05691 that we're trying to authenticate *to* a realtime peer */ 05692 const char *peer_name = ast_strdupa(p->peer); 05693 ast_mutex_unlock(&iaxsl[callno]); 05694 if ((peer = realtime_peer(peer_name, NULL))) { 05695 ast_mutex_lock(&iaxsl[callno]); 05696 if (!(p = iaxs[callno])) { 05697 peer_unref(peer); 05698 return -1; 05699 } 05700 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05701 peer_unref(peer); 05702 } 05703 if (!peer) { 05704 ast_mutex_lock(&iaxsl[callno]); 05705 if (!(p = iaxs[callno])) 05706 return -1; 05707 } 05708 } 05709 } 05710 if (ies->encmethods) 05711 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05712 if (!res) 05713 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05714 return res; 05715 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5323 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, 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 users.
Referenced by socket_process().
05324 { 05325 struct iax_ie_data ied; 05326 int res = -1, authreq_restrict = 0; 05327 char challenge[10]; 05328 struct chan_iax2_pvt *p = iaxs[call_num]; 05329 05330 memset(&ied, 0, sizeof(ied)); 05331 05332 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05333 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05334 struct iax2_user *user, tmp_user = { 05335 .name = p->username, 05336 }; 05337 05338 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05339 if (user) { 05340 if (user->curauthreq == user->maxauthreq) 05341 authreq_restrict = 1; 05342 else 05343 user->curauthreq++; 05344 user = user_unref(user); 05345 } 05346 } 05347 05348 /* If the AUTHREQ limit test failed, send back an error */ 05349 if (authreq_restrict) { 05350 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05351 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05352 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05353 return 0; 05354 } 05355 05356 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05357 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05358 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05359 ast_string_field_set(p, challenge, challenge); 05360 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05361 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05362 } 05363 if (p->encmethods) 05364 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05365 05366 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05367 05368 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05369 05370 if (p->encmethods) 05371 ast_set_flag(p, IAX_ENCRYPTED); 05372 05373 return res; 05374 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5376 of file chan_iax2.c.
References ao2_find(), ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05377 { 05378 char requeststr[256]; 05379 char md5secret[256] = ""; 05380 char secret[256] = ""; 05381 char rsasecret[256] = ""; 05382 int res = -1; 05383 int x; 05384 struct iax2_user *user, tmp_user = { 05385 .name = p->username, 05386 }; 05387 05388 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05389 if (user) { 05390 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05391 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05392 ast_clear_flag(p, IAX_MAXAUTHREQ); 05393 } 05394 ast_string_field_set(p, host, user->name); 05395 user = user_unref(user); 05396 } 05397 05398 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05399 return res; 05400 if (ies->password) 05401 ast_copy_string(secret, ies->password, sizeof(secret)); 05402 if (ies->md5_result) 05403 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05404 if (ies->rsa_result) 05405 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05406 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05407 struct ast_key *key; 05408 char *keyn; 05409 char tmpkey[256]; 05410 char *stringp=NULL; 05411 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05412 stringp=tmpkey; 05413 keyn = strsep(&stringp, ":"); 05414 while(keyn) { 05415 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05416 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05417 res = 0; 05418 break; 05419 } else if (!key) 05420 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05421 keyn = strsep(&stringp, ":"); 05422 } 05423 } else if (p->authmethods & IAX_AUTH_MD5) { 05424 struct MD5Context md5; 05425 unsigned char digest[16]; 05426 char *tmppw, *stringp; 05427 05428 tmppw = ast_strdupa(p->secret); 05429 stringp = tmppw; 05430 while((tmppw = strsep(&stringp, ";"))) { 05431 MD5Init(&md5); 05432 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05433 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05434 MD5Final(digest, &md5); 05435 /* If they support md5, authenticate with it. */ 05436 for (x=0;x<16;x++) 05437 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05438 if (!strcasecmp(requeststr, md5secret)) { 05439 res = 0; 05440 break; 05441 } 05442 } 05443 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05444 if (!strcmp(secret, p->secret)) 05445 res = 0; 05446 } 05447 return res; 05448 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3116 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03117 { 03118 #ifdef SCHED_MULTITHREADED 03119 if (schedule_action(__auto_congest, data)) 03120 #endif 03121 __auto_congest(data); 03122 return 0; 03123 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6402 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().
06403 { 06404 int callno = (int)(long)(data); 06405 ast_mutex_lock(&iaxsl[callno]); 06406 if (iaxs[callno]) { 06407 iaxs[callno]->autoid = -1; 06408 } 06409 ast_mutex_unlock(&iaxsl[callno]); 06410 #ifdef SCHED_MULTITHREADED 06411 if (schedule_action(__auto_hangup, data)) 06412 #endif 06413 __auto_hangup(data); 06414 return 0; 06415 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 9126 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
09127 { 09128 struct iax2_context *con; 09129 09130 if ((con = ast_calloc(1, sizeof(*con)))) 09131 ast_copy_string(con->context, context, sizeof(con->context)); 09132 09133 return con; 09134 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4095 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04096 { 04097 aes_encrypt_key128(digest, ecx); 04098 aes_decrypt_key128(digest, dcx); 04099 }
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 9272 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_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(), cid_name, cid_num, 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, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, prefs, sched, secret, unlink_peer(), and ast_variable::value.
09273 { 09274 struct iax2_peer *peer = NULL; 09275 struct ast_ha *oldha = NULL; 09276 int maskfound=0; 09277 int found=0; 09278 int firstpass=1; 09279 struct iax2_peer tmp_peer = { 09280 .name = name, 09281 }; 09282 09283 if (!temponly) { 09284 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09285 if (peer && !ast_test_flag(peer, IAX_DELME)) 09286 firstpass = 0; 09287 } 09288 09289 if (peer) { 09290 found++; 09291 if (firstpass) { 09292 oldha = peer->ha; 09293 peer->ha = NULL; 09294 } 09295 unlink_peer(peer); 09296 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09297 peer->expire = -1; 09298 peer->pokeexpire = -1; 09299 peer->sockfd = defaultsockfd; 09300 if (ast_string_field_init(peer, 32)) 09301 peer = peer_unref(peer); 09302 } 09303 09304 if (peer) { 09305 if (firstpass) { 09306 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09307 peer->encmethods = iax2_encryption; 09308 peer->adsi = adsi; 09309 ast_string_field_set(peer,secret,""); 09310 if (!found) { 09311 ast_string_field_set(peer, name, name); 09312 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09313 peer->expiry = min_reg_expire; 09314 } 09315 peer->prefs = prefs; 09316 peer->capability = iax2_capability; 09317 peer->smoothing = 0; 09318 peer->pokefreqok = DEFAULT_FREQ_OK; 09319 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09320 ast_string_field_set(peer,context,""); 09321 ast_string_field_set(peer,peercontext,""); 09322 ast_clear_flag(peer, IAX_HASCALLERID); 09323 ast_string_field_set(peer, cid_name, ""); 09324 ast_string_field_set(peer, cid_num, ""); 09325 } 09326 09327 if (!v) { 09328 v = alt; 09329 alt = NULL; 09330 } 09331 while(v) { 09332 if (!strcasecmp(v->name, "secret")) { 09333 ast_string_field_set(peer, secret, v->value); 09334 } else if (!strcasecmp(v->name, "mailbox")) { 09335 ast_string_field_set(peer, mailbox, v->value); 09336 } else if (!strcasecmp(v->name, "mohinterpret")) { 09337 ast_string_field_set(peer, mohinterpret, v->value); 09338 } else if (!strcasecmp(v->name, "mohsuggest")) { 09339 ast_string_field_set(peer, mohsuggest, v->value); 09340 } else if (!strcasecmp(v->name, "dbsecret")) { 09341 ast_string_field_set(peer, dbsecret, v->value); 09342 } else if (!strcasecmp(v->name, "trunk")) { 09343 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09344 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09345 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09346 ast_clear_flag(peer, IAX_TRUNK); 09347 } 09348 } else if (!strcasecmp(v->name, "auth")) { 09349 peer->authmethods = get_auth_methods(v->value); 09350 } else if (!strcasecmp(v->name, "encryption")) { 09351 peer->encmethods = get_encrypt_methods(v->value); 09352 } else if (!strcasecmp(v->name, "notransfer")) { 09353 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09354 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09355 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09356 } else if (!strcasecmp(v->name, "transfer")) { 09357 if (!strcasecmp(v->value, "mediaonly")) { 09358 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09359 } else if (ast_true(v->value)) { 09360 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09361 } else 09362 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09363 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09364 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09365 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09366 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09367 } else if (!strcasecmp(v->name, "host")) { 09368 if (!strcasecmp(v->value, "dynamic")) { 09369 /* They'll register with us */ 09370 ast_set_flag(peer, IAX_DYNAMIC); 09371 if (!found) { 09372 /* Initialize stuff iff we're not found, otherwise 09373 we keep going with what we had */ 09374 memset(&peer->addr.sin_addr, 0, 4); 09375 if (peer->addr.sin_port) { 09376 /* If we've already got a port, make it the default rather than absolute */ 09377 peer->defaddr.sin_port = peer->addr.sin_port; 09378 peer->addr.sin_port = 0; 09379 } 09380 } 09381 } else { 09382 /* Non-dynamic. Make sure we become that way if we're not */ 09383 AST_SCHED_DEL(sched, peer->expire); 09384 ast_clear_flag(peer, IAX_DYNAMIC); 09385 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09386 return peer_unref(peer); 09387 if (!peer->addr.sin_port) 09388 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09389 } 09390 if (!maskfound) 09391 inet_aton("255.255.255.255", &peer->mask); 09392 } else if (!strcasecmp(v->name, "defaultip")) { 09393 if (ast_get_ip(&peer->defaddr, v->value)) 09394 return peer_unref(peer); 09395 } else if (!strcasecmp(v->name, "sourceaddress")) { 09396 peer_set_srcaddr(peer, v->value); 09397 } else if (!strcasecmp(v->name, "permit") || 09398 !strcasecmp(v->name, "deny")) { 09399 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09400 } else if (!strcasecmp(v->name, "mask")) { 09401 maskfound++; 09402 inet_aton(v->value, &peer->mask); 09403 } else if (!strcasecmp(v->name, "context")) { 09404 ast_string_field_set(peer, context, v->value); 09405 } else if (!strcasecmp(v->name, "regexten")) { 09406 ast_string_field_set(peer, regexten, v->value); 09407 } else if (!strcasecmp(v->name, "peercontext")) { 09408 ast_string_field_set(peer, peercontext, v->value); 09409 } else if (!strcasecmp(v->name, "port")) { 09410 if (ast_test_flag(peer, IAX_DYNAMIC)) 09411 peer->defaddr.sin_port = htons(atoi(v->value)); 09412 else 09413 peer->addr.sin_port = htons(atoi(v->value)); 09414 } else if (!strcasecmp(v->name, "username")) { 09415 ast_string_field_set(peer, username, v->value); 09416 } else if (!strcasecmp(v->name, "allow")) { 09417 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09418 } else if (!strcasecmp(v->name, "disallow")) { 09419 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09420 } else if (!strcasecmp(v->name, "callerid")) { 09421 if (!ast_strlen_zero(v->value)) { 09422 char name2[80]; 09423 char num2[80]; 09424 ast_callerid_split(v->value, name2, 80, num2, 80); 09425 ast_string_field_set(peer, cid_name, name2); 09426 ast_string_field_set(peer, cid_num, num2); 09427 ast_set_flag(peer, IAX_HASCALLERID); 09428 } else { 09429 ast_clear_flag(peer, IAX_HASCALLERID); 09430 ast_string_field_set(peer, cid_name, ""); 09431 ast_string_field_set(peer, cid_num, ""); 09432 } 09433 } else if (!strcasecmp(v->name, "fullname")) { 09434 if (!ast_strlen_zero(v->value)) { 09435 ast_string_field_set(peer, cid_name, v->value); 09436 ast_set_flag(peer, IAX_HASCALLERID); 09437 } else { 09438 ast_string_field_set(peer, cid_name, ""); 09439 if (ast_strlen_zero(peer->cid_num)) 09440 ast_clear_flag(peer, IAX_HASCALLERID); 09441 } 09442 } else if (!strcasecmp(v->name, "cid_number")) { 09443 if (!ast_strlen_zero(v->value)) { 09444 ast_string_field_set(peer, cid_num, v->value); 09445 ast_set_flag(peer, IAX_HASCALLERID); 09446 } else { 09447 ast_string_field_set(peer, cid_num, ""); 09448 if (ast_strlen_zero(peer->cid_name)) 09449 ast_clear_flag(peer, IAX_HASCALLERID); 09450 } 09451 } else if (!strcasecmp(v->name, "sendani")) { 09452 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09453 } else if (!strcasecmp(v->name, "inkeys")) { 09454 ast_string_field_set(peer, inkeys, v->value); 09455 } else if (!strcasecmp(v->name, "outkey")) { 09456 ast_string_field_set(peer, outkey, v->value); 09457 } else if (!strcasecmp(v->name, "qualify")) { 09458 if (!strcasecmp(v->value, "no")) { 09459 peer->maxms = 0; 09460 } else if (!strcasecmp(v->value, "yes")) { 09461 peer->maxms = DEFAULT_MAXMS; 09462 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09463 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); 09464 peer->maxms = 0; 09465 } 09466 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09467 peer->smoothing = ast_true(v->value); 09468 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09469 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09470 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); 09471 } 09472 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09473 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09474 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); 09475 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09476 } else if (!strcasecmp(v->name, "timezone")) { 09477 ast_string_field_set(peer, zonetag, v->value); 09478 } else if (!strcasecmp(v->name, "adsi")) { 09479 peer->adsi = ast_true(v->value); 09480 }/* else if (strcasecmp(v->name,"type")) */ 09481 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09482 v = v->next; 09483 if (!v) { 09484 v = alt; 09485 alt = NULL; 09486 } 09487 } 09488 if (!peer->authmethods) 09489 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09490 ast_clear_flag(peer, IAX_DELME); 09491 /* Make sure these are IPv4 addresses */ 09492 peer->addr.sin_family = AF_INET; 09493 } 09494 if (oldha) 09495 ast_free_ha(oldha); 09496 return peer; 09497 }
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 9513 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_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(), iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, 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, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_user::prefs, prefs, secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09514 { 09515 struct iax2_user *user = NULL; 09516 struct iax2_context *con, *conl = NULL; 09517 struct ast_ha *oldha = NULL; 09518 struct iax2_context *oldcon = NULL; 09519 int format; 09520 int firstpass=1; 09521 int oldcurauthreq = 0; 09522 char *varname = NULL, *varval = NULL; 09523 struct ast_variable *tmpvar = NULL; 09524 struct iax2_user tmp_user = { 09525 .name = name, 09526 }; 09527 09528 if (!temponly) { 09529 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09530 if (user && !ast_test_flag(user, IAX_DELME)) 09531 firstpass = 0; 09532 } 09533 09534 if (user) { 09535 if (firstpass) { 09536 oldcurauthreq = user->curauthreq; 09537 oldha = user->ha; 09538 oldcon = user->contexts; 09539 user->ha = NULL; 09540 user->contexts = NULL; 09541 } 09542 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09543 ao2_unlink(users, user); 09544 } else { 09545 user = ao2_alloc(sizeof(*user), user_destructor); 09546 } 09547 09548 if (user) { 09549 if (firstpass) { 09550 ast_string_field_free_memory(user); 09551 memset(user, 0, sizeof(struct iax2_user)); 09552 if (ast_string_field_init(user, 32)) { 09553 user = user_unref(user); 09554 goto cleanup; 09555 } 09556 user->maxauthreq = maxauthreq; 09557 user->curauthreq = oldcurauthreq; 09558 user->prefs = prefs; 09559 user->capability = iax2_capability; 09560 user->encmethods = iax2_encryption; 09561 user->adsi = adsi; 09562 ast_string_field_set(user, name, name); 09563 ast_string_field_set(user, language, language); 09564 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09565 ast_clear_flag(user, IAX_HASCALLERID); 09566 ast_string_field_set(user, cid_name, ""); 09567 ast_string_field_set(user, cid_num, ""); 09568 } 09569 if (!v) { 09570 v = alt; 09571 alt = NULL; 09572 } 09573 while(v) { 09574 if (!strcasecmp(v->name, "context")) { 09575 con = build_context(v->value); 09576 if (con) { 09577 if (conl) 09578 conl->next = con; 09579 else 09580 user->contexts = con; 09581 conl = con; 09582 } 09583 } else if (!strcasecmp(v->name, "permit") || 09584 !strcasecmp(v->name, "deny")) { 09585 user->ha = ast_append_ha(v->name, v->value, user->ha); 09586 } else if (!strcasecmp(v->name, "setvar")) { 09587 varname = ast_strdupa(v->value); 09588 if (varname && (varval = strchr(varname,'='))) { 09589 *varval = '\0'; 09590 varval++; 09591 if((tmpvar = ast_variable_new(varname, varval))) { 09592 tmpvar->next = user->vars; 09593 user->vars = tmpvar; 09594 } 09595 } 09596 } else if (!strcasecmp(v->name, "allow")) { 09597 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09598 } else if (!strcasecmp(v->name, "disallow")) { 09599 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09600 } else if (!strcasecmp(v->name, "trunk")) { 09601 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09602 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09603 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09604 ast_clear_flag(user, IAX_TRUNK); 09605 } 09606 } else if (!strcasecmp(v->name, "auth")) { 09607 user->authmethods = get_auth_methods(v->value); 09608 } else if (!strcasecmp(v->name, "encryption")) { 09609 user->encmethods = get_encrypt_methods(v->value); 09610 } else if (!strcasecmp(v->name, "notransfer")) { 09611 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09612 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09613 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09614 } else if (!strcasecmp(v->name, "transfer")) { 09615 if (!strcasecmp(v->value, "mediaonly")) { 09616 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09617 } else if (ast_true(v->value)) { 09618 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09619 } else 09620 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09621 } else if (!strcasecmp(v->name, "codecpriority")) { 09622 if(!strcasecmp(v->value, "caller")) 09623 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09624 else if(!strcasecmp(v->value, "disabled")) 09625 ast_set_flag(user, IAX_CODEC_NOPREFS); 09626 else if(!strcasecmp(v->value, "reqonly")) { 09627 ast_set_flag(user, IAX_CODEC_NOCAP); 09628 ast_set_flag(user, IAX_CODEC_NOPREFS); 09629 } 09630 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09631 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09632 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09633 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09634 } else if (!strcasecmp(v->name, "dbsecret")) { 09635 ast_string_field_set(user, dbsecret, v->value); 09636 } else if (!strcasecmp(v->name, "secret")) { 09637 if (!ast_strlen_zero(user->secret)) { 09638 char *old = ast_strdupa(user->secret); 09639 09640 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09641 } else 09642 ast_string_field_set(user, secret, v->value); 09643 } else if (!strcasecmp(v->name, "callerid")) { 09644 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09645 char name2[80]; 09646 char num2[80]; 09647 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09648 ast_string_field_set(user, cid_name, name2); 09649 ast_string_field_set(user, cid_num, num2); 09650 ast_set_flag(user, IAX_HASCALLERID); 09651 } else { 09652 ast_clear_flag(user, IAX_HASCALLERID); 09653 ast_string_field_set(user, cid_name, ""); 09654 ast_string_field_set(user, cid_num, ""); 09655 } 09656 } else if (!strcasecmp(v->name, "fullname")) { 09657 if (!ast_strlen_zero(v->value)) { 09658 ast_string_field_set(user, cid_name, v->value); 09659 ast_set_flag(user, IAX_HASCALLERID); 09660 } else { 09661 ast_string_field_set(user, cid_name, ""); 09662 if (ast_strlen_zero(user->cid_num)) 09663 ast_clear_flag(user, IAX_HASCALLERID); 09664 } 09665 } else if (!strcasecmp(v->name, "cid_number")) { 09666 if (!ast_strlen_zero(v->value)) { 09667 ast_string_field_set(user, cid_num, v->value); 09668 ast_set_flag(user, IAX_HASCALLERID); 09669 } else { 09670 ast_string_field_set(user, cid_num, ""); 09671 if (ast_strlen_zero(user->cid_name)) 09672 ast_clear_flag(user, IAX_HASCALLERID); 09673 } 09674 } else if (!strcasecmp(v->name, "accountcode")) { 09675 ast_string_field_set(user, accountcode, v->value); 09676 } else if (!strcasecmp(v->name, "mohinterpret")) { 09677 ast_string_field_set(user, mohinterpret, v->value); 09678 } else if (!strcasecmp(v->name, "mohsuggest")) { 09679 ast_string_field_set(user, mohsuggest, v->value); 09680 } else if (!strcasecmp(v->name, "language")) { 09681 ast_string_field_set(user, language, v->value); 09682 } else if (!strcasecmp(v->name, "amaflags")) { 09683 format = ast_cdr_amaflags2int(v->value); 09684 if (format < 0) { 09685 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09686 } else { 09687 user->amaflags = format; 09688 } 09689 } else if (!strcasecmp(v->name, "inkeys")) { 09690 ast_string_field_set(user, inkeys, v->value); 09691 } else if (!strcasecmp(v->name, "maxauthreq")) { 09692 user->maxauthreq = atoi(v->value); 09693 if (user->maxauthreq < 0) 09694 user->maxauthreq = 0; 09695 } else if (!strcasecmp(v->name, "adsi")) { 09696 user->adsi = ast_true(v->value); 09697 }/* else if (strcasecmp(v->name,"type")) */ 09698 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09699 v = v->next; 09700 if (!v) { 09701 v = alt; 09702 alt = NULL; 09703 } 09704 } 09705 if (!user->authmethods) { 09706 if (!ast_strlen_zero(user->secret)) { 09707 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09708 if (!ast_strlen_zero(user->inkeys)) 09709 user->authmethods |= IAX_AUTH_RSA; 09710 } else if (!ast_strlen_zero(user->inkeys)) { 09711 user->authmethods = IAX_AUTH_RSA; 09712 } else { 09713 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09714 } 09715 } 09716 ast_clear_flag(user, IAX_DELME); 09717 } 09718 cleanup: 09719 if (oldha) 09720 ast_free_ha(oldha); 09721 if (oldcon) 09722 free_context(oldcon); 09723 return user; 09724 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10227 of file chan_iax2.c.
References 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().
10228 { 10229 struct sockaddr_in sin; 10230 int x; 10231 int callno; 10232 struct iax_ie_data ied; 10233 struct create_addr_info cai; 10234 struct parsed_dial_string pds; 10235 char *tmpstr; 10236 10237 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10238 /* Look for an *exact match* call. Once a call is negotiated, it can only 10239 look up entries for a single context */ 10240 if (!ast_mutex_trylock(&iaxsl[x])) { 10241 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10242 return x; 10243 ast_mutex_unlock(&iaxsl[x]); 10244 } 10245 } 10246 10247 /* No match found, we need to create a new one */ 10248 10249 memset(&cai, 0, sizeof(cai)); 10250 memset(&ied, 0, sizeof(ied)); 10251 memset(&pds, 0, sizeof(pds)); 10252 10253 tmpstr = ast_strdupa(data); 10254 parse_dial_string(tmpstr, &pds); 10255 10256 if (ast_strlen_zero(pds.peer)) { 10257 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10258 return -1; 10259 } 10260 10261 /* Populate our address from the given */ 10262 if (create_addr(pds.peer, NULL, &sin, &cai)) 10263 return -1; 10264 10265 if (option_debug) 10266 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10267 pds.peer, pds.username, pds.password, pds.context); 10268 10269 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10270 if (callno < 1) { 10271 ast_log(LOG_WARNING, "Unable to create call\n"); 10272 return -1; 10273 } 10274 10275 ast_string_field_set(iaxs[callno], dproot, data); 10276 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10277 10278 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10279 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10280 /* the string format is slightly different from a standard dial string, 10281 because the context appears in the 'exten' position 10282 */ 10283 if (pds.exten) 10284 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10285 if (pds.username) 10286 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10287 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10288 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10289 /* Keep password handy */ 10290 if (pds.password) 10291 ast_string_field_set(iaxs[callno], secret, pds.password); 10292 if (pds.key) 10293 ast_string_field_set(iaxs[callno], outkey, pds.key); 10294 /* Start the call going */ 10295 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10296 10297 return callno; 10298 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3963 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03964 { 03965 /* Returns where in "receive time" we are. That is, how many ms 03966 since we received (or would have received) the frame with timestamp 0 */ 03967 int ms; 03968 #ifdef IAXTESTS 03969 int jit; 03970 #endif /* IAXTESTS */ 03971 /* Setup rxcore if necessary */ 03972 if (ast_tvzero(p->rxcore)) { 03973 p->rxcore = ast_tvnow(); 03974 if (option_debug && iaxdebug) 03975 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03976 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03977 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03978 #if 1 03979 if (option_debug && iaxdebug) 03980 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03981 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03982 #endif 03983 } 03984 03985 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03986 #ifdef IAXTESTS 03987 if (test_jit) { 03988 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03989 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03990 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03991 jit = -jit; 03992 ms += jit; 03993 } 03994 } 03995 if (test_late) { 03996 ms += test_late; 03997 test_late = 0; 03998 } 03999 #endif /* IAXTESTS */ 04000 return ms; 04001 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3834 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), 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, option_debug, and chan_iax2_pvt::peercallno.
Referenced by iax2_send(), and socket_process().
03835 { 03836 int ms; 03837 int voice = 0; 03838 int genuine = 0; 03839 int adjust; 03840 struct timeval *delivery = NULL; 03841 03842 03843 /* What sort of frame do we have?: voice is self-explanatory 03844 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03845 non-genuine frames are CONTROL frames [ringing etc], DTMF 03846 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03847 the others need a timestamp slaved to the voice frames so that they go in sequence 03848 */ 03849 if (f) { 03850 if (f->frametype == AST_FRAME_VOICE) { 03851 voice = 1; 03852 delivery = &f->delivery; 03853 } else if (f->frametype == AST_FRAME_IAX) { 03854 genuine = 1; 03855 } else if (f->frametype == AST_FRAME_CNG) { 03856 p->notsilenttx = 0; 03857 } 03858 } 03859 if (ast_tvzero(p->offset)) { 03860 gettimeofday(&p->offset, NULL); 03861 /* Round to nearest 20ms for nice looking traces */ 03862 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03863 } 03864 /* If the timestamp is specified, just send it as is */ 03865 if (ts) 03866 return ts; 03867 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03868 if (delivery && !ast_tvzero(*delivery)) { 03869 ms = ast_tvdiff_ms(*delivery, p->offset); 03870 if (option_debug > 2 && iaxdebug) 03871 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03872 } else { 03873 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03874 if (ms < 0) 03875 ms = 0; 03876 if (voice) { 03877 /* On a voice frame, use predicted values if appropriate */ 03878 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03879 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03880 /* AN EXPLANATION: 03881 When we send voice, we usually send "calculated" timestamps worked out 03882 on the basis of the number of samples sent. When we send other frames, 03883 we usually send timestamps worked out from the real clock. 03884 The problem is that they can tend to drift out of step because the 03885 source channel's clock and our clock may not be exactly at the same rate. 03886 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03887 for this call. Moving it adjusts timestamps for non-voice frames. 03888 We make the adjustment in the style of a moving average. Each time we 03889 adjust p->offset by 10% of the difference between our clock-derived 03890 timestamp and the predicted timestamp. That's why you see "10000" 03891 below even though IAX2 timestamps are in milliseconds. 03892 The use of a moving average avoids offset moving too radically. 03893 Generally, "adjust" roams back and forth around 0, with offset hardly 03894 changing at all. But if a consistent different starts to develop it 03895 will be eliminated over the course of 10 frames (200-300msecs) 03896 */ 03897 adjust = (ms - p->nextpred); 03898 if (adjust < 0) 03899 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03900 else if (adjust > 0) 03901 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03902 03903 if (!p->nextpred) { 03904 p->nextpred = ms; /*f->samples / 8;*/ 03905 if (p->nextpred <= p->lastsent) 03906 p->nextpred = p->lastsent + 3; 03907 } 03908 ms = p->nextpred; 03909 } else { 03910 /* in this case, just use the actual 03911 * time, since we're either way off 03912 * (shouldn't happen), or we're ending a 03913 * silent period -- and seed the next 03914 * predicted time. Also, round ms to the 03915 * next multiple of frame size (so our 03916 * silent periods are multiples of 03917 * frame size too) */ 03918 03919 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03920 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03921 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03922 03923 if (f->samples >= 8) /* check to make sure we dont core dump */ 03924 { 03925 int diff = ms % (f->samples / 8); 03926 if (diff) 03927 ms += f->samples/8 - diff; 03928 } 03929 03930 p->nextpred = ms; 03931 p->notsilenttx = 1; 03932 } 03933 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03934 /* 03935 * IAX2 draft 03 says that timestamps MUST be in order. 03936 * It does not say anything about several frames having the same timestamp 03937 * When transporting video, we can have a frame that spans multiple iax packets 03938 * (so called slices), so it would make sense to use the same timestamp for all of 03939 * them 03940 * We do want to make sure that frames don't go backwards though 03941 */ 03942 if ( (unsigned int)ms < p->lastsent ) 03943 ms = p->lastsent; 03944 } else { 03945 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03946 it's a genuine frame */ 03947 if (genuine) { 03948 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03949 if (ms <= p->lastsent) 03950 ms = p->lastsent + 3; 03951 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03952 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03953 ms = p->lastsent + 3; 03954 } 03955 } 03956 } 03957 p->lastsent = ms; 03958 if (voice) 03959 p->nextpred = p->nextpred + f->samples / 8; 03960 return ms; 03961 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3790 of file chan_iax2.c.
References iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
03791 { 03792 unsigned long int mssincetx; /* unsigned to handle overflows */ 03793 long int ms, pred; 03794 03795 tpeer->trunkact = *tv; 03796 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03797 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03798 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03799 tpeer->txtrunktime = *tv; 03800 tpeer->lastsent = 999999; 03801 } 03802 /* Update last transmit time now */ 03803 tpeer->lasttxtime = *tv; 03804 03805 /* Calculate ms offset */ 03806 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03807 /* Predict from last value */ 03808 pred = tpeer->lastsent + sampms; 03809 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03810 ms = pred; 03811 03812 /* We never send the same timestamp twice, so fudge a little if we must */ 03813 if (ms == tpeer->lastsent) 03814 ms = tpeer->lastsent + 1; 03815 tpeer->lastsent = ms; 03816 return ms; 03817 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5074 of file chan_iax2.c.
References 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::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, cid_name, cid_num, iax2_context::context, iax2_user::contexts, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax2_user::ha, iax2_getpeertrunk(), 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, LOG_WARNING, iax2_user::maxauthreq, ast_variable::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, user_unref(), users, ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
05075 { 05076 /* Start pessimistic */ 05077 int res = -1; 05078 int version = 2; 05079 struct iax2_user *user = NULL, *best = NULL; 05080 int bestscore = 0; 05081 int gotcapability = 0; 05082 struct ast_variable *v = NULL, *tmpvar = NULL; 05083 struct ao2_iterator i; 05084 05085 if (!iaxs[callno]) 05086 return res; 05087 if (ies->called_number) 05088 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05089 if (ies->calling_number) { 05090 ast_shrink_phone_number(ies->calling_number); 05091 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05092 } 05093 if (ies->calling_name) 05094 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05095 if (ies->calling_ani) 05096 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05097 if (ies->dnid) 05098 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05099 if (ies->rdnis) 05100 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05101 if (ies->called_context) 05102 ast_string_field_set(iaxs[callno], context, ies->called_context); 05103 if (ies->language) 05104 ast_string_field_set(iaxs[callno], language, ies->language); 05105 if (ies->username) 05106 ast_string_field_set(iaxs[callno], username, ies->username); 05107 if (ies->calling_ton > -1) 05108 iaxs[callno]->calling_ton = ies->calling_ton; 05109 if (ies->calling_tns > -1) 05110 iaxs[callno]->calling_tns = ies->calling_tns; 05111 if (ies->calling_pres > -1) 05112 iaxs[callno]->calling_pres = ies->calling_pres; 05113 if (ies->format) 05114 iaxs[callno]->peerformat = ies->format; 05115 if (ies->adsicpe) 05116 iaxs[callno]->peeradsicpe = ies->adsicpe; 05117 if (ies->capability) { 05118 gotcapability = 1; 05119 iaxs[callno]->peercapability = ies->capability; 05120 } 05121 if (ies->version) 05122 version = ies->version; 05123 05124 /* Use provided preferences until told otherwise for actual preferences */ 05125 if(ies->codec_prefs) { 05126 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05127 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05128 } 05129 05130 if (!gotcapability) 05131 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05132 if (version > IAX_PROTO_VERSION) { 05133 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05134 ast_inet_ntoa(sin->sin_addr), version); 05135 return res; 05136 } 05137 /* Search the userlist for a compatible entry, and fill in the rest */ 05138 i = ao2_iterator_init(users, 0); 05139 while ((user = ao2_iterator_next(&i))) { 05140 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05141 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05142 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05143 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05144 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05145 if (!ast_strlen_zero(iaxs[callno]->username)) { 05146 /* Exact match, stop right now. */ 05147 if (best) 05148 user_unref(best); 05149 best = user; 05150 break; 05151 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05152 /* No required authentication */ 05153 if (user->ha) { 05154 /* There was host authentication and we passed, bonus! */ 05155 if (bestscore < 4) { 05156 bestscore = 4; 05157 if (best) 05158 user_unref(best); 05159 best = user; 05160 continue; 05161 } 05162 } else { 05163 /* No host access, but no secret, either, not bad */ 05164 if (bestscore < 3) { 05165 bestscore = 3; 05166 if (best) 05167 user_unref(best); 05168 best = user; 05169 continue; 05170 } 05171 } 05172 } else { 05173 if (user->ha) { 05174 /* Authentication, but host access too, eh, it's something.. */ 05175 if (bestscore < 2) { 05176 bestscore = 2; 05177 if (best) 05178 user_unref(best); 05179 best = user; 05180 continue; 05181 } 05182 } else { 05183 /* Authentication and no host access... This is our baseline */ 05184 if (bestscore < 1) { 05185 bestscore = 1; 05186 if (best) 05187 user_unref(best); 05188 best = user; 05189 continue; 05190 } 05191 } 05192 } 05193 } 05194 user_unref(user); 05195 } 05196 user = best; 05197 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05198 user = realtime_user(iaxs[callno]->username, sin); 05199 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05200 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05201 user = user_unref(user); 05202 } 05203 } 05204 if (user) { 05205 /* We found our match (use the first) */ 05206 /* copy vars */ 05207 for (v = user->vars ; v ; v = v->next) { 05208 if((tmpvar = ast_variable_new(v->name, v->value))) { 05209 tmpvar->next = iaxs[callno]->vars; 05210 iaxs[callno]->vars = tmpvar; 05211 } 05212 } 05213 /* If a max AUTHREQ restriction is in place, activate it */ 05214 if (user->maxauthreq > 0) 05215 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05216 iaxs[callno]->prefs = user->prefs; 05217 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05218 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05219 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05220 iaxs[callno]->encmethods = user->encmethods; 05221 /* Store the requested username if not specified */ 05222 if (ast_strlen_zero(iaxs[callno]->username)) 05223 ast_string_field_set(iaxs[callno], username, user->name); 05224 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05225 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05226 iaxs[callno]->capability = user->capability; 05227 /* And use the default context */ 05228 if (ast_strlen_zero(iaxs[callno]->context)) { 05229 if (user->contexts) 05230 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05231 else 05232 ast_string_field_set(iaxs[callno], context, context); 05233 } 05234 /* And any input keys */ 05235 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05236 /* And the permitted authentication methods */ 05237 iaxs[callno]->authmethods = user->authmethods; 05238 iaxs[callno]->adsi = user->adsi; 05239 /* If they have callerid, override the given caller id. Always store the ANI */ 05240 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05241 if (ast_test_flag(user, IAX_HASCALLERID)) { 05242 iaxs[callno]->calling_tns = 0; 05243 iaxs[callno]->calling_ton = 0; 05244 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05245 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05246 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05247 } 05248 if (ast_strlen_zero(iaxs[callno]->ani)) 05249 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05250 } else { 05251 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05252 } 05253 if (!ast_strlen_zero(user->accountcode)) 05254 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05255 if (!ast_strlen_zero(user->mohinterpret)) 05256 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05257 if (!ast_strlen_zero(user->mohsuggest)) 05258 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05259 if (user->amaflags) 05260 iaxs[callno]->amaflags = user->amaflags; 05261 if (!ast_strlen_zero(user->language)) 05262 ast_string_field_set(iaxs[callno], language, user->language); 05263 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05264 /* Keep this check last */ 05265 if (!ast_strlen_zero(user->dbsecret)) { 05266 char *family, *key=NULL; 05267 char buf[80]; 05268 family = ast_strdupa(user->dbsecret); 05269 key = strchr(family, '/'); 05270 if (key) { 05271 *key = '\0'; 05272 key++; 05273 } 05274 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05275 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05276 else 05277 ast_string_field_set(iaxs[callno], secret, buf); 05278 } else 05279 ast_string_field_set(iaxs[callno], secret, user->secret); 05280 res = 0; 05281 user = user_unref(user); 05282 } 05283 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05284 return res; 05285 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6760 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06761 { 06762 unsigned int ourver; 06763 char rsi[80]; 06764 snprintf(rsi, sizeof(rsi), "si-%s", si); 06765 if (iax_provision_version(&ourver, rsi, 1)) 06766 return 0; 06767 if (option_debug) 06768 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06769 if (ourver != ver) 06770 iax2_provision(sin, sockfd, NULL, rsi, 1); 06771 return 0; 06772 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9152 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09153 { 09154 int sd; 09155 int res; 09156 09157 sd = socket(AF_INET, SOCK_DGRAM, 0); 09158 if (sd < 0) { 09159 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09160 return -1; 09161 } 09162 09163 res = bind(sd, sa, salen); 09164 if (res < 0) { 09165 if (option_debug) 09166 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09167 close(sd); 09168 return 1; 09169 } 09170 09171 close(sd); 09172 return 0; 09173 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5764 of file chan_iax2.c.
References 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, chan_iax2_pvt::dpentries, 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, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
05765 { 05766 char exten[256] = ""; 05767 int status = CACHE_FLAG_UNKNOWN; 05768 int expiry = iaxdefaultdpcache; 05769 int x; 05770 int matchmore = 0; 05771 struct iax2_dpcache *dp, *prev; 05772 05773 if (ies->called_number) 05774 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05775 05776 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05777 status = CACHE_FLAG_EXISTS; 05778 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05779 status = CACHE_FLAG_CANEXIST; 05780 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05781 status = CACHE_FLAG_NONEXISTENT; 05782 05783 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05784 /* Don't really do anything with this */ 05785 } 05786 if (ies->refresh) 05787 expiry = ies->refresh; 05788 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05789 matchmore = CACHE_FLAG_MATCHMORE; 05790 ast_mutex_lock(&dpcache_lock); 05791 prev = NULL; 05792 dp = pvt->dpentries; 05793 while(dp) { 05794 if (!strcmp(dp->exten, exten)) { 05795 /* Let them go */ 05796 if (prev) 05797 prev->peer = dp->peer; 05798 else 05799 pvt->dpentries = dp->peer; 05800 dp->peer = NULL; 05801 dp->callno = 0; 05802 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05803 if (dp->flags & CACHE_FLAG_PENDING) { 05804 dp->flags &= ~CACHE_FLAG_PENDING; 05805 dp->flags |= status; 05806 dp->flags |= matchmore; 05807 } 05808 /* Wake up waiters */ 05809 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05810 if (dp->waiters[x] > -1) 05811 write(dp->waiters[x], "asdf", 4); 05812 } 05813 prev = dp; 05814 dp = dp->peer; 05815 } 05816 ast_mutex_unlock(&dpcache_lock); 05817 return 0; 05818 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2391 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02392 { 02393 int which = 0; 02394 struct iax2_peer *peer; 02395 char *res = NULL; 02396 int wordlen = strlen(word); 02397 struct ao2_iterator i; 02398 02399 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02400 if (pos != 3) 02401 return NULL; 02402 02403 i = ao2_iterator_init(peers, 0); 02404 while ((peer = ao2_iterator_next(&i))) { 02405 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02406 res = ast_strdup(peer->name); 02407 peer_unref(peer); 02408 break; 02409 } 02410 peer_unref(peer); 02411 } 02412 02413 return res; 02414 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5820 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, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, remove_by_peercallno(), 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().
05821 { 05822 int peercallno = 0; 05823 struct chan_iax2_pvt *pvt = iaxs[callno]; 05824 struct iax_frame *cur; 05825 jb_frame frame; 05826 05827 if (ies->callno) 05828 peercallno = ies->callno; 05829 05830 if (peercallno < 1) { 05831 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05832 return -1; 05833 } 05834 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05835 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05836 /* Reset sequence numbers */ 05837 pvt->oseqno = 0; 05838 pvt->rseqno = 0; 05839 pvt->iseqno = 0; 05840 pvt->aseqno = 0; 05841 05842 if (pvt->peercallno) { 05843 remove_by_peercallno(pvt); 05844 } 05845 pvt->peercallno = peercallno; 05846 store_by_peercallno(pvt); 05847 05848 pvt->transferring = TRANSFER_NONE; 05849 pvt->svoiceformat = -1; 05850 pvt->voiceformat = 0; 05851 pvt->svideoformat = -1; 05852 pvt->videoformat = 0; 05853 pvt->transfercallno = -1; 05854 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05855 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05856 /* reset jitterbuffer */ 05857 while(jb_getall(pvt->jb,&frame) == JB_OK) 05858 iax2_frame_free(frame.data); 05859 jb_reset(pvt->jb); 05860 pvt->lag = 0; 05861 pvt->last = 0; 05862 pvt->lastsent = 0; 05863 pvt->nextpred = 0; 05864 pvt->pingtime = DEFAULT_RETRY_TIME; 05865 AST_LIST_LOCK(&iaxq.queue); 05866 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05867 /* We must cancel any packets that would have been transmitted 05868 because now we're talking to someone new. It's okay, they 05869 were transmitted to someone that didn't care anyway. */ 05870 if (callno == cur->callno) 05871 cur->retries = -1; 05872 } 05873 AST_LIST_UNLOCK(&iaxq.queue); 05874 return 0; 05875 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1063 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), and raw_hangup().
01064 { 01065 int x; 01066 int power=-1; 01067 /* If it's 128 or smaller, just return it */ 01068 if (subclass < IAX_FLAG_SC_LOG) 01069 return subclass; 01070 /* Otherwise find its power */ 01071 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01072 if (subclass & (1 << x)) { 01073 if (power > -1) { 01074 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01075 return 0; 01076 } else 01077 power = x; 01078 } 01079 } 01080 return power | IAX_FLAG_SC_LOG; 01081 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6774 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().
06775 { 06776 jb_info stats; 06777 jb_getinfo(pvt->jb, &stats); 06778 06779 memset(iep, 0, sizeof(*iep)); 06780 06781 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06782 if(stats.frames_in == 0) stats.frames_in = 1; 06783 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06784 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06785 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06786 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06787 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06788 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3008 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_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, 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, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
03009 { 03010 struct ast_hostent ahp; 03011 struct hostent *hp; 03012 struct iax2_peer *peer; 03013 int res = -1; 03014 struct ast_codec_pref ourprefs; 03015 03016 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03017 cai->sockfd = defaultsockfd; 03018 cai->maxtime = 0; 03019 sin->sin_family = AF_INET; 03020 03021 if (!(peer = find_peer(peername, 1))) { 03022 cai->found = 0; 03023 03024 hp = ast_gethostbyname(peername, &ahp); 03025 if (hp) { 03026 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03027 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03028 /* use global iax prefs for unknown peer/user */ 03029 /* But move the calling channel's native codec to the top of the preference list */ 03030 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03031 if (c) 03032 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03033 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03034 return 0; 03035 } else { 03036 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03037 return -1; 03038 } 03039 } 03040 03041 cai->found = 1; 03042 03043 /* if the peer has no address (current or default), return failure */ 03044 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03045 goto return_unref; 03046 03047 /* if the peer is being monitored and is currently unreachable, return failure */ 03048 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03049 goto return_unref; 03050 03051 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03052 cai->maxtime = peer->maxms; 03053 cai->capability = peer->capability; 03054 cai->encmethods = peer->encmethods; 03055 cai->sockfd = peer->sockfd; 03056 cai->adsi = peer->adsi; 03057 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03058 /* Move the calling channel's native codec to the top of the preference list */ 03059 if (c) { 03060 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03061 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03062 } 03063 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03064 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03065 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03066 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03067 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03068 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03069 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03070 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03071 if (ast_strlen_zero(peer->dbsecret)) { 03072 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03073 } else { 03074 char *family; 03075 char *key = NULL; 03076 03077 family = ast_strdupa(peer->dbsecret); 03078 key = strchr(family, '/'); 03079 if (key) 03080 *key++ = '\0'; 03081 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03082 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03083 goto return_unref; 03084 } 03085 } 03086 03087 if (peer->addr.sin_addr.s_addr) { 03088 sin->sin_addr = peer->addr.sin_addr; 03089 sin->sin_port = peer->addr.sin_port; 03090 } else { 03091 sin->sin_addr = peer->defaddr.sin_addr; 03092 sin->sin_port = peer->defaddr.sin_port; 03093 } 03094 03095 res = 0; 03096 03097 return_unref: 03098 peer_unref(peer); 03099 03100 return res; 03101 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4149 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().
04150 { 04151 int padding; 04152 unsigned char *workspace; 04153 04154 workspace = alloca(*datalen); 04155 memset(f, 0, sizeof(*f)); 04156 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04157 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04158 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04159 return -1; 04160 /* Decrypt */ 04161 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04162 04163 padding = 16 + (workspace[15] & 0xf); 04164 if (option_debug && iaxdebug) 04165 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04166 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04167 return -1; 04168 04169 *datalen -= padding; 04170 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04171 f->frametype = fh->type; 04172 if (f->frametype == AST_FRAME_VIDEO) { 04173 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04174 } else { 04175 f->subclass = uncompress_subclass(fh->csub); 04176 } 04177 } else { 04178 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04179 if (option_debug && iaxdebug) 04180 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04181 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04182 return -1; 04183 /* Decrypt */ 04184 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04185 padding = 16 + (workspace[15] & 0x0f); 04186 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04187 return -1; 04188 *datalen -= padding; 04189 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04190 } 04191 return 0; 04192 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4235 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
04236 { 04237 int res=-1; 04238 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04239 /* Search for possible keys, given secrets */ 04240 struct MD5Context md5; 04241 unsigned char digest[16]; 04242 char *tmppw, *stringp; 04243 04244 tmppw = ast_strdupa(iaxs[callno]->secret); 04245 stringp = tmppw; 04246 while ((tmppw = strsep(&stringp, ";"))) { 04247 MD5Init(&md5); 04248 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04249 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04250 MD5Final(digest, &md5); 04251 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04252 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04253 if (!res) { 04254 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04255 break; 04256 } 04257 } 04258 } else 04259 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04260 return res; 04261 }
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 6836 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(), and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
06837 { 06838 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06839 struct ast_iax2_full_hdr *fh, *cur_fh; 06840 06841 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06842 return; 06843 06844 pkt_buf->len = from_here->buf_len; 06845 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06846 06847 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06848 ast_mutex_lock(&to_here->lock); 06849 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06850 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06851 if (fh->oseqno < cur_fh->oseqno) { 06852 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06853 break; 06854 } 06855 } 06856 AST_LIST_TRAVERSE_SAFE_END 06857 06858 if (!cur_pkt_buf) 06859 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06860 06861 ast_mutex_unlock(&to_here->lock); 06862 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9744 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::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
09745 { 09746 struct iax2_registry *reg; 09747 09748 ao2_callback(users, 0, user_delme_cb, NULL); 09749 09750 AST_LIST_LOCK(®istrations); 09751 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09752 ast_sched_del(sched, reg->expire); 09753 if (reg->callno) { 09754 ast_mutex_lock(&iaxsl[reg->callno]); 09755 if (iaxs[reg->callno]) { 09756 iaxs[reg->callno]->reg = NULL; 09757 iax2_destroy(reg->callno); 09758 } 09759 ast_mutex_unlock(&iaxsl[reg->callno]); 09760 } 09761 if (reg->dnsmgr) 09762 ast_dnsmgr_release(reg->dnsmgr); 09763 free(reg); 09764 } 09765 AST_LIST_UNLOCK(®istrations); 09766 09767 ao2_callback(peers, 0, peer_delme_cb, NULL); 09768 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1742 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01743 { 01744 /* Close firmware */ 01745 if (cur->fwh) { 01746 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01747 } 01748 close(cur->fd); 01749 free(cur); 01750 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6608 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().
06609 { 06610 unsigned short dpstatus = 0; 06611 struct iax_ie_data ied1; 06612 int mm; 06613 06614 memset(&ied1, 0, sizeof(ied1)); 06615 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06616 /* Must be started */ 06617 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06618 dpstatus = IAX_DPSTATUS_EXISTS; 06619 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06620 dpstatus = IAX_DPSTATUS_CANEXIST; 06621 } else { 06622 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06623 } 06624 if (ast_ignore_pattern(context, callednum)) 06625 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06626 if (mm) 06627 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06628 if (!skiplock) 06629 ast_mutex_lock(&iaxsl[callno]); 06630 if (iaxs[callno]) { 06631 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06632 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06633 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06634 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06635 } 06636 if (!skiplock) 06637 ast_mutex_unlock(&iaxsl[callno]); 06638 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6640 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().
06641 { 06642 /* Look up for dpreq */ 06643 struct dpreq_data *dpr = data; 06644 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06645 if (dpr->callerid) 06646 free(dpr->callerid); 06647 free(dpr); 06648 return NULL; 06649 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4194 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().
04195 { 04196 int padding; 04197 unsigned char *workspace; 04198 workspace = alloca(*datalen + 32); 04199 if (!workspace) 04200 return -1; 04201 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04202 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04203 if (option_debug && iaxdebug) 04204 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04205 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04206 padding = 16 + (padding & 0xf); 04207 memcpy(workspace, poo, padding); 04208 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04209 workspace[15] &= 0xf0; 04210 workspace[15] |= (padding & 0xf); 04211 if (option_debug && iaxdebug) 04212 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]); 04213 *datalen += padding; 04214 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04215 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04216 memcpy(poo, workspace + *datalen - 32, 32); 04217 } else { 04218 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04219 if (option_debug && iaxdebug) 04220 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04221 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04222 padding = 16 + (padding & 0xf); 04223 memcpy(workspace, poo, padding); 04224 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04225 workspace[15] &= 0xf0; 04226 workspace[15] |= (padding & 0x0f); 04227 *datalen += padding; 04228 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04229 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04230 memcpy(poo, workspace + *datalen - 32, 32); 04231 } 04232 return 0; 04233 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6057 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
06058 { 06059 #ifdef SCHED_MULTITHREADED 06060 if (schedule_action(__expire_registry, data)) 06061 #endif 06062 __expire_registry(data); 06063 return 0; 06064 }
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 10300 of file chan_iax2.c.
References ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, chan_iax2_pvt::dpentries, 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().
10301 { 10302 struct iax2_dpcache *dp, *prev = NULL, *next; 10303 struct timeval tv; 10304 int x; 10305 int com[2]; 10306 int timeout; 10307 int old=0; 10308 int outfd; 10309 int abort; 10310 int callno; 10311 struct ast_channel *c; 10312 struct ast_frame *f; 10313 gettimeofday(&tv, NULL); 10314 dp = dpcache; 10315 while(dp) { 10316 next = dp->next; 10317 /* Expire old caches */ 10318 if (ast_tvcmp(tv, dp->expiry) > 0) { 10319 /* It's expired, let it disappear */ 10320 if (prev) 10321 prev->next = dp->next; 10322 else 10323 dpcache = dp->next; 10324 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10325 /* Free memory and go again */ 10326 free(dp); 10327 } else { 10328 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); 10329 } 10330 dp = next; 10331 continue; 10332 } 10333 /* We found an entry that matches us! */ 10334 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10335 break; 10336 prev = dp; 10337 dp = next; 10338 } 10339 if (!dp) { 10340 /* No matching entry. Create a new one. */ 10341 /* First, can we make a callno? */ 10342 callno = cache_get_callno_locked(data); 10343 if (callno < 0) { 10344 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10345 return NULL; 10346 } 10347 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10348 ast_mutex_unlock(&iaxsl[callno]); 10349 return NULL; 10350 } 10351 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10352 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10353 gettimeofday(&dp->expiry, NULL); 10354 dp->orig = dp->expiry; 10355 /* Expires in 30 mins by default */ 10356 dp->expiry.tv_sec += iaxdefaultdpcache; 10357 dp->next = dpcache; 10358 dp->flags = CACHE_FLAG_PENDING; 10359 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10360 dp->waiters[x] = -1; 10361 dpcache = dp; 10362 dp->peer = iaxs[callno]->dpentries; 10363 iaxs[callno]->dpentries = dp; 10364 /* Send the request if we're already up */ 10365 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10366 iax2_dprequest(dp, callno); 10367 ast_mutex_unlock(&iaxsl[callno]); 10368 } 10369 /* By here we must have a dp */ 10370 if (dp->flags & CACHE_FLAG_PENDING) { 10371 /* Okay, here it starts to get nasty. We need a pipe now to wait 10372 for a reply to come back so long as it's pending */ 10373 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10374 /* Find an empty slot */ 10375 if (dp->waiters[x] < 0) 10376 break; 10377 } 10378 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10379 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10380 return NULL; 10381 } 10382 if (pipe(com)) { 10383 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10384 return NULL; 10385 } 10386 dp->waiters[x] = com[1]; 10387 /* Okay, now we wait */ 10388 timeout = iaxdefaulttimeout * 1000; 10389 /* Temporarily unlock */ 10390 ast_mutex_unlock(&dpcache_lock); 10391 /* Defer any dtmf */ 10392 if (chan) 10393 old = ast_channel_defer_dtmf(chan); 10394 abort = 0; 10395 while(timeout) { 10396 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10397 if (outfd > -1) { 10398 break; 10399 } 10400 if (c) { 10401 f = ast_read(c); 10402 if (f) 10403 ast_frfree(f); 10404 else { 10405 /* Got hung up on, abort! */ 10406 break; 10407 abort = 1; 10408 } 10409 } 10410 } 10411 if (!timeout) { 10412 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10413 } 10414 ast_mutex_lock(&dpcache_lock); 10415 dp->waiters[x] = -1; 10416 close(com[1]); 10417 close(com[0]); 10418 if (abort) { 10419 /* Don't interpret anything, just abort. Not sure what th epoint 10420 of undeferring dtmf on a hung up channel is but hey whatever */ 10421 if (!old && chan) 10422 ast_channel_undefer_dtmf(chan); 10423 return NULL; 10424 } 10425 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10426 /* Now to do non-independent analysis the results of our wait */ 10427 if (dp->flags & CACHE_FLAG_PENDING) { 10428 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10429 pending. Don't let it take as long to timeout. */ 10430 dp->flags &= ~CACHE_FLAG_PENDING; 10431 dp->flags |= CACHE_FLAG_TIMEOUT; 10432 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10433 systems without leaving it unavailable once the server comes back online */ 10434 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10435 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10436 if (dp->waiters[x] > -1) 10437 write(dp->waiters[x], "asdf", 4); 10438 } 10439 } 10440 /* Our caller will obtain the rest */ 10441 if (!old && chan) 10442 ast_channel_undefer_dtmf(chan); 10443 } 10444 return dp; 10445 }
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 1642 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01642 { 01643 01644 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01645 }
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 1647 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01647 { 01648 01649 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01650 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 908 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, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00909 { 00910 pthread_attr_t attr; 00911 struct iax2_thread *thread = NULL; 00912 00913 /* Pop the head of the list off */ 00914 AST_LIST_LOCK(&idle_list); 00915 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00916 AST_LIST_UNLOCK(&idle_list); 00917 00918 /* If no idle thread is available from the regular list, try dynamic */ 00919 if (thread == NULL) { 00920 AST_LIST_LOCK(&dynamic_list); 00921 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00922 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00923 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00924 /* We need to MAKE a thread! */ 00925 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00926 thread->threadnum = iaxdynamicthreadcount; 00927 thread->type = IAX_TYPE_DYNAMIC; 00928 ast_mutex_init(&thread->lock); 00929 ast_cond_init(&thread->cond, NULL); 00930 pthread_attr_init(&attr); 00931 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00932 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00933 free(thread); 00934 thread = NULL; 00935 } else { 00936 /* All went well and the thread is up, so increment our count */ 00937 iaxdynamicthreadcount++; 00938 00939 /* Wait for the thread to be ready before returning it to the caller */ 00940 while (!thread->ready_for_signal) 00941 usleep(1); 00942 } 00943 } 00944 } 00945 AST_LIST_UNLOCK(&dynamic_list); 00946 } 00947 00948 /* this thread is not processing a full frame (since it is idle), 00949 so ensure that the field for the full frame call number is empty */ 00950 if (thread) 00951 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00952 00953 return thread; 00954 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1141 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01142 { 01143 struct iax2_peer *peer = NULL; 01144 struct iax2_peer tmp_peer = { 01145 .name = name, 01146 }; 01147 01148 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01149 01150 /* Now go for realtime if applicable */ 01151 if(!peer && realtime) 01152 peer = realtime_peer(name, NULL); 01153 01154 return peer; 01155 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 4003 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
04004 { 04005 struct iax2_trunk_peer *tpeer; 04006 04007 /* Finds and locks trunk peer */ 04008 ast_mutex_lock(&tpeerlock); 04009 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04010 /* We don't lock here because tpeer->addr *never* changes */ 04011 if (!inaddrcmp(&tpeer->addr, sin)) { 04012 ast_mutex_lock(&tpeer->lock); 04013 break; 04014 } 04015 } 04016 if (!tpeer) { 04017 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04018 ast_mutex_init(&tpeer->lock); 04019 tpeer->lastsent = 9999; 04020 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04021 tpeer->trunkact = ast_tvnow(); 04022 ast_mutex_lock(&tpeer->lock); 04023 tpeer->next = tpeers; 04024 tpeer->sockfd = fd; 04025 tpeers = tpeer; 04026 #ifdef SO_NO_CHECK 04027 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04028 #endif 04029 if (option_debug) 04030 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04031 } 04032 } 04033 ast_mutex_unlock(&tpeerlock); 04034 return tpeer; 04035 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3819 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03820 { 03821 long ms; /* NOT unsigned */ 03822 if (ast_tvzero(iaxs[callno]->rxcore)) { 03823 /* Initialize rxcore time if appropriate */ 03824 gettimeofday(&iaxs[callno]->rxcore, NULL); 03825 /* Round to nearest 20ms so traces look pretty */ 03826 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03827 } 03828 /* Calculate difference between trunk and channel */ 03829 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03830 /* Return as the sum of trunk time and the difference between trunk and real time */ 03831 return ms + ts; 03832 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8911 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08912 { 08913 struct iax2_context *conl; 08914 while(con) { 08915 conl = con; 08916 con = con->next; 08917 free(conl); 08918 } 08919 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10569 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10570 { 10571 struct iax2_peer *peer; 10572 char *peername, *colname; 10573 10574 peername = ast_strdupa(data); 10575 10576 /* if our channel, return the IP address of the endpoint of current channel */ 10577 if (!strcmp(peername,"CURRENTCHANNEL")) { 10578 unsigned short callno; 10579 if (chan->tech != &iax2_tech) 10580 return -1; 10581 callno = PTR_TO_CALLNO(chan->tech_pvt); 10582 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10583 return 0; 10584 } 10585 10586 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10587 *colname++ = '\0'; 10588 else if ((colname = strchr(peername, '|'))) 10589 *colname++ = '\0'; 10590 else 10591 colname = "ip"; 10592 10593 if (!(peer = find_peer(peername, 1))) 10594 return -1; 10595 10596 if (!strcasecmp(colname, "ip")) { 10597 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10598 } else if (!strcasecmp(colname, "status")) { 10599 peer_status(peer, buf, len); 10600 } else if (!strcasecmp(colname, "mailbox")) { 10601 ast_copy_string(buf, peer->mailbox, len); 10602 } else if (!strcasecmp(colname, "context")) { 10603 ast_copy_string(buf, peer->context, len); 10604 } else if (!strcasecmp(colname, "expire")) { 10605 snprintf(buf, len, "%d", peer->expire); 10606 } else if (!strcasecmp(colname, "dynamic")) { 10607 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10608 } else if (!strcasecmp(colname, "callerid_name")) { 10609 ast_copy_string(buf, peer->cid_name, len); 10610 } else if (!strcasecmp(colname, "callerid_num")) { 10611 ast_copy_string(buf, peer->cid_num, len); 10612 } else if (!strcasecmp(colname, "codecs")) { 10613 ast_getformatname_multiple(buf, len -1, peer->capability); 10614 } else if (!strncasecmp(colname, "codec[", 6)) { 10615 char *codecnum, *ptr; 10616 int index = 0, codec = 0; 10617 10618 codecnum = strchr(colname, '['); 10619 *codecnum = '\0'; 10620 codecnum++; 10621 if ((ptr = strchr(codecnum, ']'))) { 10622 *ptr = '\0'; 10623 } 10624 index = atoi(codecnum); 10625 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10626 ast_copy_string(buf, ast_getformatname(codec), len); 10627 } 10628 } 10629 10630 peer_unref(peer); 10631 10632 return 0; 10633 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9136 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09137 { 09138 int methods = 0; 09139 if (strstr(value, "rsa")) 09140 methods |= IAX_AUTH_RSA; 09141 if (strstr(value, "md5")) 09142 methods |= IAX_AUTH_MD5; 09143 if (strstr(value, "plaintext")) 09144 methods |= IAX_AUTH_PLAINTEXT; 09145 return methods; 09146 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1023 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01024 { 01025 int e; 01026 if (!strcasecmp(s, "aes128")) 01027 e = IAX_ENCRYPT_AES128; 01028 else if (ast_true(s)) 01029 e = IAX_ENCRYPT_AES128; 01030 else 01031 e = 0; 01032 return e; 01033 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2622 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02623 { 02624 #ifdef SCHED_MULTITHREADED 02625 if (schedule_action(__get_from_jb, data)) 02626 #endif 02627 __get_from_jb(data); 02628 return 0; 02629 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6806 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), socket_process(), and thread.
06807 { 06808 struct iax2_pkt_buf *pkt_buf; 06809 06810 ast_mutex_lock(&thread->lock); 06811 06812 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06813 ast_mutex_unlock(&thread->lock); 06814 06815 thread->buf = pkt_buf->buf; 06816 thread->buf_len = pkt_buf->len; 06817 thread->buf_size = pkt_buf->len + 1; 06818 06819 socket_process(thread); 06820 06821 thread->buf = NULL; 06822 ast_free(pkt_buf); 06823 06824 ast_mutex_lock(&thread->lock); 06825 } 06826 06827 ast_mutex_unlock(&thread->lock); 06828 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2030 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().
02031 { 02032 /* XXX Ideally we should figure out why an error occured and then abort those 02033 rather than continuing to try. Unfortunately, the published interface does 02034 not seem to work XXX */ 02035 #if 0 02036 struct sockaddr_in *sin; 02037 int res; 02038 struct msghdr m; 02039 struct sock_extended_err e; 02040 m.msg_name = NULL; 02041 m.msg_namelen = 0; 02042 m.msg_iov = NULL; 02043 m.msg_control = &e; 02044 m.msg_controllen = sizeof(e); 02045 m.msg_flags = 0; 02046 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02047 if (res < 0) 02048 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02049 else { 02050 if (m.msg_controllen) { 02051 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02052 if (sin) 02053 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02054 else 02055 ast_log(LOG_WARNING, "No address detected??\n"); 02056 } else { 02057 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02058 } 02059 } 02060 #endif 02061 return 0; 02062 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5878 of file chan_iax2.c.
References iax2_registry::addr, 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().
05879 { 05880 struct iax2_registry *reg; 05881 /* Start pessimistic */ 05882 char peer[256] = ""; 05883 char msgstatus[60]; 05884 int refresh = 60; 05885 char ourip[256] = "<Unspecified>"; 05886 struct sockaddr_in oldus; 05887 struct sockaddr_in us; 05888 int oldmsgs; 05889 05890 memset(&us, 0, sizeof(us)); 05891 if (ies->apparent_addr) 05892 bcopy(ies->apparent_addr, &us, sizeof(us)); 05893 if (ies->username) 05894 ast_copy_string(peer, ies->username, sizeof(peer)); 05895 if (ies->refresh) 05896 refresh = ies->refresh; 05897 if (ies->calling_number) { 05898 /* We don't do anything with it really, but maybe we should */ 05899 } 05900 reg = iaxs[callno]->reg; 05901 if (!reg) { 05902 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05903 return -1; 05904 } 05905 memcpy(&oldus, ®->us, sizeof(oldus)); 05906 oldmsgs = reg->messages; 05907 if (inaddrcmp(®->addr, sin)) { 05908 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05909 return -1; 05910 } 05911 memcpy(®->us, &us, sizeof(reg->us)); 05912 if (ies->msgcount >= 0) 05913 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05914 /* always refresh the registration at the interval requested by the server 05915 we are registering to 05916 */ 05917 reg->refresh = refresh; 05918 AST_SCHED_DEL(sched, reg->expire); 05919 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05920 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05921 if (option_verbose > 2) { 05922 if (reg->messages > 255) 05923 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05924 else if (reg->messages > 1) 05925 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05926 else if (reg->messages > 0) 05927 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05928 else 05929 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05930 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05931 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05932 } 05933 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05934 } 05935 reg->regstate = REG_STATE_REGISTERED; 05936 return 0; 05937 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3619 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.
03620 { 03621 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03622 if (option_debug) 03623 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03624 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03625 }
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 3469 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.
03470 { 03471 struct ast_channel *cs[3]; 03472 struct ast_channel *who, *other; 03473 int to = -1; 03474 int res = -1; 03475 int transferstarted=0; 03476 struct ast_frame *f; 03477 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03478 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03479 struct timeval waittimer = {0, 0}, tv; 03480 03481 lock_both(callno0, callno1); 03482 if (!iaxs[callno0] || !iaxs[callno1]) { 03483 unlock_both(callno0, callno1); 03484 return AST_BRIDGE_FAILED; 03485 } 03486 /* Put them in native bridge mode */ 03487 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03488 iaxs[callno0]->bridgecallno = callno1; 03489 iaxs[callno1]->bridgecallno = callno0; 03490 } 03491 unlock_both(callno0, callno1); 03492 03493 /* If not, try to bridge until we can execute a transfer, if we can */ 03494 cs[0] = c0; 03495 cs[1] = c1; 03496 for (/* ever */;;) { 03497 /* Check in case we got masqueraded into */ 03498 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03499 if (option_verbose > 2) 03500 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03501 /* Remove from native mode */ 03502 if (c0->tech == &iax2_tech) { 03503 ast_mutex_lock(&iaxsl[callno0]); 03504 iaxs[callno0]->bridgecallno = 0; 03505 ast_mutex_unlock(&iaxsl[callno0]); 03506 } 03507 if (c1->tech == &iax2_tech) { 03508 ast_mutex_lock(&iaxsl[callno1]); 03509 iaxs[callno1]->bridgecallno = 0; 03510 ast_mutex_unlock(&iaxsl[callno1]); 03511 } 03512 return AST_BRIDGE_FAILED_NOWARN; 03513 } 03514 if (c0->nativeformats != c1->nativeformats) { 03515 if (option_verbose > 2) { 03516 char buf0[255]; 03517 char buf1[255]; 03518 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03519 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03520 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03521 } 03522 /* Remove from native mode */ 03523 lock_both(callno0, callno1); 03524 if (iaxs[callno0]) 03525 iaxs[callno0]->bridgecallno = 0; 03526 if (iaxs[callno1]) 03527 iaxs[callno1]->bridgecallno = 0; 03528 unlock_both(callno0, callno1); 03529 return AST_BRIDGE_FAILED_NOWARN; 03530 } 03531 /* check if transfered and if we really want native bridging */ 03532 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03533 /* Try the transfer */ 03534 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03535 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03536 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03537 transferstarted = 1; 03538 } 03539 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03540 /* Call has been transferred. We're no longer involved */ 03541 gettimeofday(&tv, NULL); 03542 if (ast_tvzero(waittimer)) { 03543 waittimer = tv; 03544 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03545 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03546 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03547 *fo = NULL; 03548 *rc = c0; 03549 res = AST_BRIDGE_COMPLETE; 03550 break; 03551 } 03552 } 03553 to = 1000; 03554 who = ast_waitfor_n(cs, 2, &to); 03555 if (timeoutms > -1) { 03556 timeoutms -= (1000 - to); 03557 if (timeoutms < 0) 03558 timeoutms = 0; 03559 } 03560 if (!who) { 03561 if (!timeoutms) { 03562 res = AST_BRIDGE_RETRY; 03563 break; 03564 } 03565 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03566 res = AST_BRIDGE_FAILED; 03567 break; 03568 } 03569 continue; 03570 } 03571 f = ast_read(who); 03572 if (!f) { 03573 *fo = NULL; 03574 *rc = who; 03575 res = AST_BRIDGE_COMPLETE; 03576 break; 03577 } 03578 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03579 *fo = f; 03580 *rc = who; 03581 res = AST_BRIDGE_COMPLETE; 03582 break; 03583 } 03584 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03585 if ((f->frametype == AST_FRAME_VOICE) || 03586 (f->frametype == AST_FRAME_TEXT) || 03587 (f->frametype == AST_FRAME_VIDEO) || 03588 (f->frametype == AST_FRAME_IMAGE) || 03589 (f->frametype == AST_FRAME_DTMF)) { 03590 /* monitored dtmf take out of the bridge. 03591 * check if we monitor the specific source. 03592 */ 03593 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03594 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03595 *rc = who; 03596 *fo = f; 03597 res = AST_BRIDGE_COMPLETE; 03598 /* Remove from native mode */ 03599 break; 03600 } 03601 /* everything else goes to the other side */ 03602 ast_write(other, f); 03603 } 03604 ast_frfree(f); 03605 /* Swap who gets priority */ 03606 cs[2] = cs[0]; 03607 cs[0] = cs[1]; 03608 cs[1] = cs[2]; 03609 } 03610 lock_both(callno0, callno1); 03611 if(iaxs[callno0]) 03612 iaxs[callno0]->bridgecallno = 0; 03613 if(iaxs[callno1]) 03614 iaxs[callno1]->bridgecallno = 0; 03615 unlock_both(callno0, callno1); 03616 return res; 03617 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3213 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, 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, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, 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, and ast_channel::tech_pvt.
03214 { 03215 struct sockaddr_in sin; 03216 char *l=NULL, *n=NULL, *tmpstr; 03217 struct iax_ie_data ied; 03218 char *defaultrdest = "s"; 03219 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03220 struct parsed_dial_string pds; 03221 struct create_addr_info cai; 03222 03223 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03224 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03225 return -1; 03226 } 03227 03228 memset(&cai, 0, sizeof(cai)); 03229 cai.encmethods = iax2_encryption; 03230 03231 memset(&pds, 0, sizeof(pds)); 03232 tmpstr = ast_strdupa(dest); 03233 parse_dial_string(tmpstr, &pds); 03234 03235 if (ast_strlen_zero(pds.peer)) { 03236 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03237 return -1; 03238 } 03239 03240 if (!pds.exten) { 03241 pds.exten = defaultrdest; 03242 } 03243 03244 if (create_addr(pds.peer, c, &sin, &cai)) { 03245 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03246 return -1; 03247 } 03248 03249 if (!pds.username && !ast_strlen_zero(cai.username)) 03250 pds.username = cai.username; 03251 if (!pds.password && !ast_strlen_zero(cai.secret)) 03252 pds.password = cai.secret; 03253 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03254 pds.key = cai.outkey; 03255 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03256 pds.context = cai.peercontext; 03257 03258 /* Keep track of the context for outgoing calls too */ 03259 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03260 03261 if (pds.port) 03262 sin.sin_port = htons(atoi(pds.port)); 03263 03264 l = c->cid.cid_num; 03265 n = c->cid.cid_name; 03266 03267 /* Now build request */ 03268 memset(&ied, 0, sizeof(ied)); 03269 03270 /* On new call, first IE MUST be IAX version of caller */ 03271 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03272 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03273 if (pds.options && strchr(pds.options, 'a')) { 03274 /* Request auto answer */ 03275 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03276 } 03277 03278 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03279 03280 if (l) { 03281 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03282 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03283 } else { 03284 if (n) 03285 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03286 else 03287 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03288 } 03289 03290 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03291 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03292 03293 if (n) 03294 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03295 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03296 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03297 03298 if (!ast_strlen_zero(c->language)) 03299 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03300 if (!ast_strlen_zero(c->cid.cid_dnid)) 03301 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03302 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03303 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03304 03305 if (pds.context) 03306 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03307 03308 if (pds.username) 03309 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03310 03311 if (cai.encmethods) 03312 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03313 03314 ast_mutex_lock(&iaxsl[callno]); 03315 03316 if (!ast_strlen_zero(c->context)) 03317 ast_string_field_set(iaxs[callno], context, c->context); 03318 03319 if (pds.username) 03320 ast_string_field_set(iaxs[callno], username, pds.username); 03321 03322 iaxs[callno]->encmethods = cai.encmethods; 03323 03324 iaxs[callno]->adsi = cai.adsi; 03325 03326 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03327 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03328 03329 if (pds.key) 03330 ast_string_field_set(iaxs[callno], outkey, pds.key); 03331 if (pds.password) 03332 ast_string_field_set(iaxs[callno], secret, pds.password); 03333 03334 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03335 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03336 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03337 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03338 03339 if (iaxs[callno]->maxtime) { 03340 /* Initialize pingtime and auto-congest time */ 03341 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03342 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03343 } else if (autokill) { 03344 iaxs[callno]->pingtime = autokill / 2; 03345 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03346 } 03347 03348 /* send the command using the appropriate socket for this peer */ 03349 iaxs[callno]->sockfd = cai.sockfd; 03350 03351 /* Transmit the string in a "NEW" request */ 03352 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03353 03354 ast_mutex_unlock(&iaxsl[callno]); 03355 ast_setstate(c, AST_STATE_RINGING); 03356 03357 return 0; 03358 }
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 10471 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10472 { 10473 int res = 0; 10474 struct iax2_dpcache *dp; 10475 #if 0 10476 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10477 #endif 10478 if ((priority != 1) && (priority != 2)) 10479 return 0; 10480 ast_mutex_lock(&dpcache_lock); 10481 dp = find_cache(chan, data, context, exten, priority); 10482 if (dp) { 10483 if (dp->flags & CACHE_FLAG_CANEXIST) 10484 res= 1; 10485 } 10486 ast_mutex_unlock(&dpcache_lock); 10487 if (!dp) { 10488 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10489 } 10490 return res; 10491 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3125 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03126 { 03127 time_t t; 03128 struct tm tm; 03129 unsigned int tmp; 03130 time(&t); 03131 if (!ast_strlen_zero(tz)) 03132 ast_localtime(&t, &tm, tz); 03133 else 03134 ast_localtime(&t, &tm, NULL); 03135 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03136 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03137 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03138 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03139 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03140 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03141 return tmp; 03142 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1281 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), 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(), and socket_process().
01282 { 01283 struct chan_iax2_pvt *pvt; 01284 struct ast_channel *owner; 01285 01286 retry: 01287 pvt = iaxs[callno]; 01288 gettimeofday(&lastused[callno], NULL); 01289 01290 owner = pvt ? pvt->owner : NULL; 01291 01292 if (owner) { 01293 if (ast_mutex_trylock(&owner->lock)) { 01294 if (option_debug > 2) 01295 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01296 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01297 goto retry; 01298 } 01299 } 01300 if (!owner) { 01301 iaxs[callno] = NULL; 01302 } 01303 01304 if (pvt) { 01305 if (!owner) { 01306 pvt->owner = NULL; 01307 } else { 01308 /* If there's an owner, prod it to give up */ 01309 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01310 * because we already hold the owner channel lock. */ 01311 ast_queue_hangup(owner); 01312 } 01313 01314 if (pvt->peercallno) { 01315 remove_by_peercallno(pvt); 01316 } 01317 01318 if (!owner) { 01319 ao2_ref(pvt, -1); 01320 pvt = NULL; 01321 } 01322 } 01323 01324 if (owner) { 01325 ast_mutex_unlock(&owner->lock); 01326 } 01327 01328 if (callno & 0x4000) { 01329 update_max_trunk(); 01330 } 01331 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1211 of file chan_iax2.c.
References ao2_find(), 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, chan_iax2_pvt::pingid, sched, user_unref(), and users.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01212 { 01213 /* Decrement AUTHREQ count if needed */ 01214 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01215 struct iax2_user *user; 01216 struct iax2_user tmp_user = { 01217 .name = pvt->username, 01218 }; 01219 01220 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01221 if (user) { 01222 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01223 user = user_unref(user); 01224 } 01225 01226 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01227 } 01228 01229 /* No more pings or lagrq's */ 01230 AST_SCHED_DEL(sched, pvt->pingid); 01231 AST_SCHED_DEL(sched, pvt->lagid); 01232 AST_SCHED_DEL(sched, pvt->autoid); 01233 AST_SCHED_DEL(sched, pvt->authid); 01234 AST_SCHED_DEL(sched, pvt->initid); 01235 AST_SCHED_DEL(sched, pvt->jbid); 01236 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10658 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().
10659 { 10660 struct parsed_dial_string pds; 10661 char *tmp = ast_strdupa(data); 10662 struct iax2_peer *p; 10663 int res = AST_DEVICE_INVALID; 10664 10665 memset(&pds, 0, sizeof(pds)); 10666 parse_dial_string(tmp, &pds); 10667 10668 if (ast_strlen_zero(pds.peer)) { 10669 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10670 return res; 10671 } 10672 10673 if (option_debug > 2) 10674 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10675 10676 /* SLD: FIXME: second call to find_peer during registration */ 10677 if (!(p = find_peer(pds.peer, 1))) 10678 return res; 10679 10680 res = AST_DEVICE_UNAVAILABLE; 10681 if (option_debug > 2) 10682 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10683 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10684 10685 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10686 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10687 /* Peer is registered, or have default IP address 10688 and a valid registration */ 10689 if (p->historicms == 0 || p->historicms <= p->maxms) 10690 /* let the core figure out whether it is in use or not */ 10691 res = AST_DEVICE_UNKNOWN; 10692 } 10693 10694 peer_unref(p); 10695 10696 return res; 10697 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2741 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02742 { 02743 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02744 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2746 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02747 { 02748 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02749 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4925 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04926 { 04927 if (argc < 2 || argc > 3) 04928 return RESULT_SHOWUSAGE; 04929 iaxdebug = 1; 04930 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04931 return RESULT_SUCCESS; 04932 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4943 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04944 { 04945 if (argc < 3 || argc > 4) 04946 return RESULT_SHOWUSAGE; 04947 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04948 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04949 return RESULT_SUCCESS; 04950 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8630 of file chan_iax2.c.
References 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().
08631 { 08632 struct iax_ie_data ied; 08633 if (option_debug && iaxdebug) 08634 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08635 08636 if (reg->dnsmgr && 08637 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08638 /* Maybe the IP has changed, force DNS refresh */ 08639 ast_dnsmgr_refresh(reg->dnsmgr); 08640 } 08641 08642 /* 08643 * if IP has Changed, free allocated call to create a new one with new IP 08644 * call has the pointer to IP and must be updated to the new one 08645 */ 08646 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08647 ast_mutex_lock(&iaxsl[reg->callno]); 08648 iax2_destroy(reg->callno); 08649 ast_mutex_unlock(&iaxsl[reg->callno]); 08650 reg->callno = 0; 08651 } 08652 if (!reg->addr.sin_addr.s_addr) { 08653 if (option_debug && iaxdebug) 08654 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08655 /* Setup the next registration attempt */ 08656 AST_SCHED_DEL(sched, reg->expire); 08657 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08658 return -1; 08659 } 08660 08661 if (!reg->callno) { 08662 if (option_debug) 08663 ast_log(LOG_DEBUG, "Allocate call number\n"); 08664 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08665 if (reg->callno < 1) { 08666 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08667 return -1; 08668 } else if (option_debug) 08669 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08670 iaxs[reg->callno]->reg = reg; 08671 ast_mutex_unlock(&iaxsl[reg->callno]); 08672 } 08673 /* Schedule the next registration attempt */ 08674 AST_SCHED_DEL(sched, reg->expire); 08675 /* Setup the next registration a little early */ 08676 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08677 /* Send the request */ 08678 memset(&ied, 0, sizeof(ied)); 08679 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08680 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08681 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08682 reg->regstate = REG_STATE_REGSENT; 08683 return 0; 08684 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5726 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05727 { 05728 #ifdef SCHED_MULTITHREADED 05729 if (schedule_action(__iax2_do_register_s, data)) 05730 #endif 05731 __iax2_do_register_s(data); 05732 return 0; 05733 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4934 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04935 { 04936 if (argc < 3 || argc > 4) 04937 return RESULT_SHOWUSAGE; 04938 iaxtrunkdebug = 1; 04939 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04940 return RESULT_SUCCESS; 04941 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6417 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().
06418 { 06419 struct iax_ie_data ied; 06420 /* Auto-hangup with 30 seconds of inactivity */ 06421 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06422 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06423 memset(&ied, 0, sizeof(ied)); 06424 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06425 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06426 dp->flags |= CACHE_FLAG_TRANSMITTED; 06427 }
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 10517 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
10518 { 10519 char odata[256]; 10520 char req[256]; 10521 char *ncontext; 10522 struct iax2_dpcache *dp; 10523 struct ast_app *dial; 10524 #if 0 10525 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); 10526 #endif 10527 if (priority == 2) { 10528 /* Indicate status, can be overridden in dialplan */ 10529 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10530 if (dialstatus) { 10531 dial = pbx_findapp(dialstatus); 10532 if (dial) 10533 pbx_exec(chan, dial, ""); 10534 } 10535 return -1; 10536 } else if (priority != 1) 10537 return -1; 10538 ast_mutex_lock(&dpcache_lock); 10539 dp = find_cache(chan, data, context, exten, priority); 10540 if (dp) { 10541 if (dp->flags & CACHE_FLAG_EXISTS) { 10542 ast_copy_string(odata, data, sizeof(odata)); 10543 ncontext = strchr(odata, '/'); 10544 if (ncontext) { 10545 *ncontext = '\0'; 10546 ncontext++; 10547 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10548 } else { 10549 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10550 } 10551 if (option_verbose > 2) 10552 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10553 } else { 10554 ast_mutex_unlock(&dpcache_lock); 10555 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10556 return -1; 10557 } 10558 } 10559 ast_mutex_unlock(&dpcache_lock); 10560 dial = pbx_findapp("Dial"); 10561 if (dial) { 10562 return pbx_exec(chan, dial, req); 10563 } else { 10564 ast_log(LOG_WARNING, "No dial application registered\n"); 10565 } 10566 return -1; 10567 }
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 10448 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10449 { 10450 struct iax2_dpcache *dp; 10451 int res = 0; 10452 #if 0 10453 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10454 #endif 10455 if ((priority != 1) && (priority != 2)) 10456 return 0; 10457 ast_mutex_lock(&dpcache_lock); 10458 dp = find_cache(chan, data, context, exten, priority); 10459 if (dp) { 10460 if (dp->flags & CACHE_FLAG_EXISTS) 10461 res= 1; 10462 } 10463 ast_mutex_unlock(&dpcache_lock); 10464 if (!dp) { 10465 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10466 } 10467 return res; 10468 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2768 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02769 { 02770 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02771 ast_mutex_lock(&iaxsl[callno]); 02772 if (iaxs[callno]) 02773 iaxs[callno]->owner = newchan; 02774 else 02775 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02776 ast_mutex_unlock(&iaxsl[callno]); 02777 return 0; 02778 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1275 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(), and schedule_delivery().
01276 { 01277 AST_SCHED_DEL(sched, fr->retrans); 01278 iax_frame_free(fr); 01279 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1181 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), peer_unref(), peers, and realtime_peer().
Referenced by __find_callno().
01182 { 01183 struct iax2_peer *peer = NULL; 01184 int res = 0; 01185 struct ao2_iterator i; 01186 01187 i = ao2_iterator_init(peers, 0); 01188 while ((peer = ao2_iterator_next(&i))) { 01189 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01190 (peer->addr.sin_port == sin.sin_port)) { 01191 ast_copy_string(host, peer->name, len); 01192 peer_unref(peer); 01193 res = 1; 01194 break; 01195 } 01196 peer_unref(peer); 01197 } 01198 01199 if (!peer) { 01200 peer = realtime_peer(NULL, &sin); 01201 if (peer) { 01202 ast_copy_string(host, peer->name, len); 01203 peer_unref(peer); 01204 res = 1; 01205 } 01206 } 01207 01208 return res; 01209 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3694 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, peer_unref(), and peers.
Referenced by check_access().
03695 { 03696 struct iax2_peer *peer; 03697 int res = 0; 03698 struct ao2_iterator i; 03699 03700 i = ao2_iterator_init(peers, 0); 03701 while ((peer = ao2_iterator_next(&i))) { 03702 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03703 (peer->addr.sin_port == sin.sin_port)) { 03704 res = ast_test_flag(peer, IAX_TRUNK); 03705 peer_unref(peer); 03706 break; 03707 } 03708 peer_unref(peer); 03709 } 03710 03711 return res; 03712 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3360 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, option_debug, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03361 { 03362 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03363 int alreadygone; 03364 struct iax_ie_data ied; 03365 memset(&ied, 0, sizeof(ied)); 03366 ast_mutex_lock(&iaxsl[callno]); 03367 if (callno && iaxs[callno]) { 03368 if (option_debug) 03369 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03370 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03371 /* Send the hangup unless we have had a transmission error or are already gone */ 03372 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03373 if (!iaxs[callno]->error && !alreadygone) { 03374 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03375 if (!iaxs[callno]) { 03376 ast_mutex_unlock(&iaxsl[callno]); 03377 return 0; 03378 } 03379 } 03380 /* Explicitly predestroy it */ 03381 iax2_predestroy(callno); 03382 /* If we were already gone to begin with, destroy us now */ 03383 if (alreadygone && iaxs[callno]) { 03384 if (option_debug) 03385 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03386 iax2_destroy(callno); 03387 } 03388 } 03389 ast_mutex_unlock(&iaxsl[callno]); 03390 if (option_verbose > 2) 03391 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03392 return 0; 03393 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3627 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(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, option_debug, chan_iax2_pvt::peercallno, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03628 { 03629 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03630 struct chan_iax2_pvt *pvt; 03631 int res = 0; 03632 03633 if (option_debug && iaxdebug) 03634 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03635 03636 ast_mutex_lock(&iaxsl[callno]); 03637 pvt = iaxs[callno]; 03638 03639 if (!pvt->peercallno) { 03640 /* We don't know the remote side's call number, yet. :( */ 03641 int count = 10; 03642 while (count-- && pvt && !pvt->peercallno) { 03643 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03644 pvt = iaxs[callno]; 03645 } 03646 if (!pvt->peercallno) { 03647 res = -1; 03648 goto done; 03649 } 03650 } 03651 03652 switch (condition) { 03653 case AST_CONTROL_HOLD: 03654 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03655 ast_moh_start(c, data, pvt->mohinterpret); 03656 goto done; 03657 } 03658 break; 03659 case AST_CONTROL_UNHOLD: 03660 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03661 ast_moh_stop(c); 03662 goto done; 03663 } 03664 } 03665 03666 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03667 03668 done: 03669 ast_mutex_unlock(&iaxsl[callno]); 03670 03671 return res; 03672 }
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 10494 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10495 { 10496 int res = 0; 10497 struct iax2_dpcache *dp; 10498 #if 0 10499 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10500 #endif 10501 if ((priority != 1) && (priority != 2)) 10502 return 0; 10503 ast_mutex_lock(&dpcache_lock); 10504 dp = find_cache(chan, data, context, exten, priority); 10505 if (dp) { 10506 if (dp->flags & CACHE_FLAG_MATCHMORE) 10507 res= 1; 10508 } 10509 ast_mutex_unlock(&dpcache_lock); 10510 if (!dp) { 10511 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10512 } 10513 return res; 10514 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4952 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04953 { 04954 if (argc < 3 || argc > 4) 04955 return RESULT_SHOWUSAGE; 04956 iaxdebug = 0; 04957 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04958 return RESULT_SUCCESS; 04959 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4970 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04971 { 04972 if (argc < 4 || argc > 5) 04973 return RESULT_SHOWUSAGE; 04974 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04975 jb_debug_output("\n"); 04976 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04977 return RESULT_SUCCESS; 04978 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4961 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04962 { 04963 if (argc < 4 || argc > 5) 04964 return RESULT_SHOWUSAGE; 04965 iaxtrunkdebug = 0; 04966 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04967 return RESULT_SUCCESS; 04968 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8828 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08829 { 08830 struct iax2_peer *peer = (struct iax2_peer *)data; 08831 peer->pokeexpire = -1; 08832 #ifdef SCHED_MULTITHREADED 08833 if (schedule_action(__iax2_poke_noanswer, data)) 08834 #endif 08835 __iax2_poke_noanswer(data); 08836 peer_unref(peer); 08837 return 0; 08838 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8849 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), 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, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, 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().
08850 { 08851 int callno; 08852 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08853 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08854 immediately after clearing things out */ 08855 peer->lastms = 0; 08856 peer->historicms = 0; 08857 peer->pokeexpire = -1; 08858 peer->callno = 0; 08859 return 0; 08860 } 08861 08862 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 08863 if ((callno = peer->callno) > 0) { 08864 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08865 ast_mutex_lock(&iaxsl[callno]); 08866 iax2_destroy(callno); 08867 ast_mutex_unlock(&iaxsl[callno]); 08868 } 08869 if (heldcall) 08870 ast_mutex_unlock(&iaxsl[heldcall]); 08871 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08872 if (heldcall) 08873 ast_mutex_lock(&iaxsl[heldcall]); 08874 if (peer->callno < 1) { 08875 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08876 return -1; 08877 } 08878 08879 /* Speed up retransmission times for this qualify call */ 08880 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08881 iaxs[peer->callno]->peerpoke = peer; 08882 08883 /* Remove any pending pokeexpire task */ 08884 if (peer->pokeexpire > -1) { 08885 if (!ast_sched_del(sched, peer->pokeexpire)) { 08886 peer->pokeexpire = -1; 08887 peer_unref(peer); 08888 } 08889 } 08890 08891 /* Queue up a new task to handle no reply */ 08892 /* If the host is already unreachable then use the unreachable interval instead */ 08893 if (peer->lastms < 0) { 08894 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08895 } else 08896 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08897 08898 if (peer->pokeexpire == -1) 08899 peer_unref(peer); 08900 08901 /* And send the poke */ 08902 ast_mutex_lock(&iaxsl[callno]); 08903 if (iaxs[callno]) { 08904 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08905 } 08906 ast_mutex_unlock(&iaxsl[callno]); 08907 08908 return 0; 08909 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8840 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08841 { 08842 struct iax2_peer *peer = obj; 08843 08844 iax2_poke_peer(peer, 0); 08845 08846 return 0; 08847 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6457 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06458 { 06459 struct iax2_peer *peer = (struct iax2_peer *)data; 06460 peer->pokeexpire = -1; 06461 #ifdef SCHED_MULTITHREADED 06462 if (schedule_action(__iax2_poke_peer_s, data)) 06463 #endif 06464 __iax2_poke_peer_s(data); 06465 return 0; 06466 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2114 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().
02115 { 02116 struct ast_channel *c; 02117 struct chan_iax2_pvt *pvt = iaxs[callno]; 02118 02119 if (!pvt) 02120 return -1; 02121 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02122 iax2_destroy_helper(pvt); 02123 ast_set_flag(pvt, IAX_ALREADYGONE); 02124 } 02125 c = pvt->owner; 02126 if (c) { 02127 c->tech_pvt = NULL; 02128 iax2_queue_hangup(callno); 02129 pvt->owner = NULL; 02130 ast_module_unref(ast_module_info->self); 02131 } 02132 return 0; 02133 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8505 of file chan_iax2.c.
References ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08506 { 08507 struct iax2_thread *thread = data; 08508 struct timeval tv; 08509 struct timespec ts; 08510 int put_into_idle = 0; 08511 08512 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08513 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08514 for(;;) { 08515 /* Wait for something to signal us to be awake */ 08516 ast_mutex_lock(&thread->lock); 08517 08518 /* Flag that we're ready to accept signals */ 08519 thread->ready_for_signal = 1; 08520 08521 /* Put into idle list if applicable */ 08522 if (put_into_idle) 08523 insert_idle_thread(thread); 08524 08525 if (thread->type == IAX_TYPE_DYNAMIC) { 08526 struct iax2_thread *t = NULL; 08527 /* Wait to be signalled or time out */ 08528 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08529 ts.tv_sec = tv.tv_sec; 08530 ts.tv_nsec = tv.tv_usec * 1000; 08531 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08532 /* This thread was never put back into the available dynamic 08533 * thread list, so just go away. */ 08534 if (!put_into_idle) { 08535 ast_mutex_unlock(&thread->lock); 08536 break; 08537 } 08538 AST_LIST_LOCK(&dynamic_list); 08539 /* Account for the case where this thread is acquired *right* after a timeout */ 08540 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08541 iaxdynamicthreadcount--; 08542 AST_LIST_UNLOCK(&dynamic_list); 08543 if (t) { 08544 /* This dynamic thread timed out waiting for a task and was 08545 * not acquired immediately after the timeout, 08546 * so it's time to go away. */ 08547 ast_mutex_unlock(&thread->lock); 08548 break; 08549 } 08550 /* Someone grabbed our thread *right* after we timed out. 08551 * Wait for them to set us up with something to do and signal 08552 * us to continue. */ 08553 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08554 ts.tv_sec = tv.tv_sec; 08555 ts.tv_nsec = tv.tv_usec * 1000; 08556 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08557 { 08558 ast_mutex_unlock(&thread->lock); 08559 break; 08560 } 08561 } 08562 } else { 08563 ast_cond_wait(&thread->cond, &thread->lock); 08564 } 08565 08566 /* Go back into our respective list */ 08567 put_into_idle = 1; 08568 08569 ast_mutex_unlock(&thread->lock); 08570 08571 if (thread->iostate == IAX_IOSTATE_IDLE) 08572 continue; 08573 08574 /* Add ourselves to the active list now */ 08575 AST_LIST_LOCK(&active_list); 08576 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08577 AST_LIST_UNLOCK(&active_list); 08578 08579 /* See what we need to do */ 08580 switch(thread->iostate) { 08581 case IAX_IOSTATE_READY: 08582 thread->actions++; 08583 thread->iostate = IAX_IOSTATE_PROCESSING; 08584 socket_process(thread); 08585 handle_deferred_full_frames(thread); 08586 break; 08587 case IAX_IOSTATE_SCHEDREADY: 08588 thread->actions++; 08589 thread->iostate = IAX_IOSTATE_PROCESSING; 08590 #ifdef SCHED_MULTITHREADED 08591 thread->schedfunc(thread->scheddata); 08592 #endif 08593 break; 08594 } 08595 time(&thread->checktime); 08596 thread->iostate = IAX_IOSTATE_IDLE; 08597 #ifdef DEBUG_SCHED_MULTITHREAD 08598 thread->curfunc[0]='\0'; 08599 #endif 08600 08601 /* Now... remove ourselves from the active list, and return to the idle list */ 08602 AST_LIST_LOCK(&active_list); 08603 AST_LIST_REMOVE(&active_list, thread, list); 08604 AST_LIST_UNLOCK(&active_list); 08605 08606 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08607 handle_deferred_full_frames(thread); 08608 } 08609 08610 /*!\note For some reason, idle threads are exiting without being removed 08611 * from an idle list, which is causing memory corruption. Forcibly remove 08612 * it from the list, if it's there. 08613 */ 08614 AST_LIST_LOCK(&idle_list); 08615 AST_LIST_REMOVE(&idle_list, thread, list); 08616 AST_LIST_UNLOCK(&idle_list); 08617 08618 AST_LIST_LOCK(&dynamic_list); 08619 AST_LIST_REMOVE(&dynamic_list, thread, list); 08620 AST_LIST_UNLOCK(&dynamic_list); 08621 08622 /* I am exiting here on my own volition, I need to clean up my own data structures 08623 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08624 */ 08625 pthread_cleanup_pop(1); 08626 08627 return NULL; 08628 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8496 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08497 { 08498 struct iax2_thread *thread = data; 08499 ast_mutex_destroy(&thread->lock); 08500 ast_cond_destroy(&thread->cond); 08501 free(thread); 08502 ast_atomic_dec_and_test(&iaxactivethreadcount); 08503 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8783 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08784 { 08785 int force = 0; 08786 int res; 08787 if (argc < 4) 08788 return RESULT_SHOWUSAGE; 08789 if ((argc > 4)) { 08790 if (!strcasecmp(argv[4], "forced")) 08791 force = 1; 08792 else 08793 return RESULT_SHOWUSAGE; 08794 } 08795 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08796 if (res < 0) 08797 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08798 else if (res < 1) 08799 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08800 else 08801 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08802 return RESULT_SUCCESS; 08803 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8686 of file chan_iax2.c.
References iax_prov_complete_template().
08687 { 08688 if (pos != 3) 08689 return NULL; 08690 return iax_prov_complete_template(line, word, pos, state); 08691 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8693 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().
08694 { 08695 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08696 is found for template */ 08697 struct iax_ie_data provdata; 08698 struct iax_ie_data ied; 08699 unsigned int sig; 08700 struct sockaddr_in sin; 08701 int callno; 08702 struct create_addr_info cai; 08703 08704 memset(&cai, 0, sizeof(cai)); 08705 08706 if (option_debug) 08707 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08708 08709 if (iax_provision_build(&provdata, &sig, template, force)) { 08710 if (option_debug) 08711 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08712 return 0; 08713 } 08714 08715 if (end) { 08716 memcpy(&sin, end, sizeof(sin)); 08717 cai.sockfd = sockfd; 08718 } else if (create_addr(dest, NULL, &sin, &cai)) 08719 return -1; 08720 08721 /* Build the rest of the message */ 08722 memset(&ied, 0, sizeof(ied)); 08723 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08724 08725 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08726 if (!callno) 08727 return -1; 08728 08729 if (iaxs[callno]) { 08730 /* Schedule autodestruct in case they don't ever give us anything back */ 08731 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08732 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08733 ast_set_flag(iaxs[callno], IAX_PROVISION); 08734 /* Got a call number now, so go ahead and send the provisioning information */ 08735 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08736 } 08737 ast_mutex_unlock(&iaxsl[callno]); 08738 08739 return 1; 08740 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2238 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02239 { 02240 struct iax2_peer *peer; 02241 02242 if (argc != 4) 02243 return RESULT_SHOWUSAGE; 02244 if (!strcmp(argv[3],"all")) { 02245 reload_config(); 02246 ast_cli(fd, "OK cache is flushed.\n"); 02247 } else if ((peer = find_peer(argv[3], 0))) { 02248 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02249 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02250 expire_registry(peer_ref(peer)); 02251 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02252 } else { 02253 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02254 } 02255 peer_unref(peer); 02256 } else { 02257 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02258 } 02259 02260 return RESULT_SUCCESS; 02261 }
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 1724 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01726 { 01727 for (;;) { 01728 if (iaxs[callno] && iaxs[callno]->owner) { 01729 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01730 /* Avoid deadlock by pausing and trying again */ 01731 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01732 } else { 01733 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01734 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01735 break; 01736 } 01737 } else 01738 break; 01739 } 01740 return 0; 01741 }
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 1662 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01663 { 01664 for (;;) { 01665 if (iaxs[callno] && iaxs[callno]->owner) { 01666 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01667 /* Avoid deadlock by pausing and trying again */ 01668 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01669 } else { 01670 ast_queue_frame(iaxs[callno]->owner, f); 01671 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01672 break; 01673 } 01674 } else 01675 break; 01676 } 01677 return 0; 01678 }
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 1693 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01694 { 01695 for (;;) { 01696 if (iaxs[callno] && iaxs[callno]->owner) { 01697 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01698 /* Avoid deadlock by pausing and trying again */ 01699 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01700 } else { 01701 ast_queue_hangup(iaxs[callno]->owner); 01702 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01703 break; 01704 } 01705 } else 01706 break; 01707 } 01708 return 0; 01709 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3421 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03422 { 03423 if (option_verbose > 3) 03424 ast_log(LOG_NOTICE, "I should never be called!\n"); 03425 return &ast_null_frame; 03426 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5939 of file chan_iax2.c.
References ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, secret, and strsep().
Referenced by set_config().
05940 { 05941 struct iax2_registry *reg; 05942 char copy[256]; 05943 char *username, *hostname, *secret; 05944 char *porta; 05945 char *stringp=NULL; 05946 05947 if (!value) 05948 return -1; 05949 ast_copy_string(copy, value, sizeof(copy)); 05950 stringp=copy; 05951 username = strsep(&stringp, "@"); 05952 hostname = strsep(&stringp, "@"); 05953 if (!hostname) { 05954 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05955 return -1; 05956 } 05957 stringp=username; 05958 username = strsep(&stringp, ":"); 05959 secret = strsep(&stringp, ":"); 05960 stringp=hostname; 05961 hostname = strsep(&stringp, ":"); 05962 porta = strsep(&stringp, ":"); 05963 05964 if (porta && !atoi(porta)) { 05965 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05966 return -1; 05967 } 05968 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05969 return -1; 05970 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05971 free(reg); 05972 return -1; 05973 } 05974 ast_copy_string(reg->username, username, sizeof(reg->username)); 05975 if (secret) 05976 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05977 reg->expire = -1; 05978 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05979 reg->addr.sin_family = AF_INET; 05980 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05981 AST_LIST_LOCK(®istrations); 05982 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05983 AST_LIST_UNLOCK(®istrations); 05984 05985 return 0; 05986 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10217 of file chan_iax2.c.
References reload_config().
10218 { 10219 return reload_config(); 10220 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8921 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(), fmt, 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::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.
08922 { 08923 int callno; 08924 int res; 08925 int fmt, native; 08926 struct sockaddr_in sin; 08927 struct ast_channel *c; 08928 struct parsed_dial_string pds; 08929 struct create_addr_info cai; 08930 char *tmpstr; 08931 08932 memset(&pds, 0, sizeof(pds)); 08933 tmpstr = ast_strdupa(data); 08934 parse_dial_string(tmpstr, &pds); 08935 08936 if (ast_strlen_zero(pds.peer)) { 08937 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 08938 return NULL; 08939 } 08940 08941 memset(&cai, 0, sizeof(cai)); 08942 cai.capability = iax2_capability; 08943 08944 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08945 08946 /* Populate our address from the given */ 08947 if (create_addr(pds.peer, NULL, &sin, &cai)) { 08948 *cause = AST_CAUSE_UNREGISTERED; 08949 return NULL; 08950 } 08951 08952 if (pds.port) 08953 sin.sin_port = htons(atoi(pds.port)); 08954 08955 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08956 if (callno < 1) { 08957 ast_log(LOG_WARNING, "Unable to create call\n"); 08958 *cause = AST_CAUSE_CONGESTION; 08959 return NULL; 08960 } 08961 08962 /* If this is a trunk, update it now */ 08963 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08964 if (ast_test_flag(&cai, IAX_TRUNK)) { 08965 int new_callno; 08966 if ((new_callno = make_trunk(callno, 1)) != -1) 08967 callno = new_callno; 08968 } 08969 iaxs[callno]->maxtime = cai.maxtime; 08970 if (cai.found) 08971 ast_string_field_set(iaxs[callno], host, pds.peer); 08972 08973 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08974 08975 ast_mutex_unlock(&iaxsl[callno]); 08976 08977 if (c) { 08978 /* Choose a format we can live with */ 08979 if (c->nativeformats & format) 08980 c->nativeformats &= format; 08981 else { 08982 native = c->nativeformats; 08983 fmt = format; 08984 res = ast_translator_best_choice(&fmt, &native); 08985 if (res < 0) { 08986 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08987 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08988 ast_hangup(c); 08989 return NULL; 08990 } 08991 c->nativeformats = native; 08992 } 08993 c->readformat = ast_best_codec(c->nativeformats); 08994 c->writeformat = c->readformat; 08995 } 08996 08997 return c; 08998 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 985 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
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_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00986 { 00987 int res; 00988 00989 res = ast_sched_add(con, when, callback, data); 00990 signal_condition(&sched_lock, &sched_cond); 00991 00992 return res; 00993 }
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 4263 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, encrypt_frame(), f, iax_frame::final, 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::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04264 { 04265 /* Queue a packet for delivery on a given private structure. Use "ts" for 04266 timestamp, or calculate if ts is 0. Send immediately without retransmission 04267 or delayed, with retransmission */ 04268 struct ast_iax2_full_hdr *fh; 04269 struct ast_iax2_mini_hdr *mh; 04270 struct ast_iax2_video_hdr *vh; 04271 struct { 04272 struct iax_frame fr2; 04273 unsigned char buffer[4096]; 04274 } frb; 04275 struct iax_frame *fr; 04276 int res; 04277 int sendmini=0; 04278 unsigned int lastsent; 04279 unsigned int fts; 04280 04281 frb.fr2.afdatalen = sizeof(frb.buffer); 04282 04283 if (!pvt) { 04284 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04285 return -1; 04286 } 04287 04288 lastsent = pvt->lastsent; 04289 04290 /* Calculate actual timestamp */ 04291 fts = calc_timestamp(pvt, ts, f); 04292 04293 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04294 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04295 * increment the "predicted timestamps" for voice, if we're predecting */ 04296 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04297 return 0; 04298 04299 04300 if ((ast_test_flag(pvt, IAX_TRUNK) || 04301 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04302 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04303 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04304 (f->frametype == AST_FRAME_VOICE) 04305 /* is a voice frame */ && 04306 (f->subclass == pvt->svoiceformat) 04307 /* is the same type */ ) { 04308 /* Force immediate rather than delayed transmission */ 04309 now = 1; 04310 /* Mark that mini-style frame is appropriate */ 04311 sendmini = 1; 04312 } 04313 if ( f->frametype == AST_FRAME_VIDEO ) { 04314 /* 04315 * If the lower 15 bits of the timestamp roll over, or if 04316 * the video format changed then send a full frame. 04317 * Otherwise send a mini video frame 04318 */ 04319 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04320 ((f->subclass & ~0x1) == pvt->svideoformat) 04321 ) { 04322 now = 1; 04323 sendmini = 1; 04324 } else { 04325 now = 0; 04326 sendmini = 0; 04327 } 04328 pvt->lastvsent = fts; 04329 } 04330 /* Allocate an iax_frame */ 04331 if (now) { 04332 fr = &frb.fr2; 04333 } else 04334 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)); 04335 if (!fr) { 04336 ast_log(LOG_WARNING, "Out of memory\n"); 04337 return -1; 04338 } 04339 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04340 iax_frame_wrap(fr, f); 04341 04342 fr->ts = fts; 04343 fr->callno = pvt->callno; 04344 fr->transfer = transfer; 04345 fr->final = final; 04346 if (!sendmini) { 04347 /* We need a full frame */ 04348 if (seqno > -1) 04349 fr->oseqno = seqno; 04350 else 04351 fr->oseqno = pvt->oseqno++; 04352 fr->iseqno = pvt->iseqno; 04353 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04354 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04355 fh->ts = htonl(fr->ts); 04356 fh->oseqno = fr->oseqno; 04357 if (transfer) { 04358 fh->iseqno = 0; 04359 } else 04360 fh->iseqno = fr->iseqno; 04361 /* Keep track of the last thing we've acknowledged */ 04362 if (!transfer) 04363 pvt->aseqno = fr->iseqno; 04364 fh->type = fr->af.frametype & 0xFF; 04365 if (fr->af.frametype == AST_FRAME_VIDEO) 04366 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04367 else 04368 fh->csub = compress_subclass(fr->af.subclass); 04369 if (transfer) { 04370 fr->dcallno = pvt->transfercallno; 04371 } else 04372 fr->dcallno = pvt->peercallno; 04373 fh->dcallno = htons(fr->dcallno); 04374 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04375 fr->data = fh; 04376 fr->retries = 0; 04377 /* Retry after 2x the ping time has passed */ 04378 fr->retrytime = pvt->pingtime * 2; 04379 if (fr->retrytime < MIN_RETRY_TIME) 04380 fr->retrytime = MIN_RETRY_TIME; 04381 if (fr->retrytime > MAX_RETRY_TIME) 04382 fr->retrytime = MAX_RETRY_TIME; 04383 /* Acks' don't get retried */ 04384 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04385 fr->retries = -1; 04386 else if (f->frametype == AST_FRAME_VOICE) 04387 pvt->svoiceformat = f->subclass; 04388 else if (f->frametype == AST_FRAME_VIDEO) 04389 pvt->svideoformat = f->subclass & ~0x1; 04390 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04391 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04392 if (iaxdebug) { 04393 if (fr->transfer) 04394 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04395 else 04396 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04397 } 04398 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04399 } else 04400 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04401 } 04402 04403 if (now) { 04404 res = send_packet(fr); 04405 } else 04406 res = iax2_transmit(fr); 04407 } else { 04408 if (ast_test_flag(pvt, IAX_TRUNK)) { 04409 iax2_trunk_queue(pvt, fr); 04410 res = 0; 04411 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04412 /* Video frame have no sequence number */ 04413 fr->oseqno = -1; 04414 fr->iseqno = -1; 04415 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04416 vh->zeros = 0; 04417 vh->callno = htons(0x8000 | fr->callno); 04418 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04419 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04420 fr->data = vh; 04421 fr->retries = -1; 04422 res = send_packet(fr); 04423 } else { 04424 /* Mini-frames have no sequence number */ 04425 fr->oseqno = -1; 04426 fr->iseqno = -1; 04427 /* Mini frame will do */ 04428 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04429 mh->callno = htons(fr->callno); 04430 mh->ts = htons(fr->ts & 0xFFFF); 04431 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04432 fr->data = mh; 04433 fr->retries = -1; 04434 if (pvt->transferring == TRANSFER_MEDIAPASS) 04435 fr->transfer = 1; 04436 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04437 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04438 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04439 } else 04440 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04441 } 04442 res = send_packet(fr); 04443 } 04444 } 04445 return res; 04446 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2763 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02764 { 02765 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02766 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2758 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.
02759 { 02760 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02761 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2751 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02752 { 02753 02754 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02755 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02756 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3395 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03396 { 03397 struct ast_option_header *h; 03398 int res; 03399 03400 switch (option) { 03401 case AST_OPTION_TXGAIN: 03402 case AST_OPTION_RXGAIN: 03403 /* these two cannot be sent, because they require a result */ 03404 errno = ENOSYS; 03405 return -1; 03406 default: 03407 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03408 return -1; 03409 03410 h->flag = AST_OPTION_FLAG_REQUEST; 03411 h->option = htons(option); 03412 memcpy(h->data, data, datalen); 03413 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03414 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03415 datalen + sizeof(*h), -1); 03416 free(h); 03417 return res; 03418 } 03419 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2442 of file chan_iax2.c.
References ast_cli(), 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, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02443 { 02444 struct iax2_dpcache *dp; 02445 char tmp[1024], *pc; 02446 int s; 02447 int x,y; 02448 struct timeval tv; 02449 gettimeofday(&tv, NULL); 02450 ast_mutex_lock(&dpcache_lock); 02451 dp = dpcache; 02452 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02453 while(dp) { 02454 s = dp->expiry.tv_sec - tv.tv_sec; 02455 tmp[0] = '\0'; 02456 if (dp->flags & CACHE_FLAG_EXISTS) 02457 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02458 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02459 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02460 if (dp->flags & CACHE_FLAG_CANEXIST) 02461 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02462 if (dp->flags & CACHE_FLAG_PENDING) 02463 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02464 if (dp->flags & CACHE_FLAG_TIMEOUT) 02465 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02466 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02467 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02468 if (dp->flags & CACHE_FLAG_MATCHMORE) 02469 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02470 if (dp->flags & CACHE_FLAG_UNKNOWN) 02471 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02472 /* Trim trailing pipe */ 02473 if (!ast_strlen_zero(tmp)) 02474 tmp[strlen(tmp) - 1] = '\0'; 02475 else 02476 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02477 y=0; 02478 pc = strchr(dp->peercontext, '@'); 02479 if (!pc) 02480 pc = dp->peercontext; 02481 else 02482 pc++; 02483 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02484 if (dp->waiters[x] > -1) 02485 y++; 02486 if (s > 0) 02487 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02488 else 02489 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02490 dp = dp->next; 02491 } 02492 ast_mutex_unlock(&dpcache_lock); 02493 return RESULT_SUCCESS; 02494 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4790 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_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04791 { 04792 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04793 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" 04794 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04795 int x; 04796 int numchans = 0; 04797 04798 if (argc != 3) 04799 return RESULT_SHOWUSAGE; 04800 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04801 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04802 ast_mutex_lock(&iaxsl[x]); 04803 if (iaxs[x]) { 04804 int lag, jitter, localdelay; 04805 jb_info jbinfo; 04806 04807 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04808 jb_getinfo(iaxs[x]->jb, &jbinfo); 04809 jitter = jbinfo.jitter; 04810 localdelay = jbinfo.current - jbinfo.min; 04811 } else { 04812 jitter = -1; 04813 localdelay = 0; 04814 } 04815 lag = iaxs[x]->remote_rr.delay; 04816 ast_cli(fd, FORMAT, 04817 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04818 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04819 S_OR(iaxs[x]->username, "(None)"), 04820 iaxs[x]->callno, iaxs[x]->peercallno, 04821 iaxs[x]->oseqno, iaxs[x]->iseqno, 04822 lag, 04823 jitter, 04824 localdelay, 04825 ast_getformatname(iaxs[x]->voiceformat) ); 04826 numchans++; 04827 } 04828 ast_mutex_unlock(&iaxsl[x]); 04829 } 04830 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04831 return RESULT_SUCCESS; 04832 #undef FORMAT 04833 #undef FORMAT2 04834 #undef FORMATB 04835 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4701 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.
04702 { 04703 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04704 #if !defined(__FreeBSD__) 04705 #define FORMAT "%-15.15s %-15d %-15d\n" 04706 #else /* __FreeBSD__ */ 04707 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04708 #endif /* __FreeBSD__ */ 04709 struct iax_firmware *cur; 04710 if ((argc != 3) && (argc != 4)) 04711 return RESULT_SHOWUSAGE; 04712 ast_mutex_lock(&waresl.lock); 04713 04714 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04715 for (cur = waresl.wares;cur;cur = cur->next) { 04716 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04717 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04718 (int)ntohl(cur->fwh->datalen)); 04719 } 04720 ast_mutex_unlock(&waresl.lock); 04721 return RESULT_SUCCESS; 04722 #undef FORMAT 04723 #undef FORMAT2 04724 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4913 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04914 { 04915 int numchans = 0; 04916 if (argc != 3) 04917 return RESULT_SHOWUSAGE; 04918 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04919 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04920 numchans = ast_cli_netstats(NULL, fd, 1); 04921 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04922 return RESULT_SUCCESS; 04923 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2332 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, iax2_peer::capability, iax2_peer::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02333 { 02334 char status[30]; 02335 char cbuf[256]; 02336 struct iax2_peer *peer; 02337 char codec_buf[512]; 02338 int x = 0, codec = 0, load_realtime = 0; 02339 02340 if (argc < 4) 02341 return RESULT_SHOWUSAGE; 02342 02343 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02344 02345 peer = find_peer(argv[3], load_realtime); 02346 if (peer) { 02347 ast_cli(fd,"\n\n"); 02348 ast_cli(fd, " * Name : %s\n", peer->name); 02349 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02350 ast_cli(fd, " Context : %s\n", peer->context); 02351 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02352 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02353 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02354 ast_cli(fd, " Expire : %d\n", peer->expire); 02355 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02356 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)); 02357 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02358 ast_cli(fd, " Username : %s\n", peer->username); 02359 ast_cli(fd, " Codecs : "); 02360 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02361 ast_cli(fd, "%s\n", codec_buf); 02362 02363 ast_cli(fd, " Codec Order : ("); 02364 for(x = 0; x < 32 ; x++) { 02365 codec = ast_codec_pref_index(&peer->prefs,x); 02366 if(!codec) 02367 break; 02368 ast_cli(fd, "%s", ast_getformatname(codec)); 02369 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02370 ast_cli(fd, "|"); 02371 } 02372 02373 if (!x) 02374 ast_cli(fd, "none"); 02375 ast_cli(fd, ")\n"); 02376 02377 ast_cli(fd, " Status : "); 02378 peer_status(peer, status, sizeof(status)); 02379 ast_cli(fd, "%s\n",status); 02380 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02381 ast_cli(fd,"\n"); 02382 peer_unref(peer); 02383 } else { 02384 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02385 ast_cli(fd,"\n"); 02386 } 02387 02388 return RESULT_SUCCESS; 02389 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4690 of file chan_iax2.c.
References __iax2_show_peers().
04691 { 04692 return __iax2_show_peers(0, fd, NULL, argc, argv); 04693 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4762 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
04763 { 04764 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04765 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04766 struct iax2_registry *reg = NULL; 04767 04768 char host[80]; 04769 char perceived[80]; 04770 if (argc != 3) 04771 return RESULT_SHOWUSAGE; 04772 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04773 AST_LIST_LOCK(®istrations); 04774 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04775 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04776 if (reg->us.sin_addr.s_addr) 04777 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04778 else 04779 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04780 ast_cli(fd, FORMAT, host, 04781 (reg->dnsmgr) ? "Y" : "N", 04782 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04783 } 04784 AST_LIST_UNLOCK(®istrations); 04785 return RESULT_SUCCESS; 04786 #undef FORMAT 04787 #undef FORMAT2 04788 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2416 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, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02417 { 02418 struct iax_frame *cur; 02419 int cnt = 0, dead=0, final=0; 02420 02421 if (argc != 3) 02422 return RESULT_SHOWUSAGE; 02423 02424 AST_LIST_LOCK(&iaxq.queue); 02425 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02426 if (cur->retries < 0) 02427 dead++; 02428 if (cur->final) 02429 final++; 02430 cnt++; 02431 } 02432 AST_LIST_UNLOCK(&iaxq.queue); 02433 02434 ast_cli(fd, " IAX Statistics\n"); 02435 ast_cli(fd, "---------------------\n"); 02436 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02437 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02438 02439 return RESULT_SUCCESS; 02440 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4631 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, thread, and type.
04632 { 04633 struct iax2_thread *thread = NULL; 04634 time_t t; 04635 int threadcount = 0, dynamiccount = 0; 04636 char type; 04637 04638 if (argc != 3) 04639 return RESULT_SHOWUSAGE; 04640 04641 ast_cli(fd, "IAX2 Thread Information\n"); 04642 time(&t); 04643 ast_cli(fd, "Idle Threads:\n"); 04644 AST_LIST_LOCK(&idle_list); 04645 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04646 #ifdef DEBUG_SCHED_MULTITHREAD 04647 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04648 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04649 #else 04650 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04651 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04652 #endif 04653 threadcount++; 04654 } 04655 AST_LIST_UNLOCK(&idle_list); 04656 ast_cli(fd, "Active Threads:\n"); 04657 AST_LIST_LOCK(&active_list); 04658 AST_LIST_TRAVERSE(&active_list, thread, list) { 04659 if (thread->type == IAX_TYPE_DYNAMIC) 04660 type = 'D'; 04661 else 04662 type = 'P'; 04663 #ifdef DEBUG_SCHED_MULTITHREAD 04664 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04665 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04666 #else 04667 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04668 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04669 #endif 04670 threadcount++; 04671 } 04672 AST_LIST_UNLOCK(&active_list); 04673 ast_cli(fd, "Dynamic Threads:\n"); 04674 AST_LIST_LOCK(&dynamic_list); 04675 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04676 #ifdef DEBUG_SCHED_MULTITHREAD 04677 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04678 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04679 #else 04680 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04681 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04682 #endif 04683 dynamiccount++; 04684 } 04685 AST_LIST_UNLOCK(&dynamic_list); 04686 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04687 return RESULT_SUCCESS; 04688 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4448 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), 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, RESULT_SHOWUSAGE, RESULT_SUCCESS, user_unref(), and users.
04449 { 04450 regex_t regexbuf; 04451 int havepattern = 0; 04452 04453 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04454 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04455 04456 struct iax2_user *user = NULL; 04457 char auth[90]; 04458 char *pstr = ""; 04459 struct ao2_iterator i; 04460 04461 switch (argc) { 04462 case 5: 04463 if (!strcasecmp(argv[3], "like")) { 04464 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04465 return RESULT_SHOWUSAGE; 04466 havepattern = 1; 04467 } else 04468 return RESULT_SHOWUSAGE; 04469 case 3: 04470 break; 04471 default: 04472 return RESULT_SHOWUSAGE; 04473 } 04474 04475 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04476 i = ao2_iterator_init(users, 0); 04477 for (user = ao2_iterator_next(&i); user; 04478 user_unref(user), user = ao2_iterator_next(&i)) { 04479 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04480 continue; 04481 04482 if (!ast_strlen_zero(user->secret)) { 04483 ast_copy_string(auth,user->secret,sizeof(auth)); 04484 } else if (!ast_strlen_zero(user->inkeys)) { 04485 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04486 } else 04487 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04488 04489 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04490 pstr = "REQ Only"; 04491 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04492 pstr = "Disabled"; 04493 else 04494 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04495 04496 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04497 user->contexts ? user->contexts->context : context, 04498 user->ha ? "Yes" : "No", pstr); 04499 } 04500 04501 if (havepattern) 04502 regfree(®exbuf); 04503 04504 return RESULT_SUCCESS; 04505 #undef FORMAT 04506 #undef FORMAT2 04507 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3428 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.
03429 { 03430 int res; 03431 struct iax_ie_data ied0; 03432 struct iax_ie_data ied1; 03433 unsigned int transferid = (unsigned int)ast_random(); 03434 memset(&ied0, 0, sizeof(ied0)); 03435 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03436 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03437 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03438 03439 memset(&ied1, 0, sizeof(ied1)); 03440 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03441 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03442 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03443 03444 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03445 if (res) 03446 return -1; 03447 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03448 if (res) 03449 return -1; 03450 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03451 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03452 return 0; 03453 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2263 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02264 { 02265 if (argc != 4) 02266 return RESULT_SHOWUSAGE; 02267 02268 test_losspct = atoi(argv[3]); 02269 02270 return RESULT_SUCCESS; 02271 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3674 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03675 { 03676 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03677 struct iax_ie_data ied; 03678 char tmp[256], *context; 03679 ast_copy_string(tmp, dest, sizeof(tmp)); 03680 context = strchr(tmp, '@'); 03681 if (context) { 03682 *context = '\0'; 03683 context++; 03684 } 03685 memset(&ied, 0, sizeof(ied)); 03686 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03687 if (context) 03688 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03689 if (option_debug) 03690 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03691 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03692 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2722 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iaxq, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02723 { 02724 /* Lock the queue and place this packet at the end */ 02725 /* By setting this to 0, the network thread will send it for us, and 02726 queue retransmission if necessary */ 02727 fr->sentyet = 0; 02728 AST_LIST_LOCK(&iaxq.queue); 02729 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02730 iaxq.count++; 02731 AST_LIST_UNLOCK(&iaxq.queue); 02732 /* Wake up the network and scheduler thread */ 02733 if (netthreadid != AST_PTHREADT_NULL) 02734 pthread_kill(netthreadid, SIGURG); 02735 signal_condition(&sched_lock, &sched_cond); 02736 return 0; 02737 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6512 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06513 { 06514 /* Drop when trunk is about 5 seconds idle */ 06515 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06516 return 1; 06517 return 0; 06518 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4037 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().
04038 { 04039 struct ast_frame *f; 04040 struct iax2_trunk_peer *tpeer; 04041 void *tmp, *ptr; 04042 struct ast_iax2_meta_trunk_entry *met; 04043 struct ast_iax2_meta_trunk_mini *mtm; 04044 04045 f = &fr->af; 04046 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04047 if (tpeer) { 04048 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04049 /* Need to reallocate space */ 04050 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04051 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04052 ast_mutex_unlock(&tpeer->lock); 04053 return -1; 04054 } 04055 04056 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04057 tpeer->trunkdata = tmp; 04058 if (option_debug) 04059 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); 04060 } else { 04061 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)); 04062 ast_mutex_unlock(&tpeer->lock); 04063 return -1; 04064 } 04065 } 04066 04067 /* Append to meta frame */ 04068 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04069 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04070 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04071 mtm->len = htons(f->datalen); 04072 mtm->mini.callno = htons(pvt->callno); 04073 mtm->mini.ts = htons(0xffff & fr->ts); 04074 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04075 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04076 } else { 04077 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04078 /* Store call number and length in meta header */ 04079 met->callno = htons(pvt->callno); 04080 met->len = htons(f->datalen); 04081 /* Advance pointers/decrease length past trunk entry header */ 04082 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04083 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04084 } 04085 /* Copy actual trunk data */ 04086 memcpy(ptr, f->data, f->datalen); 04087 tpeer->trunkdatalen += f->datalen; 04088 04089 tpeer->calls++; 04090 ast_mutex_unlock(&tpeer->lock); 04091 } 04092 return 0; 04093 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6429 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06430 { 06431 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06432 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4980 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, error(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04981 { 04982 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04983 int res = -1; 04984 ast_mutex_lock(&iaxsl[callno]); 04985 if (iaxs[callno]) { 04986 /* If there's an outstanding error, return failure now */ 04987 if (!iaxs[callno]->error) { 04988 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04989 res = 0; 04990 /* Don't waste bandwidth sending null frames */ 04991 else if (f->frametype == AST_FRAME_NULL) 04992 res = 0; 04993 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04994 res = 0; 04995 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04996 res = 0; 04997 else 04998 /* Simple, just queue for transmission */ 04999 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05000 } else { 05001 if (option_debug) 05002 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05003 } 05004 } 05005 /* If it's already gone, just return */ 05006 ast_mutex_unlock(&iaxsl[callno]); 05007 return res; 05008 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1897 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().
01898 { 01899 int res = 0; 01900 struct iax_firmware *cur; 01901 if (!ast_strlen_zero(dev)) { 01902 ast_mutex_lock(&waresl.lock); 01903 cur = waresl.wares; 01904 while(cur) { 01905 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01906 res = ntohs(cur->fwh->version); 01907 break; 01908 } 01909 cur = cur->next; 01910 } 01911 ast_mutex_unlock(&waresl.lock); 01912 } 01913 return res; 01914 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 763 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00764 { 00765 if (iaxdebug) 00766 ast_verbose("%s", data); 00767 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 769 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00770 { 00771 ast_log(LOG_WARNING, "%s", data); 00772 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1916 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().
01917 { 01918 int res = -1; 01919 unsigned int bs = desc & 0xff; 01920 unsigned int start = (desc >> 8) & 0xffffff; 01921 unsigned int bytes; 01922 struct iax_firmware *cur; 01923 if (!ast_strlen_zero((char *)dev) && bs) { 01924 start *= bs; 01925 ast_mutex_lock(&waresl.lock); 01926 cur = waresl.wares; 01927 while(cur) { 01928 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01929 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01930 if (start < ntohl(cur->fwh->datalen)) { 01931 bytes = ntohl(cur->fwh->datalen) - start; 01932 if (bytes > bs) 01933 bytes = bs; 01934 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01935 } else { 01936 bytes = 0; 01937 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01938 } 01939 if (bytes == bs) 01940 res = 0; 01941 else 01942 res = 1; 01943 break; 01944 } 01945 cur = cur->next; 01946 } 01947 ast_mutex_unlock(&waresl.lock); 01948 } 01949 return res; 01950 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6700 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), 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::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06701 { 06702 struct iax_dual *d; 06703 struct ast_channel *chan1m, *chan2m; 06704 pthread_t th; 06705 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06706 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06707 if (chan2m && chan1m) { 06708 /* Make formats okay */ 06709 chan1m->readformat = chan1->readformat; 06710 chan1m->writeformat = chan1->writeformat; 06711 ast_channel_masquerade(chan1m, chan1); 06712 /* Setup the extensions and such */ 06713 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06714 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06715 chan1m->priority = chan1->priority; 06716 06717 /* We make a clone of the peer channel too, so we can play 06718 back the announcement */ 06719 /* Make formats okay */ 06720 chan2m->readformat = chan2->readformat; 06721 chan2m->writeformat = chan2->writeformat; 06722 ast_channel_masquerade(chan2m, chan2); 06723 /* Setup the extensions and such */ 06724 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06725 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06726 chan2m->priority = chan2->priority; 06727 if (ast_do_masquerade(chan2m)) { 06728 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06729 ast_hangup(chan2m); 06730 return -1; 06731 } 06732 } else { 06733 if (chan1m) 06734 ast_hangup(chan1m); 06735 if (chan2m) 06736 ast_hangup(chan2m); 06737 return -1; 06738 } 06739 if ((d = ast_calloc(1, sizeof(*d)))) { 06740 pthread_attr_t attr; 06741 06742 pthread_attr_init(&attr); 06743 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06744 06745 d->chan1 = chan1m; 06746 d->chan2 = chan2m; 06747 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06748 pthread_attr_destroy(&attr); 06749 return 0; 06750 } 06751 pthread_attr_destroy(&attr); 06752 free(d); 06753 } 06754 return -1; 06755 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6680 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().
06681 { 06682 struct ast_channel *chan1, *chan2; 06683 struct iax_dual *d; 06684 struct ast_frame *f; 06685 int ext; 06686 int res; 06687 d = stuff; 06688 chan1 = d->chan1; 06689 chan2 = d->chan2; 06690 free(d); 06691 f = ast_read(chan1); 06692 if (f) 06693 ast_frfree(f); 06694 res = ast_park_call(chan1, chan2, 0, &ext); 06695 ast_hangup(chan2); 06696 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06697 return NULL; 06698 }
Definition at line 1411 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().
01412 { 01413 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01414 if (new) { 01415 size_t afdatalen = new->afdatalen; 01416 memcpy(new, fr, sizeof(*new)); 01417 iax_frame_wrap(new, &fr->af); 01418 new->afdatalen = afdatalen; 01419 new->data = NULL; 01420 new->datalen = 0; 01421 new->direction = DIRECTION_INGRESS; 01422 new->retrans = -1; 01423 } 01424 return new; 01425 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 893 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().
00894 { 00895 if (thread->type == IAX_TYPE_DYNAMIC) { 00896 AST_LIST_LOCK(&dynamic_list); 00897 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00898 AST_LIST_UNLOCK(&dynamic_list); 00899 } else { 00900 AST_LIST_LOCK(&idle_list); 00901 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00902 AST_LIST_UNLOCK(&idle_list); 00903 } 00904 00905 return; 00906 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 798 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00799 { 00800 va_list args; 00801 char buf[1024]; 00802 00803 va_start(args, fmt); 00804 vsnprintf(buf, 1024, fmt, args); 00805 va_end(args); 00806 00807 ast_verbose(buf); 00808 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 774 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00775 { 00776 va_list args; 00777 char buf[1024]; 00778 00779 va_start(args, fmt); 00780 vsnprintf(buf, 1024, fmt, args); 00781 va_end(args); 00782 00783 ast_log(LOG_ERROR, buf); 00784 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 786 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00787 { 00788 va_list args; 00789 char buf[1024]; 00790 00791 va_start(args, fmt); 00792 vsnprintf(buf, 1024, fmt, args); 00793 va_end(args); 00794 00795 ast_log(LOG_WARNING, buf); 00796 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11053 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), 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_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, errno, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_peercallno_pvts, 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(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, netsock, option_verbose, outsock, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, pvt_cmp_cb(), pvt_hash_cb(), reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
11054 { 11055 char *config = "iax.conf"; 11056 int res = 0; 11057 int x; 11058 struct iax2_registry *reg = NULL; 11059 11060 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11061 if (!peers) 11062 return AST_MODULE_LOAD_FAILURE; 11063 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11064 if (!users) { 11065 ao2_ref(peers, -1); 11066 return AST_MODULE_LOAD_FAILURE; 11067 } 11068 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11069 if (!iax_peercallno_pvts) { 11070 ao2_ref(peers, -1); 11071 ao2_ref(users, -1); 11072 return AST_MODULE_LOAD_FAILURE; 11073 } 11074 11075 ast_custom_function_register(&iaxpeer_function); 11076 11077 iax_set_output(iax_debug_output); 11078 iax_set_error(iax_error_output); 11079 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11080 11081 #ifdef HAVE_ZAPTEL 11082 #ifdef ZT_TIMERACK 11083 timingfd = open("/dev/zap/timer", O_RDWR); 11084 if (timingfd < 0) 11085 #endif 11086 timingfd = open("/dev/zap/pseudo", O_RDWR); 11087 if (timingfd < 0) 11088 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11089 #endif 11090 11091 memset(iaxs, 0, sizeof(iaxs)); 11092 11093 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11094 ast_mutex_init(&iaxsl[x]); 11095 } 11096 11097 ast_cond_init(&sched_cond, NULL); 11098 11099 io = io_context_create(); 11100 sched = sched_context_create(); 11101 11102 if (!io || !sched) { 11103 ast_log(LOG_ERROR, "Out of memory\n"); 11104 return -1; 11105 } 11106 11107 netsock = ast_netsock_list_alloc(); 11108 if (!netsock) { 11109 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11110 return -1; 11111 } 11112 ast_netsock_init(netsock); 11113 11114 outsock = ast_netsock_list_alloc(); 11115 if (!outsock) { 11116 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11117 return -1; 11118 } 11119 ast_netsock_init(outsock); 11120 11121 ast_mutex_init(&waresl.lock); 11122 11123 AST_LIST_HEAD_INIT(&iaxq.queue); 11124 11125 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11126 11127 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11128 11129 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11130 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11131 11132 if(set_config(config, 0) == -1) 11133 return AST_MODULE_LOAD_DECLINE; 11134 11135 if (ast_channel_register(&iax2_tech)) { 11136 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11137 __unload_module(); 11138 return -1; 11139 } 11140 11141 if (ast_register_switch(&iax2_switch)) 11142 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11143 11144 res = start_network_thread(); 11145 if (!res) { 11146 if (option_verbose > 1) 11147 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11148 } else { 11149 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11150 ast_netsock_release(netsock); 11151 ast_netsock_release(outsock); 11152 } 11153 11154 AST_LIST_LOCK(®istrations); 11155 AST_LIST_TRAVERSE(®istrations, reg, entry) 11156 iax2_do_register(reg); 11157 AST_LIST_UNLOCK(®istrations); 11158 11159 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11160 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11161 11162 reload_firmware(0); 11163 iax_provision_reload(); 11164 return res; 11165 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3455 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03456 { 03457 ast_mutex_lock(&iaxsl[callno0]); 03458 while (ast_mutex_trylock(&iaxsl[callno1])) { 03459 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03460 } 03461 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1465 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_sched_add(), iaxsl, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01466 { 01467 int x; 01468 int res= 0; 01469 struct timeval now; 01470 if (iaxs[callno]->oseqno) { 01471 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01472 return -1; 01473 } 01474 if (callno & TRUNK_CALL_START) { 01475 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01476 return -1; 01477 } 01478 gettimeofday(&now, NULL); 01479 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01480 ast_mutex_lock(&iaxsl[x]); 01481 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01482 iaxs[x] = iaxs[callno]; 01483 iaxs[x]->callno = x; 01484 iaxs[callno] = NULL; 01485 /* Update the two timers that should have been started */ 01486 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01487 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01488 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01489 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01490 if (locked) 01491 ast_mutex_unlock(&iaxsl[callno]); 01492 res = x; 01493 if (!locked) 01494 ast_mutex_unlock(&iaxsl[x]); 01495 break; 01496 } 01497 ast_mutex_unlock(&iaxsl[x]); 01498 } 01499 if (x >= ARRAY_LEN(iaxs) - 1) { 01500 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01501 return -1; 01502 } 01503 if (option_debug) 01504 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01505 /* We move this call from a non-trunked to a trunked call */ 01506 update_max_trunk(); 01507 update_max_nontrunk(); 01508 return res; 01509 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4694 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04695 { 04696 ast_cli_netstats(s, -1, 0); 04697 astman_append(s, "\r\n"); 04698 return RESULT_SUCCESS; 04699 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4727 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04728 { 04729 char *a[] = { "iax2", "show", "users" }; 04730 int ret; 04731 const char *id = astman_get_header(m,"ActionID"); 04732 04733 if (!ast_strlen_zero(id)) 04734 astman_append(s, "ActionID: %s\r\n",id); 04735 ret = __iax2_show_peers(1, -1, s, 3, a ); 04736 astman_append(s, "\r\n\r\n" ); 04737 return ret; 04738 } /* /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 1431 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(), and softhangup_exec().
01432 { 01433 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01434 (cur->addr.sin_port == sin->sin_port)) { 01435 /* This is the main host */ 01436 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01437 (check_dcallno ? dcallno == cur->callno : 1) ) { 01438 /* That's us. Be sure we keep track of the peer call number */ 01439 return 1; 01440 } 01441 } 01442 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01443 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01444 /* We're transferring */ 01445 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01446 return 1; 01447 } 01448 return 0; 01449 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4101 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04102 { 04103 #if 0 04104 /* Debug with "fake encryption" */ 04105 int x; 04106 if (len % 16) 04107 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04108 for (x=0;x<len;x++) 04109 dst[x] = src[x] ^ 0xff; 04110 #else 04111 unsigned char lastblock[16] = { 0 }; 04112 int x; 04113 while(len > 0) { 04114 aes_decrypt(src, dst, dcx); 04115 for (x=0;x<16;x++) 04116 dst[x] ^= lastblock[x]; 04117 memcpy(lastblock, src, sizeof(lastblock)); 04118 dst += 16; 04119 src += 16; 04120 len -= 16; 04121 } 04122 #endif 04123 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4125 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04126 { 04127 #if 0 04128 /* Debug with "fake encryption" */ 04129 int x; 04130 if (len % 16) 04131 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04132 for (x=0;x<len;x++) 04133 dst[x] = src[x] ^ 0xff; 04134 #else 04135 unsigned char curblock[16] = { 0 }; 04136 int x; 04137 while(len > 0) { 04138 for (x=0;x<16;x++) 04139 curblock[x] ^= src[x]; 04140 aes_encrypt(curblock, dst, ecx); 04141 memcpy(curblock, dst, sizeof(curblock)); 04142 dst += 16; 04143 src += 16; 04144 len -= 16; 04145 } 04146 #endif 04147 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5305 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05306 { 05307 /* Select exactly one common encryption if there are any */ 05308 p->encmethods &= enc; 05309 if (p->encmethods) { 05310 if (p->encmethods & IAX_ENCRYPT_AES128) 05311 p->encmethods = IAX_ENCRYPT_AES128; 05312 else 05313 p->encmethods = 0; 05314 } 05315 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9028 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(), f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, option_debug, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
09029 { 09030 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09031 from the network, and queue them for delivery to the channels */ 09032 int res, count, wakeup; 09033 struct iax_frame *f; 09034 09035 if (timingfd > -1) 09036 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09037 09038 for(;;) { 09039 pthread_testcancel(); 09040 09041 /* Go through the queue, sending messages which have not yet been 09042 sent, and scheduling retransmissions if appropriate */ 09043 AST_LIST_LOCK(&iaxq.queue); 09044 count = 0; 09045 wakeup = -1; 09046 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09047 if (f->sentyet) 09048 continue; 09049 09050 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09051 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09052 wakeup = 1; 09053 continue; 09054 } 09055 09056 f->sentyet++; 09057 09058 if (iaxs[f->callno]) { 09059 send_packet(f); 09060 count++; 09061 } 09062 09063 ast_mutex_unlock(&iaxsl[f->callno]); 09064 09065 if (f->retries < 0) { 09066 /* This is not supposed to be retransmitted */ 09067 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09068 iaxq.count--; 09069 /* Free the iax frame */ 09070 iax_frame_free(f); 09071 } else { 09072 /* We need reliable delivery. Schedule a retransmission */ 09073 f->retries++; 09074 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09075 } 09076 } 09077 AST_LIST_TRAVERSE_SAFE_END 09078 AST_LIST_UNLOCK(&iaxq.queue); 09079 09080 pthread_testcancel(); 09081 09082 if (option_debug && count >= 20) 09083 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09084 09085 /* Now do the IO, and run scheduled tasks */ 09086 res = ast_io_wait(io, wakeup); 09087 if (res >= 0) { 09088 if (option_debug && res >= 20) 09089 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09090 } 09091 } 09092 return NULL; 09093 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1372 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().
01373 { 01374 struct chan_iax2_pvt *tmp; 01375 jb_conf jbconf; 01376 01377 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01378 return NULL; 01379 } 01380 01381 if (ast_string_field_init(tmp, 32)) { 01382 ao2_ref(tmp, -1); 01383 tmp = NULL; 01384 return NULL; 01385 } 01386 01387 tmp->prefs = prefs; 01388 tmp->callno = 0; 01389 tmp->peercallno = 0; 01390 tmp->transfercallno = 0; 01391 tmp->bridgecallno = 0; 01392 tmp->pingid = -1; 01393 tmp->lagid = -1; 01394 tmp->autoid = -1; 01395 tmp->authid = -1; 01396 tmp->initid = -1; 01397 01398 ast_string_field_set(tmp,exten, "s"); 01399 ast_string_field_set(tmp,host, host); 01400 01401 tmp->jb = jb_new(); 01402 tmp->jbid = -1; 01403 jbconf.max_jitterbuf = maxjitterbuffer; 01404 jbconf.resync_threshold = resyncthreshold; 01405 jbconf.max_contig_interp = maxjitterinterps; 01406 jb_setconf(tmp->jb,&jbconf); 01407 01408 return tmp; 01409 }
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 3173 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
03174 { 03175 if (ast_strlen_zero(data)) 03176 return; 03177 03178 pds->peer = strsep(&data, "/"); 03179 pds->exten = strsep(&data, "/"); 03180 pds->options = data; 03181 03182 if (pds->exten) { 03183 data = pds->exten; 03184 pds->exten = strsep(&data, "@"); 03185 pds->context = data; 03186 } 03187 03188 if (strchr(pds->peer, '@')) { 03189 data = pds->peer; 03190 pds->username = strsep(&data, "@"); 03191 pds->peer = data; 03192 } 03193 03194 if (pds->username) { 03195 data = pds->username; 03196 pds->username = strsep(&data, ":"); 03197 pds->password = data; 03198 } 03199 03200 data = pds->peer; 03201 pds->peer = strsep(&data, ":"); 03202 pds->port = data; 03203 03204 /* check for a key name wrapped in [] in the secret position, if found, 03205 move it to the key field instead 03206 */ 03207 if (pds->password && (pds->password[0] == '[')) { 03208 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03209 pds->password = NULL; 03210 } 03211 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1110 of file chan_iax2.c.
Referenced by load_module().
01111 { 01112 struct iax2_peer *peer = obj, *peer2 = arg; 01113 01114 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01115 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9726 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09727 { 09728 struct iax2_peer *peer = obj; 09729 09730 ast_set_flag(peer, IAX_DELME); 09731 09732 return 0; 09733 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9251 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().
09252 { 09253 struct iax2_peer *peer = obj; 09254 09255 ast_free_ha(peer->ha); 09256 09257 if (peer->callno > 0) { 09258 ast_mutex_lock(&iaxsl[peer->callno]); 09259 iax2_destroy(peer->callno); 09260 ast_mutex_unlock(&iaxsl[peer->callno]); 09261 } 09262 09263 register_peer_exten(peer, 0); 09264 09265 if (peer->dnsmgr) 09266 ast_dnsmgr_release(peer->dnsmgr); 09267 09268 ast_string_field_free_memory(peer); 09269 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1100 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01101 { 01102 const struct iax2_peer *peer = obj; 01103 01104 return ast_str_hash(peer->name); 01105 }
Definition at line 1157 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().
01158 { 01159 ao2_ref(peer, +1); 01160 return peer; 01161 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11024 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11025 { 11026 struct iax2_peer *peer = obj; 11027 11028 if (peer->sockfd < 0) 11029 peer->sockfd = defaultsockfd; 11030 11031 return 0; 11032 }
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 9178 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, netsock, option_debug, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
09179 { 09180 struct sockaddr_in sin; 09181 int nonlocal = 1; 09182 int port = IAX_DEFAULT_PORTNO; 09183 int sockfd = defaultsockfd; 09184 char *tmp; 09185 char *addr; 09186 char *portstr; 09187 09188 if (!(tmp = ast_strdupa(srcaddr))) 09189 return -1; 09190 09191 addr = strsep(&tmp, ":"); 09192 portstr = tmp; 09193 09194 if (portstr) { 09195 port = atoi(portstr); 09196 if (port < 1) 09197 port = IAX_DEFAULT_PORTNO; 09198 } 09199 09200 if (!ast_get_ip(&sin, addr)) { 09201 struct ast_netsock *sock; 09202 int res; 09203 09204 sin.sin_port = 0; 09205 sin.sin_family = AF_INET; 09206 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09207 if (res == 0) { 09208 /* ip address valid. */ 09209 sin.sin_port = htons(port); 09210 if (!(sock = ast_netsock_find(netsock, &sin))) 09211 sock = ast_netsock_find(outsock, &sin); 09212 if (sock) { 09213 sockfd = ast_netsock_sockfd(sock); 09214 nonlocal = 0; 09215 } else { 09216 unsigned int orig_saddr = sin.sin_addr.s_addr; 09217 /* INADDR_ANY matches anyway! */ 09218 sin.sin_addr.s_addr = INADDR_ANY; 09219 if (ast_netsock_find(netsock, &sin)) { 09220 sin.sin_addr.s_addr = orig_saddr; 09221 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09222 if (sock) { 09223 sockfd = ast_netsock_sockfd(sock); 09224 ast_netsock_unref(sock); 09225 nonlocal = 0; 09226 } else { 09227 nonlocal = 2; 09228 } 09229 } 09230 } 09231 } 09232 } 09233 09234 peer->sockfd = sockfd; 09235 09236 if (nonlocal == 1) { 09237 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09238 srcaddr, peer->name); 09239 return -1; 09240 } else if (nonlocal == 2) { 09241 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09242 srcaddr, peer->name); 09243 return -1; 09244 } else { 09245 if (option_debug) 09246 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09247 return 0; 09248 } 09249 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2309 of file chan_iax2.c.
References 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().
02310 { 02311 int res = 0; 02312 if (peer->maxms) { 02313 if (peer->lastms < 0) { 02314 ast_copy_string(status, "UNREACHABLE", statuslen); 02315 } else if (peer->lastms > peer->maxms) { 02316 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02317 res = 1; 02318 } else if (peer->lastms) { 02319 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02320 res = 1; 02321 } else { 02322 ast_copy_string(status, "UNKNOWN", statuslen); 02323 } 02324 } else { 02325 ast_copy_string(status, "Unmonitored", statuslen); 02326 res = -1; 02327 } 02328 return res; 02329 }
Definition at line 1163 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(), 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(), set_config(), socket_process(), unlink_peer(), and update_registry().
01164 { 01165 ao2_ref(peer, -1); 01166 return NULL; 01167 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10185 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10186 { 10187 struct ao2_iterator i; 10188 struct iax2_peer *peer; 10189 10190 i = ao2_iterator_init(peers, 0); 10191 while ((peer = ao2_iterator_next(&i))) { 10192 iax2_poke_peer(peer, 0); 10193 peer_unref(peer); 10194 } 10195 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9784 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09785 { 09786 struct iax2_peer *peer; 09787 struct ao2_iterator i; 09788 09789 i = ao2_iterator_init(peers, 0); 09790 while ((peer = ao2_iterator_next(&i))) { 09791 if (ast_test_flag(peer, IAX_DELME)) 09792 unlink_peer(peer); 09793 peer_unref(peer); 09794 } 09795 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9770 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, user_unref(), and users.
Referenced by reload_config().
09771 { 09772 struct iax2_user *user; 09773 struct ao2_iterator i; 09774 09775 i = ao2_iterator_init(users, 0); 09776 while ((user = ao2_iterator_next(&i))) { 09777 if (ast_test_flag(user, IAX_DELME)) 09778 ao2_unlink(users, user); 09779 user_unref(user); 09780 } 09781 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11041 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11042 { 11043 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11044 11045 /* The frames_received field is used to hold whether we're matching 11046 * against a full frame or not ... */ 11047 11048 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11049 pvt2->frames_received) ? CMP_MATCH : 0; 11050 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1333 of file chan_iax2.c.
References 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, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and chan_iax2_pvt::vars.
Referenced by new_iax().
01334 { 01335 struct chan_iax2_pvt *pvt = obj; 01336 struct iax_frame *cur = NULL; 01337 01338 iax2_destroy_helper(pvt); 01339 01340 /* Already gone */ 01341 ast_set_flag(pvt, IAX_ALREADYGONE); 01342 01343 AST_LIST_LOCK(&iaxq.queue); 01344 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01345 /* Cancel any pending transmissions */ 01346 if (cur->callno == pvt->callno) { 01347 cur->retries = -1; 01348 } 01349 } 01350 AST_LIST_UNLOCK(&iaxq.queue); 01351 01352 if (pvt->reg) { 01353 pvt->reg->callno = 0; 01354 } 01355 01356 if (!pvt->owner) { 01357 jb_frame frame; 01358 if (pvt->vars) { 01359 ast_variables_destroy(pvt->vars); 01360 pvt->vars = NULL; 01361 } 01362 01363 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01364 iax2_frame_free(frame.data); 01365 } 01366 01367 jb_destroy(pvt->jb); 01368 ast_string_field_free_memory(pvt); 01369 } 01370 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11034 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11035 { 11036 const struct chan_iax2_pvt *pvt = obj; 11037 11038 return pvt->peercallno; 11039 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5287 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().
05288 { 05289 struct ast_iax2_full_hdr fh; 05290 fh.scallno = htons(src | IAX_FLAG_FULL); 05291 fh.dcallno = htons(dst); 05292 fh.ts = 0; 05293 fh.oseqno = 0; 05294 fh.iseqno = 0; 05295 fh.type = AST_FRAME_IAX; 05296 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05297 if (iaxdebug) 05298 iax_showframe(NULL, &fh, 0, sin, 0); 05299 if (option_debug) 05300 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05301 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05302 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05303 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2784 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.
02785 { 02786 struct ast_variable *var = NULL; 02787 struct ast_variable *tmp; 02788 struct iax2_peer *peer=NULL; 02789 time_t regseconds = 0, nowtime; 02790 int dynamic=0; 02791 02792 if (peername) { 02793 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02794 if (!var && sin) 02795 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02796 } else if (sin) { 02797 char porta[25]; 02798 sprintf(porta, "%d", ntohs(sin->sin_port)); 02799 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02800 if (var) { 02801 /* We'll need the peer name in order to build the structure! */ 02802 for (tmp = var; tmp; tmp = tmp->next) { 02803 if (!strcasecmp(tmp->name, "name")) 02804 peername = tmp->value; 02805 } 02806 } 02807 } 02808 if (!var && peername) { /* Last ditch effort */ 02809 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02810 /*!\note 02811 * If this one loaded something, then we need to ensure that the host 02812 * field matched. The only reason why we can't have this as a criteria 02813 * is because we only have the IP address and the host field might be 02814 * set as a name (and the reverse PTR might not match). 02815 */ 02816 if (var && sin) { 02817 for (tmp = var; tmp; tmp = tmp->next) { 02818 if (!strcasecmp(tmp->name, "host")) { 02819 struct ast_hostent ahp; 02820 struct hostent *hp; 02821 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02822 /* No match */ 02823 ast_variables_destroy(var); 02824 var = NULL; 02825 } 02826 break; 02827 } 02828 } 02829 } 02830 } 02831 if (!var) 02832 return NULL; 02833 02834 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02835 02836 if (!peer) { 02837 ast_variables_destroy(var); 02838 return NULL; 02839 } 02840 02841 for (tmp = var; tmp; tmp = tmp->next) { 02842 /* Make sure it's not a user only... */ 02843 if (!strcasecmp(tmp->name, "type")) { 02844 if (strcasecmp(tmp->value, "friend") && 02845 strcasecmp(tmp->value, "peer")) { 02846 /* Whoops, we weren't supposed to exist! */ 02847 peer = peer_unref(peer); 02848 break; 02849 } 02850 } else if (!strcasecmp(tmp->name, "regseconds")) { 02851 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02852 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02853 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02854 } else if (!strcasecmp(tmp->name, "port")) { 02855 peer->addr.sin_port = htons(atoi(tmp->value)); 02856 } else if (!strcasecmp(tmp->name, "host")) { 02857 if (!strcasecmp(tmp->value, "dynamic")) 02858 dynamic = 1; 02859 } 02860 } 02861 02862 ast_variables_destroy(var); 02863 02864 if (!peer) 02865 return NULL; 02866 02867 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02868 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02869 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02870 if (peer->expire > -1) { 02871 if (!ast_sched_del(sched, peer->expire)) { 02872 peer->expire = -1; 02873 peer_unref(peer); 02874 } 02875 } 02876 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02877 if (peer->expire == -1) 02878 peer_unref(peer); 02879 } 02880 ao2_link(peers, peer); 02881 if (ast_test_flag(peer, IAX_DYNAMIC)) 02882 reg_source_db(peer); 02883 } else { 02884 ast_set_flag(peer, IAX_TEMPONLY); 02885 } 02886 02887 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02888 time(&nowtime); 02889 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02890 memset(&peer->addr, 0, sizeof(peer->addr)); 02891 realtime_update_peer(peer->name, &peer->addr, 0); 02892 if (option_debug) 02893 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02894 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02895 } 02896 else { 02897 if (option_debug) 02898 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02899 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02900 } 02901 } 02902 02903 return peer; 02904 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2977 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02978 { 02979 char port[10]; 02980 char regseconds[20]; 02981 02982 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02983 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02984 ast_update_realtime("iaxpeers", "name", peername, 02985 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02986 "regseconds", regseconds, NULL); 02987 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2906 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.
02907 { 02908 struct ast_variable *var; 02909 struct ast_variable *tmp; 02910 struct iax2_user *user=NULL; 02911 02912 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02913 if (!var) 02914 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02915 if (!var && sin) { 02916 char porta[6]; 02917 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02918 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02919 if (!var) 02920 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02921 } 02922 if (!var) { /* Last ditch effort */ 02923 var = ast_load_realtime("iaxusers", "name", username, NULL); 02924 /*!\note 02925 * If this one loaded something, then we need to ensure that the host 02926 * field matched. The only reason why we can't have this as a criteria 02927 * is because we only have the IP address and the host field might be 02928 * set as a name (and the reverse PTR might not match). 02929 */ 02930 if (var) { 02931 for (tmp = var; tmp; tmp = tmp->next) { 02932 if (!strcasecmp(tmp->name, "host")) { 02933 struct ast_hostent ahp; 02934 struct hostent *hp; 02935 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02936 /* No match */ 02937 ast_variables_destroy(var); 02938 var = NULL; 02939 } 02940 break; 02941 } 02942 } 02943 } 02944 } 02945 if (!var) 02946 return NULL; 02947 02948 tmp = var; 02949 while(tmp) { 02950 /* Make sure it's not a peer only... */ 02951 if (!strcasecmp(tmp->name, "type")) { 02952 if (strcasecmp(tmp->value, "friend") && 02953 strcasecmp(tmp->value, "user")) { 02954 return NULL; 02955 } 02956 } 02957 tmp = tmp->next; 02958 } 02959 02960 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02961 02962 ast_variables_destroy(var); 02963 02964 if (!user) 02965 return NULL; 02966 02967 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02968 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02969 ao2_link(users, user); 02970 } else { 02971 ast_set_flag(user, IAX_TEMPONLY); 02972 } 02973 02974 return user; 02975 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6068 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, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
06069 { 06070 char data[80]; 06071 struct in_addr in; 06072 char *c, *d; 06073 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06074 c = strchr(data, ':'); 06075 if (c) { 06076 *c = '\0'; 06077 c++; 06078 if (inet_aton(data, &in)) { 06079 d = strchr(c, ':'); 06080 if (d) { 06081 *d = '\0'; 06082 d++; 06083 if (option_verbose > 2) 06084 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06085 ast_inet_ntoa(in), atoi(c), atoi(d)); 06086 iax2_poke_peer(p, 0); 06087 p->expiry = atoi(d); 06088 memset(&p->addr, 0, sizeof(p->addr)); 06089 p->addr.sin_family = AF_INET; 06090 p->addr.sin_addr = in; 06091 p->addr.sin_port = htons(atoi(c)); 06092 if (p->expire > -1) { 06093 if (!ast_sched_del(sched, p->expire)) { 06094 p->expire = -1; 06095 peer_unref(p); 06096 } 06097 } 06098 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06099 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06100 if (p->expire == -1) 06101 peer_unref(p); 06102 if (iax2_regfunk) 06103 iax2_regfunk(p->name, 1); 06104 register_peer_exten(p, 1); 06105 } 06106 06107 } 06108 } 06109 } 06110 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5988 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_free, ast_strdup, ast_strlen_zero(), ext, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
05989 { 05990 char multi[256]; 05991 char *stringp, *ext; 05992 if (!ast_strlen_zero(regcontext)) { 05993 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05994 stringp = multi; 05995 while((ext = strsep(&stringp, "&"))) { 05996 if (onoff) { 05997 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05998 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05999 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06000 } else 06001 ast_context_remove_extension(regcontext, ext, 1, NULL); 06002 } 06003 } 06004 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5451 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, 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, IAX_STATE_UNCHANGED, iaxs, iaxsl, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by handle_request_register(), and socket_process().
05452 { 05453 char requeststr[256] = ""; 05454 char peer[256] = ""; 05455 char md5secret[256] = ""; 05456 char rsasecret[256] = ""; 05457 char secret[256] = ""; 05458 struct iax2_peer *p = NULL; 05459 struct ast_key *key; 05460 char *keyn; 05461 int x; 05462 int expire = 0; 05463 int res = -1; 05464 05465 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05466 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05467 if (ies->username) 05468 ast_copy_string(peer, ies->username, sizeof(peer)); 05469 if (ies->password) 05470 ast_copy_string(secret, ies->password, sizeof(secret)); 05471 if (ies->md5_result) 05472 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05473 if (ies->rsa_result) 05474 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05475 if (ies->refresh) 05476 expire = ies->refresh; 05477 05478 if (ast_strlen_zero(peer)) { 05479 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05480 return -1; 05481 } 05482 05483 /* SLD: first call to lookup peer during registration */ 05484 ast_mutex_unlock(&iaxsl[callno]); 05485 p = find_peer(peer, 1); 05486 ast_mutex_lock(&iaxsl[callno]); 05487 if (!p || !iaxs[callno]) { 05488 if (authdebug && !p) 05489 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05490 goto return_unref; 05491 } 05492 05493 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05494 if (authdebug) 05495 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05496 goto return_unref; 05497 } 05498 05499 if (!ast_apply_ha(p->ha, sin)) { 05500 if (authdebug) 05501 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05502 goto return_unref; 05503 } 05504 if (!inaddrcmp(&p->addr, sin)) 05505 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05506 ast_string_field_set(iaxs[callno], secret, p->secret); 05507 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05508 /* Check secret against what we have on file */ 05509 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05510 if (!ast_strlen_zero(p->inkeys)) { 05511 char tmpkeys[256]; 05512 char *stringp=NULL; 05513 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05514 stringp=tmpkeys; 05515 keyn = strsep(&stringp, ":"); 05516 while(keyn) { 05517 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05518 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05519 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05520 break; 05521 } else if (!key) 05522 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05523 keyn = strsep(&stringp, ":"); 05524 } 05525 if (!keyn) { 05526 if (authdebug) 05527 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05528 goto return_unref; 05529 } 05530 } else { 05531 if (authdebug) 05532 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05533 goto return_unref; 05534 } 05535 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05536 struct MD5Context md5; 05537 unsigned char digest[16]; 05538 char *tmppw, *stringp; 05539 05540 tmppw = ast_strdupa(p->secret); 05541 stringp = tmppw; 05542 while((tmppw = strsep(&stringp, ";"))) { 05543 MD5Init(&md5); 05544 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05545 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05546 MD5Final(digest, &md5); 05547 for (x=0;x<16;x++) 05548 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05549 if (!strcasecmp(requeststr, md5secret)) 05550 break; 05551 } 05552 if (tmppw) { 05553 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05554 } else { 05555 if (authdebug) 05556 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05557 goto return_unref; 05558 } 05559 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05560 /* They've provided a plain text password and we support that */ 05561 if (strcmp(secret, p->secret)) { 05562 if (authdebug) 05563 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05564 goto return_unref; 05565 } else 05566 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05567 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05568 if (authdebug) 05569 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05570 goto return_unref; 05571 } 05572 ast_string_field_set(iaxs[callno], peer, peer); 05573 /* Choose lowest expiry number */ 05574 if (expire && (expire < iaxs[callno]->expiry)) 05575 iaxs[callno]->expiry = expire; 05576 05577 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05578 05579 res = 0; 05580 05581 return_unref: 05582 if (p) 05583 peer_unref(p); 05584 05585 return res; 05586 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6247 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, 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, LOG_WARNING, peer_unref(), and send_command().
Referenced by socket_process().
06248 { 06249 struct iax_ie_data ied; 06250 struct iax2_peer *p; 06251 char challenge[10]; 06252 const char *peer_name; 06253 int res = -1; 06254 06255 peer_name = ast_strdupa(iaxs[callno]->peer); 06256 06257 /* SLD: third call to find_peer in registration */ 06258 ast_mutex_unlock(&iaxsl[callno]); 06259 p = find_peer(peer_name, 1); 06260 ast_mutex_lock(&iaxsl[callno]); 06261 if (!iaxs[callno]) 06262 goto return_unref; 06263 if (!p) { 06264 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06265 goto return_unref; 06266 } 06267 06268 memset(&ied, 0, sizeof(ied)); 06269 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06270 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06271 /* Build the challenge */ 06272 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06273 ast_string_field_set(iaxs[callno], challenge, challenge); 06274 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06275 } 06276 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06277 06278 res = 0; 06279 06280 return_unref: 06281 peer_unref(p); 06282 06283 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 06284 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6286 of file chan_iax2.c.
References iax2_registry::addr, 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().
06287 { 06288 struct iax2_registry *reg; 06289 /* Start pessimistic */ 06290 struct iax_ie_data ied; 06291 char peer[256] = ""; 06292 char challenge[256] = ""; 06293 int res; 06294 int authmethods = 0; 06295 if (ies->authmethods) 06296 authmethods = ies->authmethods; 06297 if (ies->username) 06298 ast_copy_string(peer, ies->username, sizeof(peer)); 06299 if (ies->challenge) 06300 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06301 memset(&ied, 0, sizeof(ied)); 06302 reg = iaxs[callno]->reg; 06303 if (reg) { 06304 if (inaddrcmp(®->addr, sin)) { 06305 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06306 return -1; 06307 } 06308 if (ast_strlen_zero(reg->secret)) { 06309 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06310 reg->regstate = REG_STATE_NOAUTH; 06311 return -1; 06312 } 06313 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06314 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06315 if (reg->secret[0] == '[') { 06316 char tmpkey[256]; 06317 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06318 tmpkey[strlen(tmpkey) - 1] = '\0'; 06319 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06320 } else 06321 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06322 if (!res) { 06323 reg->regstate = REG_STATE_AUTHSENT; 06324 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06325 } else 06326 return -1; 06327 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06328 } else 06329 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06330 return -1; 06331 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4740 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().
04741 { 04742 switch(regstate) { 04743 case REG_STATE_UNREGISTERED: 04744 return "Unregistered"; 04745 case REG_STATE_REGSENT: 04746 return "Request Sent"; 04747 case REG_STATE_AUTHSENT: 04748 return "Auth. Sent"; 04749 case REG_STATE_REGISTERED: 04750 return "Registered"; 04751 case REG_STATE_REJECTED: 04752 return "Rejected"; 04753 case REG_STATE_TIMEOUT: 04754 return "Timeout"; 04755 case REG_STATE_NOAUTH: 04756 return "No Authentication"; 04757 default: 04758 return "Unknown"; 04759 } 04760 }
static int reload | ( | void | ) | [static] |
Definition at line 10222 of file chan_iax2.c.
References reload_config().
10223 { 10224 return reload_config(); 10225 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10196 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, iax2_do_register(), iax_provision_reload(), poke_all_peers(), prune_peers(), prune_users(), reload_firmware(), and set_config().
10197 { 10198 char *config = "iax.conf"; 10199 struct iax2_registry *reg; 10200 10201 if (set_config(config, 1) > 0) { 10202 prune_peers(); 10203 prune_users(); 10204 AST_LIST_LOCK(®istrations); 10205 AST_LIST_TRAVERSE(®istrations, reg, entry) 10206 iax2_do_register(reg); 10207 AST_LIST_UNLOCK(®istrations); 10208 /* Qualify hosts, too */ 10209 poke_all_peers(); 10210 } 10211 reload_firmware(0); 10212 iax_provision_reload(); 10213 10214 return 0; 10215 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1953 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().
01954 { 01955 struct iax_firmware *cur, *curl, *curp; 01956 DIR *fwd; 01957 struct dirent *de; 01958 char dir[256]; 01959 char fn[256]; 01960 /* Mark all as dead */ 01961 ast_mutex_lock(&waresl.lock); 01962 cur = waresl.wares; 01963 while(cur) { 01964 cur->dead = 1; 01965 cur = cur->next; 01966 } 01967 01968 /* Now that we've freed them, load the new ones */ 01969 if (!unload) { 01970 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01971 fwd = opendir(dir); 01972 if (fwd) { 01973 while((de = readdir(fwd))) { 01974 if (de->d_name[0] != '.') { 01975 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01976 if (!try_firmware(fn)) { 01977 if (option_verbose > 1) 01978 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01979 } 01980 } 01981 } 01982 closedir(fwd); 01983 } else 01984 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01985 } 01986 01987 /* Clean up leftovers */ 01988 cur = waresl.wares; 01989 curp = NULL; 01990 while(cur) { 01991 curl = cur; 01992 cur = cur->next; 01993 if (curl->dead) { 01994 if (curp) { 01995 curp->next = cur; 01996 } else { 01997 waresl.wares = cur; 01998 } 01999 destroy_firmware(curl); 02000 } else { 02001 curp = cur; 02002 } 02003 } 02004 ast_mutex_unlock(&waresl.lock); 02005 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1248 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(), and socket_process().
01249 { 01250 if (!pvt->peercallno) { 01251 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01252 return; 01253 } 01254 01255 ao2_unlink(iax_peercallno_pvts, pvt); 01256 }
Definition at line 6790 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().
06791 { 06792 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06793 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06794 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06795 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06796 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06797 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06798 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06799 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9000 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), option_debug, and sched.
Referenced by start_network_thread().
09001 { 09002 int count; 09003 int res; 09004 struct timeval tv; 09005 struct timespec ts; 09006 09007 for (;;) { 09008 res = ast_sched_wait(sched); 09009 if ((res > 1000) || (res < 0)) 09010 res = 1000; 09011 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09012 ts.tv_sec = tv.tv_sec; 09013 ts.tv_nsec = tv.tv_usec * 1000; 09014 09015 pthread_testcancel(); 09016 ast_mutex_lock(&sched_lock); 09017 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09018 ast_mutex_unlock(&sched_lock); 09019 pthread_testcancel(); 09020 09021 count = ast_sched_runq(sched); 09022 if (option_debug && count >= 20) 09023 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09024 } 09025 return NULL; 09026 }
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 2637 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), AST_SCHED_DEL, ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02638 { 02639 int type, len; 02640 int ret; 02641 int needfree = 0; 02642 struct ast_channel *owner = NULL; 02643 struct ast_channel *bridge = NULL; 02644 02645 /* Attempt to recover wrapped timestamps */ 02646 unwrap_timestamp(fr); 02647 02648 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02649 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02650 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02651 else { 02652 #if 0 02653 if (option_debug) 02654 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02655 #endif 02656 fr->af.delivery = ast_tv(0,0); 02657 } 02658 02659 type = JB_TYPE_CONTROL; 02660 len = 0; 02661 02662 if(fr->af.frametype == AST_FRAME_VOICE) { 02663 type = JB_TYPE_VOICE; 02664 len = ast_codec_get_samples(&fr->af) / 8; 02665 } else if(fr->af.frametype == AST_FRAME_CNG) { 02666 type = JB_TYPE_SILENCE; 02667 } 02668 02669 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02670 if (tsout) 02671 *tsout = fr->ts; 02672 __do_deliver(fr); 02673 return -1; 02674 } 02675 02676 if ((owner = iaxs[fr->callno]->owner)) 02677 bridge = ast_bridged_channel(owner); 02678 02679 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02680 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02681 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02682 jb_frame frame; 02683 02684 /* deliver any frames in the jb */ 02685 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02686 __do_deliver(frame.data); 02687 /* __do_deliver() can make the call disappear */ 02688 if (!iaxs[fr->callno]) 02689 return -1; 02690 } 02691 02692 jb_reset(iaxs[fr->callno]->jb); 02693 02694 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02695 02696 /* deliver this frame now */ 02697 if (tsout) 02698 *tsout = fr->ts; 02699 __do_deliver(fr); 02700 return -1; 02701 } 02702 02703 /* insert into jitterbuffer */ 02704 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02705 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02706 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02707 if (ret == JB_DROP) { 02708 needfree++; 02709 } else if (ret == JB_SCHED) { 02710 update_jbsched(iaxs[fr->callno]); 02711 } 02712 if (tsout) 02713 *tsout = fr->ts; 02714 if (needfree) { 02715 /* Free our iax frame */ 02716 iax2_frame_free(fr); 02717 return -1; 02718 } 02719 return 0; 02720 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5024 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(), send_command_locked(), and socket_process().
05025 { 05026 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05027 }
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 5043 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().
05044 { 05045 int call_num = i->callno; 05046 /* It is assumed that the callno has already been locked */ 05047 iax2_predestroy(i->callno); 05048 if (!iaxs[call_num]) 05049 return -1; 05050 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05051 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5053 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05054 { 05055 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05056 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5029 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().
05030 { 05031 int res; 05032 ast_mutex_lock(&iaxsl[callno]); 05033 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05034 ast_mutex_unlock(&iaxsl[callno]); 05035 return res; 05036 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 5058 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05059 { 05060 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05061 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1054 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01055 { 01056 #ifdef SCHED_MULTITHREADED 01057 if (schedule_action(__send_lagrq, data)) 01058 #endif 01059 __send_lagrq(data); 01060 return 0; 01061 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2078 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), errno, error(), 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().
02079 { 02080 int res; 02081 int callno = f->callno; 02082 02083 /* Don't send if there was an error, but return error instead */ 02084 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02085 return -1; 02086 02087 /* Called with iaxsl held */ 02088 if (option_debug > 2 && iaxdebug) 02089 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)); 02090 if (f->transfer) { 02091 if (iaxdebug) 02092 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02093 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02094 sizeof(iaxs[callno]->transfer)); 02095 } else { 02096 if (iaxdebug) 02097 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02098 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02099 sizeof(iaxs[callno]->addr)); 02100 } 02101 if (res < 0) { 02102 if (option_debug && iaxdebug) 02103 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02104 handle_error(); 02105 } else 02106 res = 0; 02107 return res; 02108 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1014 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01015 { 01016 #ifdef SCHED_MULTITHREADED 01017 if (schedule_action(__send_ping, data)) 01018 #endif 01019 __send_ping(data); 01020 return 0; 01021 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6468 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().
06469 { 06470 int res = 0; 06471 struct iax_frame *fr; 06472 struct ast_iax2_meta_hdr *meta; 06473 struct ast_iax2_meta_trunk_hdr *mth; 06474 int calls = 0; 06475 06476 /* Point to frame */ 06477 fr = (struct iax_frame *)tpeer->trunkdata; 06478 /* Point to meta data */ 06479 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06480 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06481 if (tpeer->trunkdatalen) { 06482 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06483 meta->zeros = 0; 06484 meta->metacmd = IAX_META_TRUNK; 06485 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06486 meta->cmddata = IAX_META_TRUNK_MINI; 06487 else 06488 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06489 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06490 /* And the rest of the ast_iax2 header */ 06491 fr->direction = DIRECTION_OUTGRESS; 06492 fr->retrans = -1; 06493 fr->transfer = 0; 06494 /* Any appropriate call will do */ 06495 fr->data = fr->afdata; 06496 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06497 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06498 calls = tpeer->calls; 06499 #if 0 06500 if (option_debug) 06501 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)); 06502 #endif 06503 /* Reset transmit trunk side data */ 06504 tpeer->trunkdatalen = 0; 06505 tpeer->calls = 0; 06506 } 06507 if (res < 0) 06508 return res; 06509 return calls; 06510 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9828 of file chan_iax2.c.
References __ao2_link(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), 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_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), 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(), peers, portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09829 { 09830 struct ast_config *cfg, *ucfg; 09831 int capability=iax2_capability; 09832 struct ast_variable *v; 09833 char *cat; 09834 const char *utype; 09835 const char *tosval; 09836 int format; 09837 int portno = IAX_DEFAULT_PORTNO; 09838 int x; 09839 struct iax2_user *user; 09840 struct iax2_peer *peer; 09841 struct ast_netsock *ns; 09842 #if 0 09843 static unsigned short int last_port=0; 09844 #endif 09845 09846 cfg = ast_config_load(config_file); 09847 09848 if (!cfg) { 09849 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09850 return -1; 09851 } 09852 09853 if (reload) { 09854 set_config_destroy(); 09855 } 09856 09857 /* Reset global codec prefs */ 09858 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09859 09860 /* Reset Global Flags */ 09861 memset(&globalflags, 0, sizeof(globalflags)); 09862 ast_set_flag(&globalflags, IAX_RTUPDATE); 09863 09864 #ifdef SO_NO_CHECK 09865 nochecksums = 0; 09866 #endif 09867 09868 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09869 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09870 09871 maxauthreq = 3; 09872 09873 v = ast_variable_browse(cfg, "general"); 09874 09875 /* Seed initial tos value */ 09876 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09877 if (tosval) { 09878 if (ast_str2tos(tosval, &tos)) 09879 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09880 } 09881 while(v) { 09882 if (!strcasecmp(v->name, "bindport")){ 09883 if (reload) 09884 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09885 else 09886 portno = atoi(v->value); 09887 } else if (!strcasecmp(v->name, "pingtime")) 09888 ping_time = atoi(v->value); 09889 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09890 if (reload) { 09891 if (atoi(v->value) != iaxthreadcount) 09892 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09893 } else { 09894 iaxthreadcount = atoi(v->value); 09895 if (iaxthreadcount < 1) { 09896 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09897 iaxthreadcount = 1; 09898 } else if (iaxthreadcount > 256) { 09899 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09900 iaxthreadcount = 256; 09901 } 09902 } 09903 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09904 if (reload) { 09905 AST_LIST_LOCK(&dynamic_list); 09906 iaxmaxthreadcount = atoi(v->value); 09907 AST_LIST_UNLOCK(&dynamic_list); 09908 } else { 09909 iaxmaxthreadcount = atoi(v->value); 09910 if (iaxmaxthreadcount < 0) { 09911 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09912 iaxmaxthreadcount = 0; 09913 } else if (iaxmaxthreadcount > 256) { 09914 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09915 iaxmaxthreadcount = 256; 09916 } 09917 } 09918 } else if (!strcasecmp(v->name, "nochecksums")) { 09919 #ifdef SO_NO_CHECK 09920 if (ast_true(v->value)) 09921 nochecksums = 1; 09922 else 09923 nochecksums = 0; 09924 #else 09925 if (ast_true(v->value)) 09926 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09927 #endif 09928 } 09929 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09930 maxjitterbuffer = atoi(v->value); 09931 else if (!strcasecmp(v->name, "resyncthreshold")) 09932 resyncthreshold = atoi(v->value); 09933 else if (!strcasecmp(v->name, "maxjitterinterps")) 09934 maxjitterinterps = atoi(v->value); 09935 else if (!strcasecmp(v->name, "lagrqtime")) 09936 lagrq_time = atoi(v->value); 09937 else if (!strcasecmp(v->name, "maxregexpire")) 09938 max_reg_expire = atoi(v->value); 09939 else if (!strcasecmp(v->name, "minregexpire")) 09940 min_reg_expire = atoi(v->value); 09941 else if (!strcasecmp(v->name, "bindaddr")) { 09942 if (reload) { 09943 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09944 } else { 09945 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09946 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09947 } else { 09948 if (option_verbose > 1) { 09949 if (strchr(v->value, ':')) 09950 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09951 else 09952 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09953 } 09954 if (defaultsockfd < 0) 09955 defaultsockfd = ast_netsock_sockfd(ns); 09956 ast_netsock_unref(ns); 09957 } 09958 } 09959 } else if (!strcasecmp(v->name, "authdebug")) 09960 authdebug = ast_true(v->value); 09961 else if (!strcasecmp(v->name, "encryption")) 09962 iax2_encryption = get_encrypt_methods(v->value); 09963 else if (!strcasecmp(v->name, "notransfer")) { 09964 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09965 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09966 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09967 } else if (!strcasecmp(v->name, "transfer")) { 09968 if (!strcasecmp(v->value, "mediaonly")) { 09969 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09970 } else if (ast_true(v->value)) { 09971 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09972 } else 09973 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09974 } else if (!strcasecmp(v->name, "codecpriority")) { 09975 if(!strcasecmp(v->value, "caller")) 09976 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09977 else if(!strcasecmp(v->value, "disabled")) 09978 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09979 else if(!strcasecmp(v->value, "reqonly")) { 09980 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09981 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09982 } 09983 } else if (!strcasecmp(v->name, "jitterbuffer")) 09984 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09985 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09986 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09987 else if (!strcasecmp(v->name, "delayreject")) 09988 delayreject = ast_true(v->value); 09989 else if (!strcasecmp(v->name, "rtcachefriends")) 09990 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09991 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09992 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09993 else if (!strcasecmp(v->name, "rtupdate")) 09994 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09995 else if (!strcasecmp(v->name, "trunktimestamps")) 09996 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09997 else if (!strcasecmp(v->name, "rtautoclear")) { 09998 int i = atoi(v->value); 09999 if(i > 0) 10000 global_rtautoclear = i; 10001 else 10002 i = 0; 10003 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10004 } else if (!strcasecmp(v->name, "trunkfreq")) { 10005 trunkfreq = atoi(v->value); 10006 if (trunkfreq < 10) 10007 trunkfreq = 10; 10008 } else if (!strcasecmp(v->name, "autokill")) { 10009 if (sscanf(v->value, "%d", &x) == 1) { 10010 if (x >= 0) 10011 autokill = x; 10012 else 10013 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10014 } else if (ast_true(v->value)) { 10015 autokill = DEFAULT_MAXMS; 10016 } else { 10017 autokill = 0; 10018 } 10019 } else if (!strcasecmp(v->name, "bandwidth")) { 10020 if (!strcasecmp(v->value, "low")) { 10021 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10022 } else if (!strcasecmp(v->value, "medium")) { 10023 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10024 } else if (!strcasecmp(v->value, "high")) { 10025 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10026 } else 10027 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10028 } else if (!strcasecmp(v->name, "allow")) { 10029 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10030 } else if (!strcasecmp(v->name, "disallow")) { 10031 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10032 } else if (!strcasecmp(v->name, "register")) { 10033 iax2_register(v->value, v->lineno); 10034 } else if (!strcasecmp(v->name, "iaxcompat")) { 10035 iaxcompat = ast_true(v->value); 10036 } else if (!strcasecmp(v->name, "regcontext")) { 10037 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10038 /* Create context if it doesn't exist already */ 10039 if (!ast_context_find(regcontext)) 10040 ast_context_create(NULL, regcontext, "IAX2"); 10041 } else if (!strcasecmp(v->name, "tos")) { 10042 if (ast_str2tos(v->value, &tos)) 10043 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10044 } else if (!strcasecmp(v->name, "accountcode")) { 10045 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10046 } else if (!strcasecmp(v->name, "mohinterpret")) { 10047 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 10048 } else if (!strcasecmp(v->name, "mohsuggest")) { 10049 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 10050 } else if (!strcasecmp(v->name, "amaflags")) { 10051 format = ast_cdr_amaflags2int(v->value); 10052 if (format < 0) { 10053 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10054 } else { 10055 amaflags = format; 10056 } 10057 } else if (!strcasecmp(v->name, "language")) { 10058 ast_copy_string(language, v->value, sizeof(language)); 10059 } else if (!strcasecmp(v->name, "maxauthreq")) { 10060 maxauthreq = atoi(v->value); 10061 if (maxauthreq < 0) 10062 maxauthreq = 0; 10063 } else if (!strcasecmp(v->name, "adsi")) { 10064 adsi = ast_true(v->value); 10065 } /*else if (strcasecmp(v->name,"type")) */ 10066 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10067 v = v->next; 10068 } 10069 10070 if (defaultsockfd < 0) { 10071 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10072 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10073 } else { 10074 if (option_verbose > 1) 10075 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10076 defaultsockfd = ast_netsock_sockfd(ns); 10077 ast_netsock_unref(ns); 10078 } 10079 } 10080 if (reload) { 10081 ast_netsock_release(outsock); 10082 outsock = ast_netsock_list_alloc(); 10083 if (!outsock) { 10084 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10085 return -1; 10086 } 10087 ast_netsock_init(outsock); 10088 } 10089 10090 if (min_reg_expire > max_reg_expire) { 10091 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10092 min_reg_expire, max_reg_expire, max_reg_expire); 10093 min_reg_expire = max_reg_expire; 10094 } 10095 iax2_capability = capability; 10096 10097 ucfg = ast_config_load("users.conf"); 10098 if (ucfg) { 10099 struct ast_variable *gen; 10100 int genhasiax; 10101 int genregisteriax; 10102 const char *hasiax, *registeriax; 10103 10104 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10105 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10106 gen = ast_variable_browse(ucfg, "general"); 10107 cat = ast_category_browse(ucfg, NULL); 10108 while (cat) { 10109 if (strcasecmp(cat, "general")) { 10110 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10111 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10112 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10113 /* Start with general parameters, then specific parameters, user and peer */ 10114 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10115 if (user) { 10116 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10117 user = user_unref(user); 10118 } 10119 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10120 if (peer) { 10121 if (ast_test_flag(peer, IAX_DYNAMIC)) 10122 reg_source_db(peer); 10123 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10124 peer = peer_unref(peer); 10125 } 10126 } 10127 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10128 char tmp[256]; 10129 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10130 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10131 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10132 if (!host) 10133 host = ast_variable_retrieve(ucfg, "general", "host"); 10134 if (!username) 10135 username = ast_variable_retrieve(ucfg, "general", "username"); 10136 if (!secret) 10137 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10138 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10139 if (!ast_strlen_zero(secret)) 10140 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10141 else 10142 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10143 iax2_register(tmp, 0); 10144 } 10145 } 10146 } 10147 cat = ast_category_browse(ucfg, cat); 10148 } 10149 ast_config_destroy(ucfg); 10150 } 10151 10152 cat = ast_category_browse(cfg, NULL); 10153 while(cat) { 10154 if (strcasecmp(cat, "general")) { 10155 utype = ast_variable_retrieve(cfg, cat, "type"); 10156 if (utype) { 10157 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10158 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10159 if (user) { 10160 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10161 user = user_unref(user); 10162 } 10163 } 10164 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10165 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10166 if (peer) { 10167 if (ast_test_flag(peer, IAX_DYNAMIC)) 10168 reg_source_db(peer); 10169 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10170 peer = peer_unref(peer); 10171 } 10172 } else if (strcasecmp(utype, "user")) { 10173 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10174 } 10175 } else 10176 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10177 } 10178 cat = ast_category_browse(cfg, cat); 10179 } 10180 ast_config_destroy(cfg); 10181 set_timing(); 10182 return 1; 10183 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9812 of file chan_iax2.c.
References ast_clear_flag, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09813 { 09814 strcpy(accountcode, ""); 09815 strcpy(language, ""); 09816 strcpy(mohinterpret, "default"); 09817 strcpy(mohsuggest, ""); 09818 amaflags = 0; 09819 delayreject = 0; 09820 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09821 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09822 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09823 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09824 delete_users(); 09825 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9797 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09798 { 09799 #ifdef HAVE_ZAPTEL 09800 int bs = trunkfreq * 8; 09801 if (timingfd > -1) { 09802 if ( 09803 #ifdef ZT_TIMERACK 09804 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09805 #endif 09806 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09807 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09808 } 09809 #endif 09810 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 756 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_sched_add(), iax2_transmit(), and socket_read().
00757 { 00758 ast_mutex_lock(lock); 00759 ast_cond_signal(cond); 00760 ast_mutex_unlock(lock); 00761 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6942 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, 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_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_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_frame::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(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), 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_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_STATE_UNCHANGED, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), chan_iax2_pvt::state, 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().
06943 { 06944 struct sockaddr_in sin; 06945 int res; 06946 int updatehistory=1; 06947 int new = NEW_PREVENT; 06948 void *ptr; 06949 int dcallno = 0; 06950 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06951 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06952 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06953 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06954 struct ast_iax2_meta_trunk_hdr *mth; 06955 struct ast_iax2_meta_trunk_entry *mte; 06956 struct ast_iax2_meta_trunk_mini *mtm; 06957 struct iax_frame *fr; 06958 struct iax_frame *cur; 06959 struct ast_frame f = { 0, }; 06960 struct ast_channel *c; 06961 struct iax2_dpcache *dp; 06962 struct iax2_peer *peer; 06963 struct iax2_trunk_peer *tpeer; 06964 struct timeval rxtrunktime; 06965 struct iax_ies ies; 06966 struct iax_ie_data ied0, ied1; 06967 int format; 06968 int fd; 06969 int exists; 06970 int minivid = 0; 06971 unsigned int ts; 06972 char empty[32]=""; /* Safety measure */ 06973 struct iax_frame *duped_fr; 06974 char host_pref_buf[128]; 06975 char caller_pref_buf[128]; 06976 struct ast_codec_pref pref; 06977 char *using_prefs = "mine"; 06978 06979 /* allocate an iax_frame with 4096 bytes of data buffer */ 06980 fr = alloca(sizeof(*fr) + 4096); 06981 memset(fr, 0, sizeof(*fr)); 06982 fr->afdatalen = 4096; /* From alloca() above */ 06983 06984 /* Copy frequently used parameters to the stack */ 06985 res = thread->buf_len; 06986 fd = thread->iofd; 06987 memcpy(&sin, &thread->iosin, sizeof(sin)); 06988 06989 if (res < sizeof(*mh)) { 06990 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06991 return 1; 06992 } 06993 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06994 if (res < sizeof(*vh)) { 06995 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)); 06996 return 1; 06997 } 06998 06999 /* This is a video frame, get call number */ 07000 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07001 minivid = 1; 07002 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07003 unsigned char metatype; 07004 07005 if (res < sizeof(*meta)) { 07006 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)); 07007 return 1; 07008 } 07009 07010 /* This is a meta header */ 07011 switch(meta->metacmd) { 07012 case IAX_META_TRUNK: 07013 if (res < (sizeof(*meta) + sizeof(*mth))) { 07014 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07015 sizeof(*meta) + sizeof(*mth)); 07016 return 1; 07017 } 07018 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07019 ts = ntohl(mth->ts); 07020 metatype = meta->cmddata; 07021 res -= (sizeof(*meta) + sizeof(*mth)); 07022 ptr = mth->data; 07023 tpeer = find_tpeer(&sin, fd); 07024 if (!tpeer) { 07025 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)); 07026 return 1; 07027 } 07028 tpeer->trunkact = ast_tvnow(); 07029 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07030 tpeer->rxtrunktime = tpeer->trunkact; 07031 rxtrunktime = tpeer->rxtrunktime; 07032 ast_mutex_unlock(&tpeer->lock); 07033 while(res >= sizeof(*mte)) { 07034 /* Process channels */ 07035 unsigned short callno, trunked_ts, len; 07036 07037 if (metatype == IAX_META_TRUNK_MINI) { 07038 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07039 ptr += sizeof(*mtm); 07040 res -= sizeof(*mtm); 07041 len = ntohs(mtm->len); 07042 callno = ntohs(mtm->mini.callno); 07043 trunked_ts = ntohs(mtm->mini.ts); 07044 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07045 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07046 ptr += sizeof(*mte); 07047 res -= sizeof(*mte); 07048 len = ntohs(mte->len); 07049 callno = ntohs(mte->callno); 07050 trunked_ts = 0; 07051 } else { 07052 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07053 break; 07054 } 07055 /* Stop if we don't have enough data */ 07056 if (len > res) 07057 break; 07058 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07059 if (fr->callno) { 07060 /* If it's a valid call, deliver the contents. If not, we 07061 drop it, since we don't have a scallno to use for an INVAL */ 07062 /* Process as a mini frame */ 07063 memset(&f, 0, sizeof(f)); 07064 f.frametype = AST_FRAME_VOICE; 07065 if (iaxs[fr->callno]) { 07066 if (iaxs[fr->callno]->voiceformat > 0) { 07067 f.subclass = iaxs[fr->callno]->voiceformat; 07068 f.datalen = len; 07069 if (f.datalen >= 0) { 07070 if (f.datalen) 07071 f.data = ptr; 07072 if(trunked_ts) { 07073 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07074 } else 07075 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07076 /* Don't pass any packets until we're started */ 07077 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07078 /* Common things */ 07079 f.src = "IAX2"; 07080 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07081 f.samples = ast_codec_get_samples(&f); 07082 iax_frame_wrap(fr, &f); 07083 duped_fr = iaxfrdup2(fr); 07084 if (duped_fr) { 07085 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07086 } 07087 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07088 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07089 iaxs[fr->callno]->last = fr->ts; 07090 #if 1 07091 if (option_debug && iaxdebug) 07092 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07093 #endif 07094 } 07095 } 07096 } else { 07097 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07098 } 07099 } else { 07100 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 07101 iax2_vnak(fr->callno); 07102 } 07103 } 07104 ast_mutex_unlock(&iaxsl[fr->callno]); 07105 } 07106 ptr += len; 07107 res -= len; 07108 } 07109 07110 } 07111 return 1; 07112 } 07113 07114 #ifdef DEBUG_SUPPORT 07115 if (iaxdebug && (res >= sizeof(*fh))) 07116 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07117 #endif 07118 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07119 if (res < sizeof(*fh)) { 07120 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)); 07121 return 1; 07122 } 07123 07124 /* Get the destination call number */ 07125 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07126 /* Retrieve the type and subclass */ 07127 f.frametype = fh->type; 07128 if (f.frametype == AST_FRAME_VIDEO) { 07129 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07130 } else { 07131 f.subclass = uncompress_subclass(fh->csub); 07132 } 07133 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07134 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07135 (f.subclass == IAX_COMMAND_REGREL))) 07136 new = NEW_ALLOW; 07137 } else { 07138 /* Don't know anything about it yet */ 07139 f.frametype = AST_FRAME_NULL; 07140 f.subclass = 0; 07141 } 07142 07143 if (!fr->callno) { 07144 int check_dcallno = 0; 07145 07146 /* 07147 * We enforce accurate destination call numbers for all full frames except 07148 * LAGRQ and PING commands. This is because older versions of Asterisk 07149 * schedule these commands to get sent very quickly, and they will sometimes 07150 * be sent before they receive the first frame from the other side. When 07151 * that happens, it doesn't contain the destination call number. However, 07152 * not checking it for these frames is safe. 07153 * 07154 * Discussed in the following thread: 07155 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07156 */ 07157 07158 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07159 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07160 } 07161 07162 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07163 } 07164 07165 if (fr->callno > 0) 07166 ast_mutex_lock(&iaxsl[fr->callno]); 07167 07168 if (!fr->callno || !iaxs[fr->callno]) { 07169 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07170 frame, reply with an inval */ 07171 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07172 /* We can only raw hangup control frames */ 07173 if (((f.subclass != IAX_COMMAND_INVAL) && 07174 (f.subclass != IAX_COMMAND_TXCNT) && 07175 (f.subclass != IAX_COMMAND_TXACC) && 07176 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07177 (f.frametype != AST_FRAME_IAX)) 07178 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07179 fd); 07180 } 07181 if (fr->callno > 0) 07182 ast_mutex_unlock(&iaxsl[fr->callno]); 07183 return 1; 07184 } 07185 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07186 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07187 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07188 ast_mutex_unlock(&iaxsl[fr->callno]); 07189 return 1; 07190 } 07191 #ifdef DEBUG_SUPPORT 07192 else if (iaxdebug) 07193 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07194 #endif 07195 } 07196 07197 /* count this frame */ 07198 iaxs[fr->callno]->frames_received++; 07199 07200 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07201 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07202 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07203 unsigned short new_peercallno; 07204 07205 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07206 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07207 if (iaxs[fr->callno]->peercallno) { 07208 remove_by_peercallno(iaxs[fr->callno]); 07209 } 07210 iaxs[fr->callno]->peercallno = new_peercallno; 07211 store_by_peercallno(iaxs[fr->callno]); 07212 } 07213 } 07214 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07215 if (option_debug && iaxdebug) 07216 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07217 /* Check if it's out of order (and not an ACK or INVAL) */ 07218 fr->oseqno = fh->oseqno; 07219 fr->iseqno = fh->iseqno; 07220 fr->ts = ntohl(fh->ts); 07221 #ifdef IAXTESTS 07222 if (test_resync) { 07223 if (option_debug) 07224 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07225 fr->ts += test_resync; 07226 } 07227 #endif /* IAXTESTS */ 07228 #if 0 07229 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07230 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07231 (f.subclass == IAX_COMMAND_NEW || 07232 f.subclass == IAX_COMMAND_AUTHREQ || 07233 f.subclass == IAX_COMMAND_ACCEPT || 07234 f.subclass == IAX_COMMAND_REJECT)) ) ) 07235 #endif 07236 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07237 updatehistory = 0; 07238 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07239 (iaxs[fr->callno]->iseqno || 07240 ((f.subclass != IAX_COMMAND_TXCNT) && 07241 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07242 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07243 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07244 (f.subclass != IAX_COMMAND_TXACC)) || 07245 (f.frametype != AST_FRAME_IAX))) { 07246 if ( 07247 ((f.subclass != IAX_COMMAND_ACK) && 07248 (f.subclass != IAX_COMMAND_INVAL) && 07249 (f.subclass != IAX_COMMAND_TXCNT) && 07250 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07251 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07252 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07253 (f.subclass != IAX_COMMAND_TXACC) && 07254 (f.subclass != IAX_COMMAND_VNAK)) || 07255 (f.frametype != AST_FRAME_IAX)) { 07256 /* If it's not an ACK packet, it's out of order. */ 07257 if (option_debug) 07258 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07259 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07260 /* Check to see if we need to request retransmission, 07261 * and take sequence number wraparound into account */ 07262 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07263 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07264 if ((f.frametype != AST_FRAME_IAX) || 07265 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07266 if (option_debug) 07267 ast_log(LOG_DEBUG, "Acking anyway\n"); 07268 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07269 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07270 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07271 } 07272 } else { 07273 /* Send a VNAK requesting retransmission */ 07274 iax2_vnak(fr->callno); 07275 } 07276 ast_mutex_unlock(&iaxsl[fr->callno]); 07277 return 1; 07278 } 07279 } else { 07280 /* Increment unless it's an ACK or VNAK */ 07281 if (((f.subclass != IAX_COMMAND_ACK) && 07282 (f.subclass != IAX_COMMAND_INVAL) && 07283 (f.subclass != IAX_COMMAND_TXCNT) && 07284 (f.subclass != IAX_COMMAND_TXACC) && 07285 (f.subclass != IAX_COMMAND_VNAK)) || 07286 (f.frametype != AST_FRAME_IAX)) 07287 iaxs[fr->callno]->iseqno++; 07288 } 07289 /* A full frame */ 07290 if (res < sizeof(*fh)) { 07291 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07292 ast_mutex_unlock(&iaxsl[fr->callno]); 07293 return 1; 07294 } 07295 /* Ensure text frames are NULL-terminated */ 07296 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07297 if (res < thread->buf_size) 07298 thread->buf[res++] = '\0'; 07299 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07300 thread->buf[res - 1] = '\0'; 07301 } 07302 f.datalen = res - sizeof(*fh); 07303 07304 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07305 from the real peer, not the transfer peer */ 07306 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07307 ((f.subclass != IAX_COMMAND_INVAL) || 07308 (f.frametype != AST_FRAME_IAX))) { 07309 unsigned char x; 07310 int call_to_destroy; 07311 /* XXX This code is not very efficient. Surely there is a better way which still 07312 properly handles boundary conditions? XXX */ 07313 /* First we have to qualify that the ACKed value is within our window */ 07314 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07315 if (fr->iseqno == x) 07316 break; 07317 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07318 /* The acknowledgement is within our window. Time to acknowledge everything 07319 that it says to */ 07320 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07321 /* Ack the packet with the given timestamp */ 07322 if (option_debug && iaxdebug) 07323 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07324 call_to_destroy = 0; 07325 AST_LIST_LOCK(&iaxq.queue); 07326 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07327 /* If it's our call, and our timestamp, mark -1 retries */ 07328 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07329 cur->retries = -1; 07330 /* Destroy call if this is the end */ 07331 if (cur->final) 07332 call_to_destroy = fr->callno; 07333 } 07334 } 07335 AST_LIST_UNLOCK(&iaxq.queue); 07336 if (call_to_destroy) { 07337 if (iaxdebug && option_debug) 07338 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07339 ast_mutex_lock(&iaxsl[call_to_destroy]); 07340 iax2_destroy(call_to_destroy); 07341 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07342 } 07343 } 07344 /* Note how much we've received acknowledgement for */ 07345 if (iaxs[fr->callno]) 07346 iaxs[fr->callno]->rseqno = fr->iseqno; 07347 else { 07348 /* Stop processing now */ 07349 ast_mutex_unlock(&iaxsl[fr->callno]); 07350 return 1; 07351 } 07352 } else if (option_debug) 07353 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07354 } 07355 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07356 ((f.frametype != AST_FRAME_IAX) || 07357 ((f.subclass != IAX_COMMAND_TXACC) && 07358 (f.subclass != IAX_COMMAND_TXCNT)))) { 07359 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07360 ast_mutex_unlock(&iaxsl[fr->callno]); 07361 return 1; 07362 } 07363 07364 if (f.datalen) { 07365 if (f.frametype == AST_FRAME_IAX) { 07366 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07367 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07368 ast_mutex_unlock(&iaxsl[fr->callno]); 07369 return 1; 07370 } 07371 f.data = NULL; 07372 f.datalen = 0; 07373 } else 07374 f.data = thread->buf + sizeof(*fh); 07375 } else { 07376 if (f.frametype == AST_FRAME_IAX) 07377 f.data = NULL; 07378 else 07379 f.data = empty; 07380 memset(&ies, 0, sizeof(ies)); 07381 } 07382 07383 /* when we receive the first full frame for a new incoming channel, 07384 it is safe to start the PBX on the channel because we have now 07385 completed a 3-way handshake with the peer */ 07386 if ((f.frametype == AST_FRAME_VOICE) || 07387 (f.frametype == AST_FRAME_VIDEO) || 07388 (f.frametype == AST_FRAME_IAX)) { 07389 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07390 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07391 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07392 ast_mutex_unlock(&iaxsl[fr->callno]); 07393 return 1; 07394 } 07395 } 07396 } 07397 07398 if (f.frametype == AST_FRAME_VOICE) { 07399 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07400 iaxs[fr->callno]->voiceformat = f.subclass; 07401 if (option_debug) 07402 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07403 if (iaxs[fr->callno]->owner) { 07404 int orignative; 07405 retryowner: 07406 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07407 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07408 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07409 } 07410 if (iaxs[fr->callno]) { 07411 if (iaxs[fr->callno]->owner) { 07412 orignative = iaxs[fr->callno]->owner->nativeformats; 07413 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07414 if (iaxs[fr->callno]->owner->readformat) 07415 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07416 iaxs[fr->callno]->owner->nativeformats = orignative; 07417 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07418 } 07419 } else { 07420 if (option_debug) 07421 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07422 ast_mutex_unlock(&iaxsl[fr->callno]); 07423 return 1; 07424 } 07425 } 07426 } 07427 } 07428 if (f.frametype == AST_FRAME_VIDEO) { 07429 if (f.subclass != iaxs[fr->callno]->videoformat) { 07430 if (option_debug) 07431 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07432 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07433 } 07434 } 07435 if (f.frametype == AST_FRAME_IAX) { 07436 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07437 /* Handle the IAX pseudo frame itself */ 07438 if (option_debug && iaxdebug) 07439 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07440 07441 /* Update last ts unless the frame's timestamp originated with us. */ 07442 if (iaxs[fr->callno]->last < fr->ts && 07443 f.subclass != IAX_COMMAND_ACK && 07444 f.subclass != IAX_COMMAND_PONG && 07445 f.subclass != IAX_COMMAND_LAGRP) { 07446 iaxs[fr->callno]->last = fr->ts; 07447 if (option_debug && iaxdebug) 07448 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07449 } 07450 07451 switch(f.subclass) { 07452 case IAX_COMMAND_ACK: 07453 /* Do nothing */ 07454 break; 07455 case IAX_COMMAND_QUELCH: 07456 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07457 /* Generate Manager Hold event, if necessary*/ 07458 if (iaxs[fr->callno]->owner) { 07459 manager_event(EVENT_FLAG_CALL, "Hold", 07460 "Channel: %s\r\n" 07461 "Uniqueid: %s\r\n", 07462 iaxs[fr->callno]->owner->name, 07463 iaxs[fr->callno]->owner->uniqueid); 07464 } 07465 07466 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07467 if (ies.musiconhold) { 07468 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07469 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07470 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07471 S_OR(mohsuggest, NULL), 07472 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07473 if (!iaxs[fr->callno]) { 07474 ast_mutex_unlock(&iaxsl[fr->callno]); 07475 return 1; 07476 } 07477 } 07478 } 07479 } 07480 break; 07481 case IAX_COMMAND_UNQUELCH: 07482 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07483 /* Generate Manager Unhold event, if necessary*/ 07484 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07485 manager_event(EVENT_FLAG_CALL, "Unhold", 07486 "Channel: %s\r\n" 07487 "Uniqueid: %s\r\n", 07488 iaxs[fr->callno]->owner->name, 07489 iaxs[fr->callno]->owner->uniqueid); 07490 } 07491 07492 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07493 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07494 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07495 if (!iaxs[fr->callno]) { 07496 ast_mutex_unlock(&iaxsl[fr->callno]); 07497 return 1; 07498 } 07499 } 07500 } 07501 break; 07502 case IAX_COMMAND_TXACC: 07503 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07504 /* Ack the packet with the given timestamp */ 07505 AST_LIST_LOCK(&iaxq.queue); 07506 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07507 /* Cancel any outstanding txcnt's */ 07508 if ((fr->callno == cur->callno) && (cur->transfer)) 07509 cur->retries = -1; 07510 } 07511 AST_LIST_UNLOCK(&iaxq.queue); 07512 memset(&ied1, 0, sizeof(ied1)); 07513 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07514 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07515 iaxs[fr->callno]->transferring = TRANSFER_READY; 07516 } 07517 break; 07518 case IAX_COMMAND_NEW: 07519 /* Ignore if it's already up */ 07520 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07521 break; 07522 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07523 ast_mutex_unlock(&iaxsl[fr->callno]); 07524 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07525 ast_mutex_lock(&iaxsl[fr->callno]); 07526 if (!iaxs[fr->callno]) { 07527 ast_mutex_unlock(&iaxsl[fr->callno]); 07528 return 1; 07529 } 07530 } 07531 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07532 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07533 int new_callno; 07534 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07535 fr->callno = new_callno; 07536 } 07537 /* For security, always ack immediately */ 07538 if (delayreject) 07539 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07540 if (check_access(fr->callno, &sin, &ies)) { 07541 /* They're not allowed on */ 07542 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07543 if (authdebug) 07544 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); 07545 break; 07546 } 07547 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07548 const char *context, *exten, *cid_num; 07549 07550 context = ast_strdupa(iaxs[fr->callno]->context); 07551 exten = ast_strdupa(iaxs[fr->callno]->exten); 07552 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07553 07554 /* This might re-enter the IAX code and need the lock */ 07555 ast_mutex_unlock(&iaxsl[fr->callno]); 07556 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07557 ast_mutex_lock(&iaxsl[fr->callno]); 07558 07559 if (!iaxs[fr->callno]) { 07560 ast_mutex_unlock(&iaxsl[fr->callno]); 07561 return 1; 07562 } 07563 } else 07564 exists = 0; 07565 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07566 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07567 memset(&ied0, 0, sizeof(ied0)); 07568 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07569 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07570 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07571 if (!iaxs[fr->callno]) { 07572 ast_mutex_unlock(&iaxsl[fr->callno]); 07573 return 1; 07574 } 07575 if (authdebug) 07576 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); 07577 } else { 07578 /* Select an appropriate format */ 07579 07580 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07581 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07582 using_prefs = "reqonly"; 07583 } else { 07584 using_prefs = "disabled"; 07585 } 07586 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07587 memset(&pref, 0, sizeof(pref)); 07588 strcpy(caller_pref_buf, "disabled"); 07589 strcpy(host_pref_buf, "disabled"); 07590 } else { 07591 using_prefs = "mine"; 07592 /* If the information elements are in here... use them */ 07593 if (ies.codec_prefs) 07594 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07595 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07596 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07597 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07598 pref = iaxs[fr->callno]->rprefs; 07599 using_prefs = "caller"; 07600 } else { 07601 pref = iaxs[fr->callno]->prefs; 07602 } 07603 } else 07604 pref = iaxs[fr->callno]->prefs; 07605 07606 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07607 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07608 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07609 } 07610 if (!format) { 07611 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07612 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07613 if (!format) { 07614 memset(&ied0, 0, sizeof(ied0)); 07615 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07616 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07617 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07618 if (!iaxs[fr->callno]) { 07619 ast_mutex_unlock(&iaxsl[fr->callno]); 07620 return 1; 07621 } 07622 if (authdebug) { 07623 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07624 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); 07625 else 07626 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); 07627 } 07628 } else { 07629 /* Pick one... */ 07630 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07631 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07632 format = 0; 07633 } else { 07634 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07635 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07636 memset(&pref, 0, sizeof(pref)); 07637 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07638 strcpy(caller_pref_buf,"disabled"); 07639 strcpy(host_pref_buf,"disabled"); 07640 } else { 07641 using_prefs = "mine"; 07642 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07643 /* Do the opposite of what we tried above. */ 07644 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07645 pref = iaxs[fr->callno]->prefs; 07646 } else { 07647 pref = iaxs[fr->callno]->rprefs; 07648 using_prefs = "caller"; 07649 } 07650 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07651 07652 } else /* if no codec_prefs IE do it the old way */ 07653 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07654 } 07655 } 07656 07657 if (!format) { 07658 memset(&ied0, 0, sizeof(ied0)); 07659 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07660 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07661 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07662 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07663 if (!iaxs[fr->callno]) { 07664 ast_mutex_unlock(&iaxsl[fr->callno]); 07665 return 1; 07666 } 07667 if (authdebug) 07668 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); 07669 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07670 break; 07671 } 07672 } 07673 } 07674 if (format) { 07675 /* No authentication required, let them in */ 07676 memset(&ied1, 0, sizeof(ied1)); 07677 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07678 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07679 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07680 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07681 if (option_verbose > 2) 07682 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07683 "%srequested format = %s,\n" 07684 "%srequested prefs = %s,\n" 07685 "%sactual format = %s,\n" 07686 "%shost prefs = %s,\n" 07687 "%spriority = %s\n", 07688 ast_inet_ntoa(sin.sin_addr), 07689 VERBOSE_PREFIX_4, 07690 ast_getformatname(iaxs[fr->callno]->peerformat), 07691 VERBOSE_PREFIX_4, 07692 caller_pref_buf, 07693 VERBOSE_PREFIX_4, 07694 ast_getformatname(format), 07695 VERBOSE_PREFIX_4, 07696 host_pref_buf, 07697 VERBOSE_PREFIX_4, 07698 using_prefs); 07699 07700 iaxs[fr->callno]->chosenformat = format; 07701 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07702 } else { 07703 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07704 /* If this is a TBD call, we're ready but now what... */ 07705 if (option_verbose > 2) 07706 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07707 } 07708 } 07709 } 07710 break; 07711 } 07712 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07713 merge_encryption(iaxs[fr->callno],ies.encmethods); 07714 else 07715 iaxs[fr->callno]->encmethods = 0; 07716 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07717 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07718 if (!iaxs[fr->callno]) { 07719 ast_mutex_unlock(&iaxsl[fr->callno]); 07720 return 1; 07721 } 07722 break; 07723 case IAX_COMMAND_DPREQ: 07724 /* Request status in the dialplan */ 07725 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07726 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07727 if (iaxcompat) { 07728 /* Spawn a thread for the lookup */ 07729 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07730 } else { 07731 /* Just look it up */ 07732 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07733 } 07734 } 07735 break; 07736 case IAX_COMMAND_HANGUP: 07737 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07738 if (option_debug) 07739 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07740 /* Set hangup cause according to remote */ 07741 if (ies.causecode && iaxs[fr->callno]->owner) 07742 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07743 /* Send ack immediately, before we destroy */ 07744 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07745 iax2_destroy(fr->callno); 07746 break; 07747 case IAX_COMMAND_REJECT: 07748 /* Set hangup cause according to remote */ 07749 if (ies.causecode && iaxs[fr->callno]->owner) 07750 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07751 07752 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07753 if (iaxs[fr->callno]->owner && authdebug) 07754 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07755 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07756 ies.cause ? ies.cause : "<Unknown>"); 07757 if (option_debug) 07758 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07759 fr->callno); 07760 } 07761 /* Send ack immediately, before we destroy */ 07762 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07763 fr->ts, NULL, 0, fr->iseqno); 07764 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07765 iaxs[fr->callno]->error = EPERM; 07766 iax2_destroy(fr->callno); 07767 break; 07768 case IAX_COMMAND_TRANSFER: 07769 { 07770 struct ast_channel *bridged_chan; 07771 07772 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07773 /* Set BLINDTRANSFER channel variables */ 07774 07775 ast_mutex_unlock(&iaxsl[fr->callno]); 07776 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07777 ast_mutex_lock(&iaxsl[fr->callno]); 07778 if (!iaxs[fr->callno]) { 07779 ast_mutex_unlock(&iaxsl[fr->callno]); 07780 return 1; 07781 } 07782 07783 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07784 if (!strcmp(ies.called_number, ast_parking_ext())) { 07785 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07786 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07787 } else { 07788 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07789 } 07790 } else { 07791 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07792 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07793 ies.called_number, iaxs[fr->callno]->context); 07794 else 07795 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07796 ies.called_number, iaxs[fr->callno]->context); 07797 } 07798 } else 07799 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07800 07801 break; 07802 } 07803 case IAX_COMMAND_ACCEPT: 07804 /* Ignore if call is already up or needs authentication or is a TBD */ 07805 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07806 break; 07807 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07808 /* Send ack immediately, before we destroy */ 07809 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07810 iax2_destroy(fr->callno); 07811 break; 07812 } 07813 if (ies.format) { 07814 iaxs[fr->callno]->peerformat = ies.format; 07815 } else { 07816 if (iaxs[fr->callno]->owner) 07817 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07818 else 07819 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07820 } 07821 if (option_verbose > 2) 07822 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)); 07823 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07824 memset(&ied0, 0, sizeof(ied0)); 07825 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07826 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07827 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07828 if (!iaxs[fr->callno]) { 07829 ast_mutex_unlock(&iaxsl[fr->callno]); 07830 return 1; 07831 } 07832 if (authdebug) 07833 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); 07834 } else { 07835 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07836 if (iaxs[fr->callno]->owner) { 07837 /* Switch us to use a compatible format */ 07838 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07839 if (option_verbose > 2) 07840 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07841 retryowner2: 07842 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07843 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07844 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07845 } 07846 07847 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07848 /* Setup read/write formats properly. */ 07849 if (iaxs[fr->callno]->owner->writeformat) 07850 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07851 if (iaxs[fr->callno]->owner->readformat) 07852 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07853 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07854 } 07855 } 07856 } 07857 if (iaxs[fr->callno]) { 07858 ast_mutex_lock(&dpcache_lock); 07859 dp = iaxs[fr->callno]->dpentries; 07860 while(dp) { 07861 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07862 iax2_dprequest(dp, fr->callno); 07863 } 07864 dp = dp->peer; 07865 } 07866 ast_mutex_unlock(&dpcache_lock); 07867 } 07868 break; 07869 case IAX_COMMAND_POKE: 07870 /* Send back a pong packet with the original timestamp */ 07871 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07872 if (!iaxs[fr->callno]) { 07873 ast_mutex_unlock(&iaxsl[fr->callno]); 07874 return 1; 07875 } 07876 break; 07877 case IAX_COMMAND_PING: 07878 { 07879 struct iax_ie_data pingied; 07880 construct_rr(iaxs[fr->callno], &pingied); 07881 /* Send back a pong packet with the original timestamp */ 07882 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07883 } 07884 break; 07885 case IAX_COMMAND_PONG: 07886 /* Calculate ping time */ 07887 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07888 /* save RR info */ 07889 save_rr(fr, &ies); 07890 07891 if (iaxs[fr->callno]->peerpoke) { 07892 peer = iaxs[fr->callno]->peerpoke; 07893 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07894 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07895 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07896 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07897 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07898 } 07899 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07900 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07901 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07902 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07903 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07904 } 07905 } 07906 peer->lastms = iaxs[fr->callno]->pingtime; 07907 if (peer->smoothing && (peer->lastms > -1)) 07908 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07909 else if (peer->smoothing && peer->lastms < 0) 07910 peer->historicms = (0 + peer->historicms) / 2; 07911 else 07912 peer->historicms = iaxs[fr->callno]->pingtime; 07913 07914 /* Remove scheduled iax2_poke_noanswer */ 07915 if (peer->pokeexpire > -1) { 07916 if (!ast_sched_del(sched, peer->pokeexpire)) { 07917 peer_unref(peer); 07918 peer->pokeexpire = -1; 07919 } 07920 } 07921 /* Schedule the next cycle */ 07922 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07923 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07924 else 07925 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07926 if (peer->pokeexpire == -1) 07927 peer_unref(peer); 07928 /* and finally send the ack */ 07929 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07930 /* And wrap up the qualify call */ 07931 iax2_destroy(fr->callno); 07932 peer->callno = 0; 07933 if (option_debug) 07934 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07935 } 07936 break; 07937 case IAX_COMMAND_LAGRQ: 07938 case IAX_COMMAND_LAGRP: 07939 f.src = "LAGRQ"; 07940 f.mallocd = 0; 07941 f.offset = 0; 07942 f.samples = 0; 07943 iax_frame_wrap(fr, &f); 07944 if(f.subclass == IAX_COMMAND_LAGRQ) { 07945 /* Received a LAGRQ - echo back a LAGRP */ 07946 fr->af.subclass = IAX_COMMAND_LAGRP; 07947 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07948 } else { 07949 /* Received LAGRP in response to our LAGRQ */ 07950 unsigned int ts; 07951 /* This is a reply we've been given, actually measure the difference */ 07952 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07953 iaxs[fr->callno]->lag = ts - fr->ts; 07954 if (option_debug && iaxdebug) 07955 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07956 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07957 } 07958 break; 07959 case IAX_COMMAND_AUTHREQ: 07960 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07961 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>"); 07962 break; 07963 } 07964 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07965 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 07966 .subclass = AST_CONTROL_HANGUP, 07967 }; 07968 ast_log(LOG_WARNING, 07969 "I don't know how to authenticate %s to %s\n", 07970 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07971 iax2_queue_frame(fr->callno, &hangup_fr); 07972 } 07973 if (!iaxs[fr->callno]) { 07974 ast_mutex_unlock(&iaxsl[fr->callno]); 07975 return 1; 07976 } 07977 break; 07978 case IAX_COMMAND_AUTHREP: 07979 /* For security, always ack immediately */ 07980 if (delayreject) 07981 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07982 /* Ignore once we've started */ 07983 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07984 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>"); 07985 break; 07986 } 07987 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07988 if (authdebug) 07989 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); 07990 memset(&ied0, 0, sizeof(ied0)); 07991 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07992 break; 07993 } 07994 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07995 /* This might re-enter the IAX code and need the lock */ 07996 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07997 } else 07998 exists = 0; 07999 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08000 if (authdebug) 08001 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); 08002 memset(&ied0, 0, sizeof(ied0)); 08003 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08004 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08005 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08006 if (!iaxs[fr->callno]) { 08007 ast_mutex_unlock(&iaxsl[fr->callno]); 08008 return 1; 08009 } 08010 } else { 08011 /* Select an appropriate format */ 08012 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08013 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08014 using_prefs = "reqonly"; 08015 } else { 08016 using_prefs = "disabled"; 08017 } 08018 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08019 memset(&pref, 0, sizeof(pref)); 08020 strcpy(caller_pref_buf, "disabled"); 08021 strcpy(host_pref_buf, "disabled"); 08022 } else { 08023 using_prefs = "mine"; 08024 if (ies.codec_prefs) 08025 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08026 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08027 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08028 pref = iaxs[fr->callno]->rprefs; 08029 using_prefs = "caller"; 08030 } else { 08031 pref = iaxs[fr->callno]->prefs; 08032 } 08033 } else /* if no codec_prefs IE do it the old way */ 08034 pref = iaxs[fr->callno]->prefs; 08035 08036 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08037 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08038 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08039 } 08040 if (!format) { 08041 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08042 if (option_debug) 08043 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); 08044 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08045 } 08046 if (!format) { 08047 if (authdebug) { 08048 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08049 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); 08050 else 08051 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); 08052 } 08053 memset(&ied0, 0, sizeof(ied0)); 08054 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08055 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08056 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08057 if (!iaxs[fr->callno]) { 08058 ast_mutex_unlock(&iaxsl[fr->callno]); 08059 return 1; 08060 } 08061 } else { 08062 /* Pick one... */ 08063 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08064 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08065 format = 0; 08066 } else { 08067 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08068 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08069 memset(&pref, 0, sizeof(pref)); 08070 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08071 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08072 strcpy(caller_pref_buf,"disabled"); 08073 strcpy(host_pref_buf,"disabled"); 08074 } else { 08075 using_prefs = "mine"; 08076 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08077 /* Do the opposite of what we tried above. */ 08078 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08079 pref = iaxs[fr->callno]->prefs; 08080 } else { 08081 pref = iaxs[fr->callno]->rprefs; 08082 using_prefs = "caller"; 08083 } 08084 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08085 } else /* if no codec_prefs IE do it the old way */ 08086 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08087 } 08088 } 08089 if (!format) { 08090 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08091 if (authdebug) { 08092 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08093 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); 08094 else 08095 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); 08096 } 08097 memset(&ied0, 0, sizeof(ied0)); 08098 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08099 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08100 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08101 if (!iaxs[fr->callno]) { 08102 ast_mutex_unlock(&iaxsl[fr->callno]); 08103 return 1; 08104 } 08105 } 08106 } 08107 } 08108 if (format) { 08109 /* Authentication received */ 08110 memset(&ied1, 0, sizeof(ied1)); 08111 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08112 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08113 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08114 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08115 if (option_verbose > 2) 08116 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08117 "%srequested format = %s,\n" 08118 "%srequested prefs = %s,\n" 08119 "%sactual format = %s,\n" 08120 "%shost prefs = %s,\n" 08121 "%spriority = %s\n", 08122 ast_inet_ntoa(sin.sin_addr), 08123 VERBOSE_PREFIX_4, 08124 ast_getformatname(iaxs[fr->callno]->peerformat), 08125 VERBOSE_PREFIX_4, 08126 caller_pref_buf, 08127 VERBOSE_PREFIX_4, 08128 ast_getformatname(format), 08129 VERBOSE_PREFIX_4, 08130 host_pref_buf, 08131 VERBOSE_PREFIX_4, 08132 using_prefs); 08133 08134 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08135 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08136 iax2_destroy(fr->callno); 08137 } else { 08138 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08139 /* If this is a TBD call, we're ready but now what... */ 08140 if (option_verbose > 2) 08141 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08142 } 08143 } 08144 } 08145 break; 08146 case IAX_COMMAND_DIAL: 08147 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08148 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08149 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08150 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08151 if (authdebug) 08152 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); 08153 memset(&ied0, 0, sizeof(ied0)); 08154 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08155 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08156 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08157 if (!iaxs[fr->callno]) { 08158 ast_mutex_unlock(&iaxsl[fr->callno]); 08159 return 1; 08160 } 08161 } else { 08162 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08163 if (option_verbose > 2) 08164 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08165 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08166 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08167 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08168 iax2_destroy(fr->callno); 08169 } 08170 } 08171 break; 08172 case IAX_COMMAND_INVAL: 08173 iaxs[fr->callno]->error = ENOTCONN; 08174 if (option_debug) 08175 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08176 iax2_destroy(fr->callno); 08177 if (option_debug) 08178 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08179 break; 08180 case IAX_COMMAND_VNAK: 08181 if (option_debug) 08182 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08183 /* Force retransmission */ 08184 vnak_retransmit(fr->callno, fr->iseqno); 08185 break; 08186 case IAX_COMMAND_REGREQ: 08187 case IAX_COMMAND_REGREL: 08188 /* For security, always ack immediately */ 08189 if (delayreject) 08190 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08191 if (register_verify(fr->callno, &sin, &ies)) { 08192 if (!iaxs[fr->callno]) { 08193 ast_mutex_unlock(&iaxsl[fr->callno]); 08194 return 1; 08195 } 08196 /* Send delayed failure */ 08197 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08198 break; 08199 } 08200 if (!iaxs[fr->callno]) { 08201 ast_mutex_unlock(&iaxsl[fr->callno]); 08202 return 1; 08203 } 08204 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08205 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08206 if (f.subclass == IAX_COMMAND_REGREL) 08207 memset(&sin, 0, sizeof(sin)); 08208 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08209 ast_log(LOG_WARNING, "Registry error\n"); 08210 if (!iaxs[fr->callno]) { 08211 ast_mutex_unlock(&iaxsl[fr->callno]); 08212 return 1; 08213 } 08214 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08215 ast_mutex_unlock(&iaxsl[fr->callno]); 08216 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08217 ast_mutex_lock(&iaxsl[fr->callno]); 08218 if (!iaxs[fr->callno]) { 08219 ast_mutex_unlock(&iaxsl[fr->callno]); 08220 return 1; 08221 } 08222 } 08223 break; 08224 } 08225 registry_authrequest(fr->callno); 08226 if (!iaxs[fr->callno]) { 08227 ast_mutex_unlock(&iaxsl[fr->callno]); 08228 return 1; 08229 } 08230 break; 08231 case IAX_COMMAND_REGACK: 08232 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08233 ast_log(LOG_WARNING, "Registration failure\n"); 08234 /* Send ack immediately, before we destroy */ 08235 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08236 iax2_destroy(fr->callno); 08237 break; 08238 case IAX_COMMAND_REGREJ: 08239 if (iaxs[fr->callno]->reg) { 08240 if (authdebug) { 08241 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)); 08242 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>"); 08243 } 08244 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08245 } 08246 /* Send ack immediately, before we destroy */ 08247 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08248 iax2_destroy(fr->callno); 08249 break; 08250 case IAX_COMMAND_REGAUTH: 08251 /* Authentication request */ 08252 if (registry_rerequest(&ies, fr->callno, &sin)) { 08253 memset(&ied0, 0, sizeof(ied0)); 08254 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08255 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08256 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08257 if (!iaxs[fr->callno]) { 08258 ast_mutex_unlock(&iaxsl[fr->callno]); 08259 return 1; 08260 } 08261 } 08262 break; 08263 case IAX_COMMAND_TXREJ: 08264 iaxs[fr->callno]->transferring = 0; 08265 if (option_verbose > 2) 08266 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08267 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08268 if (iaxs[fr->callno]->bridgecallno) { 08269 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08270 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08271 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08272 } 08273 } 08274 break; 08275 case IAX_COMMAND_TXREADY: 08276 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08277 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08278 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08279 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08280 else 08281 iaxs[fr->callno]->transferring = TRANSFER_READY; 08282 if (option_verbose > 2) 08283 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08284 if (iaxs[fr->callno]->bridgecallno) { 08285 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08286 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08287 /* They're both ready, now release them. */ 08288 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08289 if (option_verbose > 2) 08290 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08291 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08292 08293 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08294 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08295 08296 memset(&ied0, 0, sizeof(ied0)); 08297 memset(&ied1, 0, sizeof(ied1)); 08298 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08299 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08300 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08301 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08302 } else { 08303 if (option_verbose > 2) 08304 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08305 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08306 08307 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08308 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08309 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08310 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08311 08312 /* Stop doing lag & ping requests */ 08313 stop_stuff(fr->callno); 08314 stop_stuff(iaxs[fr->callno]->bridgecallno); 08315 08316 memset(&ied0, 0, sizeof(ied0)); 08317 memset(&ied1, 0, sizeof(ied1)); 08318 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08319 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08320 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08321 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08322 } 08323 08324 } 08325 } 08326 } 08327 break; 08328 case IAX_COMMAND_TXREQ: 08329 try_transfer(iaxs[fr->callno], &ies); 08330 break; 08331 case IAX_COMMAND_TXCNT: 08332 if (iaxs[fr->callno]->transferring) 08333 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08334 break; 08335 case IAX_COMMAND_TXREL: 08336 /* Send ack immediately, rather than waiting until we've changed addresses */ 08337 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08338 complete_transfer(fr->callno, &ies); 08339 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08340 break; 08341 case IAX_COMMAND_TXMEDIA: 08342 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08343 AST_LIST_LOCK(&iaxq.queue); 08344 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08345 /* Cancel any outstanding frames and start anew */ 08346 if ((fr->callno == cur->callno) && (cur->transfer)) { 08347 cur->retries = -1; 08348 } 08349 } 08350 AST_LIST_UNLOCK(&iaxq.queue); 08351 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08352 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08353 } 08354 break; 08355 case IAX_COMMAND_DPREP: 08356 complete_dpreply(iaxs[fr->callno], &ies); 08357 break; 08358 case IAX_COMMAND_UNSUPPORT: 08359 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08360 break; 08361 case IAX_COMMAND_FWDOWNL: 08362 /* Firmware download */ 08363 memset(&ied0, 0, sizeof(ied0)); 08364 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08365 if (res < 0) 08366 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08367 else if (res > 0) 08368 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08369 else 08370 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08371 if (!iaxs[fr->callno]) { 08372 ast_mutex_unlock(&iaxsl[fr->callno]); 08373 return 1; 08374 } 08375 break; 08376 default: 08377 if (option_debug) 08378 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08379 memset(&ied0, 0, sizeof(ied0)); 08380 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08381 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08382 } 08383 /* Don't actually pass these frames along */ 08384 if ((f.subclass != IAX_COMMAND_ACK) && 08385 (f.subclass != IAX_COMMAND_TXCNT) && 08386 (f.subclass != IAX_COMMAND_TXACC) && 08387 (f.subclass != IAX_COMMAND_INVAL) && 08388 (f.subclass != IAX_COMMAND_VNAK)) { 08389 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08390 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08391 } 08392 ast_mutex_unlock(&iaxsl[fr->callno]); 08393 return 1; 08394 } 08395 /* Unless this is an ACK or INVAL frame, ack it */ 08396 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08397 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08398 } else if (minivid) { 08399 f.frametype = AST_FRAME_VIDEO; 08400 if (iaxs[fr->callno]->videoformat > 0) 08401 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08402 else { 08403 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08404 iax2_vnak(fr->callno); 08405 ast_mutex_unlock(&iaxsl[fr->callno]); 08406 return 1; 08407 } 08408 f.datalen = res - sizeof(*vh); 08409 if (f.datalen) 08410 f.data = thread->buf + sizeof(*vh); 08411 else 08412 f.data = NULL; 08413 #ifdef IAXTESTS 08414 if (test_resync) { 08415 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08416 } else 08417 #endif /* IAXTESTS */ 08418 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08419 } else { 08420 /* A mini frame */ 08421 f.frametype = AST_FRAME_VOICE; 08422 if (iaxs[fr->callno]->voiceformat > 0) 08423 f.subclass = iaxs[fr->callno]->voiceformat; 08424 else { 08425 if (option_debug) 08426 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08427 iax2_vnak(fr->callno); 08428 ast_mutex_unlock(&iaxsl[fr->callno]); 08429 return 1; 08430 } 08431 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08432 if (f.datalen < 0) { 08433 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08434 ast_mutex_unlock(&iaxsl[fr->callno]); 08435 return 1; 08436 } 08437 if (f.datalen) 08438 f.data = thread->buf + sizeof(*mh); 08439 else 08440 f.data = NULL; 08441 #ifdef IAXTESTS 08442 if (test_resync) { 08443 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08444 } else 08445 #endif /* IAXTESTS */ 08446 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08447 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08448 } 08449 /* Don't pass any packets until we're started */ 08450 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08451 ast_mutex_unlock(&iaxsl[fr->callno]); 08452 return 1; 08453 } 08454 /* Common things */ 08455 f.src = "IAX2"; 08456 f.mallocd = 0; 08457 f.offset = 0; 08458 f.len = 0; 08459 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08460 f.samples = ast_codec_get_samples(&f); 08461 /* We need to byteswap incoming slinear samples from network byte order */ 08462 if (f.subclass == AST_FORMAT_SLINEAR) 08463 ast_frame_byteswap_be(&f); 08464 } else 08465 f.samples = 0; 08466 iax_frame_wrap(fr, &f); 08467 08468 /* If this is our most recent packet, use it as our basis for timestamping */ 08469 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08470 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08471 fr->outoforder = 0; 08472 } else { 08473 if (option_debug && iaxdebug && iaxs[fr->callno]) 08474 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); 08475 fr->outoforder = -1; 08476 } 08477 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08478 duped_fr = iaxfrdup2(fr); 08479 if (duped_fr) { 08480 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08481 } 08482 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08483 iaxs[fr->callno]->last = fr->ts; 08484 #if 1 08485 if (option_debug && iaxdebug) 08486 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08487 #endif 08488 } 08489 08490 /* Always run again */ 08491 ast_mutex_unlock(&iaxsl[fr->callno]); 08492 return 1; 08493 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6864 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), 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(), len, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06865 { 06866 struct iax2_thread *thread; 06867 socklen_t len; 06868 time_t t; 06869 static time_t last_errtime = 0; 06870 struct ast_iax2_full_hdr *fh; 06871 06872 if (!(thread = find_idle_thread())) { 06873 time(&t); 06874 if (t != last_errtime && option_debug) 06875 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06876 last_errtime = t; 06877 usleep(1); 06878 return 1; 06879 } 06880 06881 len = sizeof(thread->iosin); 06882 thread->iofd = fd; 06883 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06884 thread->buf_size = sizeof(thread->readbuf); 06885 thread->buf = thread->readbuf; 06886 if (thread->buf_len < 0) { 06887 if (errno != ECONNREFUSED && errno != EAGAIN) 06888 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06889 handle_error(); 06890 thread->iostate = IAX_IOSTATE_IDLE; 06891 signal_condition(&thread->lock, &thread->cond); 06892 return 1; 06893 } 06894 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06895 thread->iostate = IAX_IOSTATE_IDLE; 06896 signal_condition(&thread->lock, &thread->cond); 06897 return 1; 06898 } 06899 06900 /* Determine if this frame is a full frame; if so, and any thread is currently 06901 processing a full frame for the same callno from this peer, then drop this 06902 frame (and the peer will retransmit it) */ 06903 fh = (struct ast_iax2_full_hdr *) thread->buf; 06904 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06905 struct iax2_thread *cur = NULL; 06906 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06907 06908 AST_LIST_LOCK(&active_list); 06909 AST_LIST_TRAVERSE(&active_list, cur, list) { 06910 if ((cur->ffinfo.callno == callno) && 06911 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06912 break; 06913 } 06914 if (cur) { 06915 /* we found another thread processing a full frame for this call, 06916 so queue it up for processing later. */ 06917 defer_full_frame(thread, cur); 06918 AST_LIST_UNLOCK(&active_list); 06919 thread->iostate = IAX_IOSTATE_IDLE; 06920 signal_condition(&thread->lock, &thread->cond); 06921 return 1; 06922 } else { 06923 /* this thread is going to process this frame, so mark it */ 06924 thread->ffinfo.callno = callno; 06925 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06926 thread->ffinfo.type = fh->type; 06927 thread->ffinfo.csub = fh->csub; 06928 } 06929 AST_LIST_UNLOCK(&active_list); 06930 } 06931 06932 /* Mark as ready and send on its way */ 06933 thread->iostate = IAX_IOSTATE_READY; 06934 #ifdef DEBUG_SCHED_MULTITHREAD 06935 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06936 #endif 06937 signal_condition(&thread->lock, &thread->cond); 06938 06939 return 1; 06940 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6651 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06652 { 06653 pthread_t newthread; 06654 struct dpreq_data *dpr; 06655 pthread_attr_t attr; 06656 06657 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06658 return; 06659 06660 pthread_attr_init(&attr); 06661 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06662 06663 dpr->callno = callno; 06664 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06665 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06666 if (callerid) 06667 dpr->callerid = ast_strdup(callerid); 06668 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06669 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06670 } 06671 06672 pthread_attr_destroy(&attr); 06673 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9095 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, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
09096 { 09097 pthread_attr_t attr; 09098 int threadcount = 0; 09099 int x; 09100 for (x = 0; x < iaxthreadcount; x++) { 09101 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09102 if (thread) { 09103 thread->type = IAX_TYPE_POOL; 09104 thread->threadnum = ++threadcount; 09105 ast_mutex_init(&thread->lock); 09106 ast_cond_init(&thread->cond, NULL); 09107 pthread_attr_init(&attr); 09108 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09109 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09110 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09111 free(thread); 09112 thread = NULL; 09113 } 09114 AST_LIST_LOCK(&idle_list); 09115 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09116 AST_LIST_UNLOCK(&idle_list); 09117 } 09118 } 09119 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09120 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09121 if (option_verbose > 1) 09122 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 09123 return 0; 09124 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6333 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06334 { 06335 iax2_destroy_helper(iaxs[callno]); 06336 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1238 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().
01239 { 01240 if (!pvt->peercallno) { 01241 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01242 return; 01243 } 01244 01245 ao2_link(iax_peercallno_pvts, pvt); 01246 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6520 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(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06521 { 06522 char buf[1024]; 06523 int res; 06524 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06525 int processed = 0; 06526 int totalcalls = 0; 06527 #ifdef ZT_TIMERACK 06528 int x = 1; 06529 #endif 06530 struct timeval now; 06531 if (iaxtrunkdebug) 06532 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06533 gettimeofday(&now, NULL); 06534 if (events & AST_IO_PRI) { 06535 #ifdef ZT_TIMERACK 06536 /* Great, this is a timing interface, just call the ioctl */ 06537 if (ioctl(fd, ZT_TIMERACK, &x)) { 06538 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06539 usleep(1); 06540 return -1; 06541 } 06542 #endif 06543 } else { 06544 /* Read and ignore from the pseudo channel for timing */ 06545 res = read(fd, buf, sizeof(buf)); 06546 if (res < 1) { 06547 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06548 return 1; 06549 } 06550 } 06551 /* For each peer that supports trunking... */ 06552 ast_mutex_lock(&tpeerlock); 06553 tpeer = tpeers; 06554 while(tpeer) { 06555 processed++; 06556 res = 0; 06557 ast_mutex_lock(&tpeer->lock); 06558 /* We can drop a single tpeer per pass. That makes all this logic 06559 substantially easier */ 06560 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06561 /* Take it out of the list, but don't free it yet, because it 06562 could be in use */ 06563 if (prev) 06564 prev->next = tpeer->next; 06565 else 06566 tpeers = tpeer->next; 06567 drop = tpeer; 06568 } else { 06569 res = send_trunk(tpeer, &now); 06570 if (iaxtrunkdebug) 06571 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); 06572 } 06573 totalcalls += res; 06574 res = 0; 06575 ast_mutex_unlock(&tpeer->lock); 06576 prev = tpeer; 06577 tpeer = tpeer->next; 06578 } 06579 ast_mutex_unlock(&tpeerlock); 06580 if (drop) { 06581 ast_mutex_lock(&drop->lock); 06582 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06583 because by the time they could get tpeerlock, we've already grabbed it */ 06584 if (option_debug) 06585 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06586 if (drop->trunkdata) { 06587 free(drop->trunkdata); 06588 drop->trunkdata = NULL; 06589 } 06590 ast_mutex_unlock(&drop->lock); 06591 ast_mutex_destroy(&drop->lock); 06592 free(drop); 06593 06594 } 06595 if (iaxtrunkdebug) 06596 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06597 iaxtrunkdebug =0; 06598 return 1; 06599 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2064 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02065 { 02066 int res; 02067 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02068 sizeof(*sin)); 02069 if (res < 0) { 02070 if (option_debug) 02071 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02072 handle_error(); 02073 } else 02074 res = 0; 02075 return res; 02076 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1752 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, 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, len, 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().
01753 { 01754 struct stat stbuf; 01755 struct iax_firmware *cur; 01756 int ifd; 01757 int fd; 01758 int res; 01759 01760 struct ast_iax2_firmware_header *fwh, fwh2; 01761 struct MD5Context md5; 01762 unsigned char sum[16]; 01763 unsigned char buf[1024]; 01764 int len, chunk; 01765 char *s2; 01766 char *last; 01767 s2 = alloca(strlen(s) + 100); 01768 if (!s2) { 01769 ast_log(LOG_WARNING, "Alloca failed!\n"); 01770 return -1; 01771 } 01772 last = strrchr(s, '/'); 01773 if (last) 01774 last++; 01775 else 01776 last = s; 01777 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01778 res = stat(s, &stbuf); 01779 if (res < 0) { 01780 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01781 return -1; 01782 } 01783 /* Make sure it's not a directory */ 01784 if (S_ISDIR(stbuf.st_mode)) 01785 return -1; 01786 ifd = open(s, O_RDONLY); 01787 if (ifd < 0) { 01788 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01789 return -1; 01790 } 01791 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01792 if (fd < 0) { 01793 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01794 close(ifd); 01795 return -1; 01796 } 01797 /* Unlink our newly created file */ 01798 unlink(s2); 01799 01800 /* Now copy the firmware into it */ 01801 len = stbuf.st_size; 01802 while(len) { 01803 chunk = len; 01804 if (chunk > sizeof(buf)) 01805 chunk = sizeof(buf); 01806 res = read(ifd, buf, chunk); 01807 if (res != chunk) { 01808 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01809 close(ifd); 01810 close(fd); 01811 return -1; 01812 } 01813 res = write(fd, buf, chunk); 01814 if (res != chunk) { 01815 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01816 close(ifd); 01817 close(fd); 01818 return -1; 01819 } 01820 len -= chunk; 01821 } 01822 close(ifd); 01823 /* Return to the beginning */ 01824 lseek(fd, 0, SEEK_SET); 01825 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01826 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01827 close(fd); 01828 return -1; 01829 } 01830 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01831 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01832 close(fd); 01833 return -1; 01834 } 01835 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01836 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01837 close(fd); 01838 return -1; 01839 } 01840 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01841 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01842 close(fd); 01843 return -1; 01844 } 01845 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01846 if (fwh == (void *) -1) { 01847 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01848 close(fd); 01849 return -1; 01850 } 01851 MD5Init(&md5); 01852 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01853 MD5Final(sum, &md5); 01854 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01855 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01856 munmap((void*)fwh, stbuf.st_size); 01857 close(fd); 01858 return -1; 01859 } 01860 cur = waresl.wares; 01861 while(cur) { 01862 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01863 /* Found a candidate */ 01864 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01865 /* The version we have on loaded is older, load this one instead */ 01866 break; 01867 /* This version is no newer than what we have. Don't worry about it. 01868 We'll consider it a proper load anyhow though */ 01869 munmap((void*)fwh, stbuf.st_size); 01870 close(fd); 01871 return 0; 01872 } 01873 cur = cur->next; 01874 } 01875 if (!cur) { 01876 /* Allocate a new one and link it */ 01877 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01878 cur->fd = -1; 01879 cur->next = waresl.wares; 01880 waresl.wares = cur; 01881 } 01882 } 01883 if (cur) { 01884 if (cur->fwh) { 01885 munmap((void*)cur->fwh, cur->mmaplen); 01886 } 01887 if (cur->fd > -1) 01888 close(cur->fd); 01889 cur->fwh = fwh; 01890 cur->fd = fd; 01891 cur->mmaplen = stbuf.st_size; 01892 cur->dead = 0; 01893 } 01894 return 0; 01895 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5735 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(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05736 { 05737 int newcall = 0; 05738 char newip[256]; 05739 struct iax_ie_data ied; 05740 struct sockaddr_in new; 05741 05742 05743 memset(&ied, 0, sizeof(ied)); 05744 if (ies->apparent_addr) 05745 bcopy(ies->apparent_addr, &new, sizeof(new)); 05746 if (ies->callno) 05747 newcall = ies->callno; 05748 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05749 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05750 return -1; 05751 } 05752 pvt->transfercallno = newcall; 05753 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05754 inet_aton(newip, &pvt->transfer.sin_addr); 05755 pvt->transfer.sin_family = AF_INET; 05756 pvt->transferring = TRANSFER_BEGIN; 05757 pvt->transferid = ies->transferid; 05758 if (ies->transferid) 05759 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05760 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05761 return 0; 05762 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1083 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01084 { 01085 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01086 if (csub & IAX_FLAG_SC_LOG) { 01087 /* special case for 'compressed' -1 */ 01088 if (csub == 0xff) 01089 return -1; 01090 else 01091 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01092 } 01093 else 01094 return csub; 01095 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6007 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
06008 { 06009 if (peer->expire > -1) { 06010 if (!ast_sched_del(sched, peer->expire)) { 06011 peer->expire = -1; 06012 peer_unref(peer); 06013 } 06014 } 06015 06016 if (peer->pokeexpire > -1) { 06017 if (!ast_sched_del(sched, peer->pokeexpire)) { 06018 peer->pokeexpire = -1; 06019 peer_unref(peer); 06020 } 06021 } 06022 06023 ao2_unlink(peers, peer); 06024 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11018 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11019 { 11020 ast_custom_function_unregister(&iaxpeer_function); 11021 return __unload_module(); 11022 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3463 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03464 { 03465 ast_mutex_unlock(&iaxsl[callno1]); 03466 ast_mutex_unlock(&iaxsl[callno0]); 03467 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2498 of file chan_iax2.c.
References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02499 { 02500 int x; 02501 02502 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02503 x = fr->ts - iaxs[fr->callno]->last; 02504 if (x < -50000) { 02505 /* Sudden big jump backwards in timestamp: 02506 What likely happened here is that miniframe timestamp has circled but we haven't 02507 gotten the update from the main packet. We'll just pretend that we did, and 02508 update the timestamp appropriately. */ 02509 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02510 if (option_debug && iaxdebug) 02511 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02512 } 02513 if (x > 50000) { 02514 /* Sudden apparent big jump forwards in timestamp: 02515 What's likely happened is this is an old miniframe belonging to the previous 02516 top-16-bit timestamp that has turned up out of order. 02517 Adjust the timestamp appropriately. */ 02518 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02519 if (option_debug && iaxdebug) 02520 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02521 } 02522 } 02523 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2527 of file chan_iax2.c.
References AST_SCHED_DEL, 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().
02528 { 02529 int when; 02530 02531 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02532 02533 when = jb_next(pvt->jb) - when; 02534 02535 AST_SCHED_DEL(sched, pvt->jbid); 02536 02537 if(when <= 0) { 02538 /* XXX should really just empty until when > 0.. */ 02539 when = 1; 02540 } 02541 02542 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02543 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1451 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01452 { 01453 int max = 1; 01454 int x; 01455 /* XXX Prolly don't need locks here XXX */ 01456 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01457 if (iaxs[x]) 01458 max = x + 1; 01459 } 01460 maxnontrunkcall = max; 01461 if (option_debug && iaxdebug) 01462 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01463 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1258 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01259 { 01260 int max = TRUNK_CALL_START; 01261 int x; 01262 01263 /* XXX Prolly don't need locks here XXX */ 01264 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01265 if (iaxs[x]) { 01266 max = x + 1; 01267 } 01268 } 01269 01270 maxtrunkcall = max; 01271 if (option_debug && iaxdebug) 01272 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01273 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2135 of file chan_iax2.c.
References ast_iax2_full_hdr::dcallno, f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
02136 { 02137 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02138 struct ast_iax2_full_hdr *fh = f->data; 02139 /* Mark this as a retransmission */ 02140 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02141 /* Update iseqno */ 02142 f->iseqno = iaxs[f->callno]->iseqno; 02143 fh->iseqno = f->iseqno; 02144 return 0; 02145 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6118 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(), 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, manager_event(), option_verbose, peer_ref(), peer_unref(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
06119 { 06120 /* Called from IAX thread only, with proper iaxsl lock */ 06121 struct iax_ie_data ied; 06122 struct iax2_peer *p; 06123 int msgcount; 06124 char data[80]; 06125 int version; 06126 const char *peer_name; 06127 int res = -1; 06128 06129 memset(&ied, 0, sizeof(ied)); 06130 06131 peer_name = ast_strdupa(iaxs[callno]->peer); 06132 06133 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06134 ast_mutex_unlock(&iaxsl[callno]); 06135 if (!(p = find_peer(peer_name, 1))) { 06136 ast_mutex_lock(&iaxsl[callno]); 06137 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06138 return -1; 06139 } 06140 ast_mutex_lock(&iaxsl[callno]); 06141 if (!iaxs[callno]) 06142 goto return_unref; 06143 06144 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06145 if (sin->sin_addr.s_addr) { 06146 time_t nowtime; 06147 time(&nowtime); 06148 realtime_update_peer(peer_name, sin, nowtime); 06149 } else { 06150 realtime_update_peer(peer_name, sin, 0); 06151 } 06152 } 06153 if (inaddrcmp(&p->addr, sin)) { 06154 if (iax2_regfunk) 06155 iax2_regfunk(p->name, 1); 06156 /* Stash the IP address from which they registered */ 06157 memcpy(&p->addr, sin, sizeof(p->addr)); 06158 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06159 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06160 ast_db_put("IAX/Registry", p->name, data); 06161 if (option_verbose > 2) 06162 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06163 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06164 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06165 register_peer_exten(p, 1); 06166 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06167 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06168 if (option_verbose > 2) 06169 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06170 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06171 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06172 register_peer_exten(p, 0); 06173 ast_db_del("IAX/Registry", p->name); 06174 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06175 } 06176 /* Update the host */ 06177 /* Verify that the host is really there */ 06178 iax2_poke_peer(p, callno); 06179 } 06180 06181 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06182 if (!iaxs[callno]) { 06183 res = 0; 06184 goto return_unref; 06185 } 06186 06187 /* Store socket fd */ 06188 p->sockfd = fd; 06189 /* Setup the expiry */ 06190 if (p->expire > -1) { 06191 if (!ast_sched_del(sched, p->expire)) { 06192 p->expire = -1; 06193 peer_unref(p); 06194 } 06195 } 06196 /* treat an unspecified refresh interval as the minimum */ 06197 if (!refresh) 06198 refresh = min_reg_expire; 06199 if (refresh > max_reg_expire) { 06200 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06201 p->name, max_reg_expire, refresh); 06202 p->expiry = max_reg_expire; 06203 } else if (refresh < min_reg_expire) { 06204 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06205 p->name, min_reg_expire, refresh); 06206 p->expiry = min_reg_expire; 06207 } else { 06208 p->expiry = refresh; 06209 } 06210 if (p->expiry && sin->sin_addr.s_addr) { 06211 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06212 if (p->expire == -1) 06213 peer_unref(p); 06214 } 06215 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06216 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06217 if (sin->sin_addr.s_addr) { 06218 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06219 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06220 if (!ast_strlen_zero(p->mailbox)) { 06221 int new, old; 06222 ast_app_inboxcount(p->mailbox, &new, &old); 06223 if (new > 255) 06224 new = 255; 06225 if (old > 255) 06226 old = 255; 06227 msgcount = (old << 8) | new; 06228 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06229 } 06230 if (ast_test_flag(p, IAX_HASCALLERID)) { 06231 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06232 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06233 } 06234 } 06235 version = iax_check_version(devtype); 06236 if (version) 06237 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06238 06239 res = 0; 06240 06241 return_unref: 06242 peer_unref(p); 06243 06244 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06245 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1130 of file chan_iax2.c.
Referenced by load_module().
01131 { 01132 struct iax2_user *user = obj, *user2 = arg; 01133 01134 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01135 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9735 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09736 { 09737 struct iax2_user *user = obj; 09738 09739 ast_set_flag(user, IAX_DELME); 09740 09741 return 0; 09742 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9499 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().
09500 { 09501 struct iax2_user *user = obj; 09502 09503 ast_free_ha(user->ha); 09504 free_context(user->contexts); 09505 if(user->vars) { 09506 ast_variables_destroy(user->vars); 09507 user->vars = NULL; 09508 } 09509 ast_string_field_free_memory(user); 09510 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1120 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01121 { 01122 const struct iax2_user *user = obj; 01123 01124 return ast_str_hash(user->name); 01125 }
Definition at line 1169 of file chan_iax2.c.
References ao2_ref().
01170 { 01171 ao2_ref(user, +1); 01172 return user; 01173 }
Definition at line 1175 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), prune_users(), and set_config().
01176 { 01177 ao2_ref(user, -1); 01178 return NULL; 01179 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6434 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, and send_packet().
Referenced by socket_process().
06435 { 06436 struct iax_frame *f; 06437 06438 AST_LIST_LOCK(&iaxq.queue); 06439 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06440 /* Send a copy immediately */ 06441 if ((f->callno == callno) && iaxs[f->callno] && 06442 ((unsigned char ) (f->oseqno - last) < 128) && 06443 (f->retries >= 0)) { 06444 send_packet(f); 06445 } 06446 } 06447 AST_LIST_UNLOCK(&iaxq.queue); 06448 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
int amaflags = 0 [static] |
int authdebug = 1 [static] |
Definition at line 158 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 159 of file chan_iax2.c.
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 10814 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 10819 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 10829 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 10824 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 10809 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 145 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 10783 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 10775 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 10767 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 175 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 223 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
int global_rtautoclear = 120 [static] |
Definition at line 276 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 226 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), 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(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 204 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 224 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 177 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 10725 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 865 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 10791 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 824 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_peercallno(), and store_by_peercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 452 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 164 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 451 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
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 811 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __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_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 812 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), and update_registry().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 449 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 208 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 201 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 153 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 147 of file chan_iax2.c.
Definition at line 813 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 169 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 151 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 150 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 154 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 156 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 831 of file chan_iax2.c.
Referenced by __find_callno(), and update_max_nontrunk().
int maxtrunkcall = TRUNK_CALL_START [static] |
int min_reg_expire [static] |
Definition at line 168 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 219 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 173 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 228 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 10787 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 10779 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 10771 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 174 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 8742 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 8744 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 649 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), abort_request(), authenticate_reply(), build_peer(), build_transactions(), cancel_request(), chanavail_exec(), check_request(), complete_iax2_show_peer(), complete_peer_helper(), delete_users(), destroy_trans(), discover_transactions(), dundi_flush(), dundi_ie_append_eid_appropriately(), dundi_lookup_thread(), dundi_precache_internal(), dundi_precache_thread(), dundi_query_thread(), dundi_rexmit(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), dundi_show_trans(), find_peer(), handle_command_response(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), mark_mappings(), mark_peers(), network_thread(), optimize_transactions(), poke_all_peers(), precache_transactions(), prune_mappings(), prune_peers(), query_transactions(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 152 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 141 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 10721 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8743 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 148 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 155 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 202 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 231 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 10713 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 10741 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 10759 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 10745 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 10717 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 10753 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10729 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 10763 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 10709 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 10749 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 10736 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 143 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 210 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 171 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 166 of file chan_iax2.c.
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 157 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 652 of file chan_iax2.c.
Referenced by __unload_module(), ast_get_manager_by_name_locked(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_voicemail_show_users(), delete_users(), find_or_create(), find_user(), handle_showmanager(), handle_showmanagers(), handle_voicemail_show_users(), iax2_destroy_helper(), iax2_show_users(), init_manager(), load_config(), load_module(), prune_users(), reset_user_pw(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().