#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"
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) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
enum | 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_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno) |
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 |
struct ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static 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 666 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 662 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 676 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 664 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 668 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 670 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 672 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 674 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 200 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 199 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 198 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 442 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 181 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 189 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 194 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 183 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
Definition at line 700 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 703 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 439 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 648 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 445 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 443 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 440 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 1431 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 984 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 830 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 448 of file chan_iax2.c.
anonymous enum |
Definition at line 234 of file chan_iax2.c.
00234 { 00235 IAX_STATE_STARTED = (1 << 0), 00236 IAX_STATE_AUTHENTICATED = (1 << 1), 00237 IAX_STATE_TBD = (1 << 2), 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 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00275 } 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 394 of file chan_iax2.c.
00394 { 00395 REG_STATE_UNREGISTERED = 0, 00396 REG_STATE_REGSENT, 00397 REG_STATE_AUTHSENT, 00398 REG_STATE_REGISTERED, 00399 REG_STATE_REJECTED, 00400 REG_STATE_TIMEOUT, 00401 REG_STATE_NOAUTH 00402 };
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 404 of file chan_iax2.c.
00404 { 00405 TRANSFER_NONE = 0, 00406 TRANSFER_BEGIN, 00407 TRANSFER_READY, 00408 TRANSFER_RELEASED, 00409 TRANSFER_PASSTHROUGH, 00410 TRANSFER_MBEGIN, 00411 TRANSFER_MREADY, 00412 TRANSFER_MRELEASED, 00413 TRANSFER_MPASSTHROUGH, 00414 TRANSFER_MEDIA, 00415 TRANSFER_MEDIAPASS 00416 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2150 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, 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, iax2_registry::callno, chan_iax2_pvt::error, f, iax_frame::final, 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, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02151 { 02152 /* Attempt to transmit the frame to the remote peer... 02153 Called without iaxsl held. */ 02154 struct iax_frame *f = (struct iax_frame *)data; 02155 int freeme=0; 02156 int callno = f->callno; 02157 /* Make sure this call is still active */ 02158 if (callno) 02159 ast_mutex_lock(&iaxsl[callno]); 02160 if (callno && iaxs[callno]) { 02161 if ((f->retries < 0) /* Already ACK'd */ || 02162 (f->retries >= max_retries) /* Too many attempts */) { 02163 /* Record an error if we've transmitted too many times */ 02164 if (f->retries >= max_retries) { 02165 if (f->transfer) { 02166 /* Transfer timeout */ 02167 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02168 } else if (f->final) { 02169 if (f->final) 02170 iax2_destroy(callno); 02171 } else { 02172 if (iaxs[callno]->owner) 02173 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); 02174 iaxs[callno]->error = ETIMEDOUT; 02175 if (iaxs[callno]->owner) { 02176 struct ast_frame fr = { 0, }; 02177 /* Hangup the fd */ 02178 fr.frametype = AST_FRAME_CONTROL; 02179 fr.subclass = AST_CONTROL_HANGUP; 02180 iax2_queue_frame(callno, &fr); // XXX 02181 /* Remember, owner could disappear */ 02182 if (iaxs[callno] && iaxs[callno]->owner) 02183 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02184 } else { 02185 if (iaxs[callno]->reg) { 02186 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02187 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02188 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02189 } 02190 iax2_destroy(callno); 02191 } 02192 } 02193 02194 } 02195 freeme++; 02196 } else { 02197 /* Update it if it needs it */ 02198 update_packet(f); 02199 /* Attempt transmission */ 02200 send_packet(f); 02201 f->retries++; 02202 /* Try again later after 10 times as long */ 02203 f->retrytime *= 10; 02204 if (f->retrytime > MAX_RETRY_TIME) 02205 f->retrytime = MAX_RETRY_TIME; 02206 /* Transfer messages max out at one second */ 02207 if (f->transfer && (f->retrytime > 1000)) 02208 f->retrytime = 1000; 02209 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02210 } 02211 } else { 02212 /* Make sure it gets freed */ 02213 f->retries = -1; 02214 freeme++; 02215 } 02216 if (callno) 02217 ast_mutex_unlock(&iaxsl[callno]); 02218 /* Do not try again */ 02219 if (freeme) { 02220 /* Don't attempt delivery, just remove it from the queue */ 02221 AST_LIST_LOCK(&iaxq.queue); 02222 AST_LIST_REMOVE(&iaxq.queue, f, list); 02223 iaxq.count--; 02224 AST_LIST_UNLOCK(&iaxq.queue); 02225 f->retrans = -1; 02226 /* Free the IAX frame */ 02227 iax2_frame_free(f); 02228 } 02229 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6405 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_ie_data::buf, iax2_registry::callno, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
06406 { 06407 /* Called from IAX thread only, without iaxs lock */ 06408 int callno = (int)(long)(nothing); 06409 struct iax_ie_data ied; 06410 ast_mutex_lock(&iaxsl[callno]); 06411 if (iaxs[callno]) { 06412 memset(&ied, 0, sizeof(ied)); 06413 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06414 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06415 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06416 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06417 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06418 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06419 } 06420 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06421 } 06422 ast_mutex_unlock(&iaxsl[callno]); 06423 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3105 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03106 { 03107 int callno = PTR_TO_CALLNO(nothing); 03108 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03109 ast_mutex_lock(&iaxsl[callno]); 03110 if (iaxs[callno]) { 03111 iaxs[callno]->initid = -1; 03112 iax2_queue_frame(callno, &f); 03113 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03114 } 03115 ast_mutex_unlock(&iaxsl[callno]); 03116 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6454 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
06455 { 06456 /* Called from IAX thread only, without iaxs lock */ 06457 int callno = (int)(long)(nothing); 06458 struct iax_ie_data ied; 06459 ast_mutex_lock(&iaxsl[callno]); 06460 if (iaxs[callno]) { 06461 memset(&ied, 0, sizeof(ied)); 06462 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06463 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06464 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06465 } 06466 ast_mutex_unlock(&iaxsl[callno]); 06467 }
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 2017 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().
02018 { 02019 /* Just deliver the packet by using queueing. This is called by 02020 the IAX thread with the iaxsl lock held. */ 02021 struct iax_frame *fr = data; 02022 fr->retrans = -1; 02023 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02024 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02025 iax2_queue_frame(fr->callno, &fr->af); 02026 /* Free our iax frame */ 02027 iax2_frame_free(fr); 02028 /* And don't run again */ 02029 return 0; 02030 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6084 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, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, LOG_DEBUG, manager_event(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
06085 { 06086 struct iax2_peer *peer = (struct iax2_peer *) data; 06087 06088 if (!peer) 06089 return; 06090 06091 peer->expire = -1; 06092 06093 if (option_debug) 06094 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06095 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06096 realtime_update_peer(peer->name, &peer->addr, 0); 06097 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06098 /* Reset the address */ 06099 memset(&peer->addr, 0, sizeof(peer->addr)); 06100 /* Reset expiry value */ 06101 peer->expiry = min_reg_expire; 06102 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06103 ast_db_del("IAX/Registry", peer->name); 06104 register_peer_exten(peer, 0); 06105 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06106 if (iax2_regfunk) 06107 iax2_regfunk(peer->name, 0); 06108 06109 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06110 unlink_peer(peer); 06111 06112 peer_unref(peer); 06113 }
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 1516 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01517 { 01518 int res = 0; 01519 int x; 01520 struct timeval now; 01521 char host[80]; 01522 01523 if (new <= NEW_ALLOW) { 01524 if (callno) { 01525 struct chan_iax2_pvt *pvt; 01526 struct chan_iax2_pvt tmp_pvt = { 01527 .callno = dcallno, 01528 .peercallno = callno, 01529 /* hack!! */ 01530 .frames_received = check_dcallno, 01531 }; 01532 01533 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01534 01535 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01536 if (return_locked) { 01537 ast_mutex_lock(&iaxsl[pvt->callno]); 01538 } 01539 res = pvt->callno; 01540 ao2_ref(pvt, -1); 01541 pvt = NULL; 01542 return res; 01543 } 01544 } 01545 01546 /* Look for an existing connection first */ 01547 for (x = 1; !res && x < maxnontrunkcall; x++) { 01548 ast_mutex_lock(&iaxsl[x]); 01549 if (iaxs[x]) { 01550 /* Look for an exact match */ 01551 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01552 res = x; 01553 } 01554 } 01555 if (!res || !return_locked) 01556 ast_mutex_unlock(&iaxsl[x]); 01557 } 01558 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01559 ast_mutex_lock(&iaxsl[x]); 01560 if (iaxs[x]) { 01561 /* Look for an exact match */ 01562 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01563 res = x; 01564 } 01565 } 01566 if (!res || !return_locked) 01567 ast_mutex_unlock(&iaxsl[x]); 01568 } 01569 } 01570 if (!res && (new >= NEW_ALLOW)) { 01571 int start, found = 0; 01572 01573 /* It may seem odd that we look through the peer list for a name for 01574 * this *incoming* call. Well, it is weird. However, users don't 01575 * have an IP address/port number that we can match against. So, 01576 * this is just checking for a peer that has that IP/port and 01577 * assuming that we have a user of the same name. This isn't always 01578 * correct, but it will be changed if needed after authentication. */ 01579 if (!iax2_getpeername(*sin, host, sizeof(host))) 01580 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01581 01582 now = ast_tvnow(); 01583 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01584 for (x = start; 1; x++) { 01585 if (x == TRUNK_CALL_START) { 01586 x = 1; 01587 continue; 01588 } 01589 01590 /* Find first unused call number that hasn't been used in a while */ 01591 ast_mutex_lock(&iaxsl[x]); 01592 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01593 found = 1; 01594 break; 01595 } 01596 ast_mutex_unlock(&iaxsl[x]); 01597 01598 if (x == start - 1) { 01599 break; 01600 } 01601 } 01602 /* We've still got lock held if we found a spot */ 01603 if (x == start - 1 && !found) { 01604 ast_log(LOG_WARNING, "No more space\n"); 01605 return 0; 01606 } 01607 iaxs[x] = new_iax(sin, host); 01608 update_max_nontrunk(); 01609 if (iaxs[x]) { 01610 if (option_debug && iaxdebug) 01611 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01612 iaxs[x]->sockfd = sockfd; 01613 iaxs[x]->addr.sin_port = sin->sin_port; 01614 iaxs[x]->addr.sin_family = sin->sin_family; 01615 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01616 iaxs[x]->peercallno = callno; 01617 iaxs[x]->callno = x; 01618 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01619 iaxs[x]->expiry = min_reg_expire; 01620 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01621 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01622 iaxs[x]->amaflags = amaflags; 01623 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01624 01625 ast_string_field_set(iaxs[x], accountcode, accountcode); 01626 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01627 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01628 01629 if (iaxs[x]->peercallno) { 01630 store_by_peercallno(iaxs[x]); 01631 } 01632 } else { 01633 ast_log(LOG_WARNING, "Out of resources\n"); 01634 ast_mutex_unlock(&iaxsl[x]); 01635 return 0; 01636 } 01637 if (!return_locked) 01638 ast_mutex_unlock(&iaxsl[x]); 01639 res = x; 01640 } 01641 return res; 01642 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2547 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(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, 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().
02548 { 02549 int callno = PTR_TO_CALLNO(p); 02550 struct chan_iax2_pvt *pvt = NULL; 02551 struct iax_frame *fr; 02552 jb_frame frame; 02553 int ret; 02554 long now; 02555 long next; 02556 struct timeval tv; 02557 02558 /* Make sure we have a valid private structure before going on */ 02559 ast_mutex_lock(&iaxsl[callno]); 02560 pvt = iaxs[callno]; 02561 if (!pvt) { 02562 /* No go! */ 02563 ast_mutex_unlock(&iaxsl[callno]); 02564 return; 02565 } 02566 02567 pvt->jbid = -1; 02568 02569 gettimeofday(&tv,NULL); 02570 /* round up a millisecond since ast_sched_runq does; */ 02571 /* prevents us from spinning while waiting for our now */ 02572 /* to catch up with runq's now */ 02573 tv.tv_usec += 1000; 02574 02575 now = ast_tvdiff_ms(tv, pvt->rxcore); 02576 02577 if(now >= (next = jb_next(pvt->jb))) { 02578 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02579 switch(ret) { 02580 case JB_OK: 02581 fr = frame.data; 02582 __do_deliver(fr); 02583 /* __do_deliver() can cause the call to disappear */ 02584 pvt = iaxs[callno]; 02585 break; 02586 case JB_INTERP: 02587 { 02588 struct ast_frame af = { 0, }; 02589 02590 /* create an interpolation frame */ 02591 af.frametype = AST_FRAME_VOICE; 02592 af.subclass = pvt->voiceformat; 02593 af.samples = frame.ms * 8; 02594 af.src = "IAX2 JB interpolation"; 02595 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02596 af.offset = AST_FRIENDLY_OFFSET; 02597 02598 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02599 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02600 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02601 iax2_queue_frame(callno, &af); 02602 /* iax2_queue_frame() could cause the call to disappear */ 02603 pvt = iaxs[callno]; 02604 } 02605 } 02606 break; 02607 case JB_DROP: 02608 iax2_frame_free(frame.data); 02609 break; 02610 case JB_NOFRAME: 02611 case JB_EMPTY: 02612 /* do nothing */ 02613 break; 02614 default: 02615 /* shouldn't happen */ 02616 break; 02617 } 02618 } 02619 if (pvt) 02620 update_jbsched(pvt); 02621 ast_mutex_unlock(&iaxsl[callno]); 02622 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5777 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05778 { 05779 struct iax2_registry *reg = (struct iax2_registry *)data; 05780 reg->expire = -1; 05781 iax2_do_register(reg); 05782 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8888 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, iax2_registry::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, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
08889 { 08890 struct iax2_peer *peer = (struct iax2_peer *)data; 08891 int callno; 08892 08893 if (peer->lastms > -1) { 08894 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08895 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08896 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08897 } 08898 if ((callno = peer->callno) > 0) { 08899 ast_mutex_lock(&iaxsl[callno]); 08900 iax2_destroy(callno); 08901 ast_mutex_unlock(&iaxsl[callno]); 08902 } 08903 peer->callno = 0; 08904 peer->lastms = -1; 08905 /* Try again quickly */ 08906 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08907 if (peer->pokeexpire == -1) 08908 peer_unref(peer); 08909 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6517 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06518 { 06519 struct iax2_peer *peer = (struct iax2_peer *)data; 06520 iax2_poke_peer(peer, 0); 06521 peer_unref(peer); 06522 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4532 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, and RESULT_SUCCESS.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04533 { 04534 regex_t regexbuf; 04535 int havepattern = 0; 04536 int total_peers = 0; 04537 int online_peers = 0; 04538 int offline_peers = 0; 04539 int unmonitored_peers = 0; 04540 struct ao2_iterator i; 04541 04542 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04543 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04544 04545 struct iax2_peer *peer = NULL; 04546 char name[256]; 04547 int registeredonly=0; 04548 char *term = manager ? "\r\n" : "\n"; 04549 04550 switch (argc) { 04551 case 6: 04552 if (!strcasecmp(argv[3], "registered")) 04553 registeredonly = 1; 04554 else 04555 return RESULT_SHOWUSAGE; 04556 if (!strcasecmp(argv[4], "like")) { 04557 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04558 return RESULT_SHOWUSAGE; 04559 havepattern = 1; 04560 } else 04561 return RESULT_SHOWUSAGE; 04562 break; 04563 case 5: 04564 if (!strcasecmp(argv[3], "like")) { 04565 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04566 return RESULT_SHOWUSAGE; 04567 havepattern = 1; 04568 } else 04569 return RESULT_SHOWUSAGE; 04570 break; 04571 case 4: 04572 if (!strcasecmp(argv[3], "registered")) 04573 registeredonly = 1; 04574 else 04575 return RESULT_SHOWUSAGE; 04576 break; 04577 case 3: 04578 break; 04579 default: 04580 return RESULT_SHOWUSAGE; 04581 } 04582 04583 04584 if (s) 04585 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04586 else 04587 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04588 04589 i = ao2_iterator_init(peers, 0); 04590 for (peer = ao2_iterator_next(&i); peer; 04591 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04592 char nm[20]; 04593 char status[20]; 04594 char srch[2000]; 04595 int retstatus; 04596 04597 if (registeredonly && !peer->addr.sin_addr.s_addr) 04598 continue; 04599 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04600 continue; 04601 04602 if (!ast_strlen_zero(peer->username)) 04603 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04604 else 04605 ast_copy_string(name, peer->name, sizeof(name)); 04606 04607 retstatus = peer_status(peer, status, sizeof(status)); 04608 if (retstatus > 0) 04609 online_peers++; 04610 else if (!retstatus) 04611 offline_peers++; 04612 else 04613 unmonitored_peers++; 04614 04615 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04616 04617 snprintf(srch, sizeof(srch), FORMAT, name, 04618 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04619 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04620 nm, 04621 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04622 peer->encmethods ? "(E)" : " ", status, term); 04623 04624 if (s) 04625 astman_append(s, FORMAT, name, 04626 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04627 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04628 nm, 04629 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04630 peer->encmethods ? "(E)" : " ", status, term); 04631 else 04632 ast_cli(fd, FORMAT, name, 04633 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04634 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04635 nm, 04636 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04637 peer->encmethods ? "(E)" : " ", status, term); 04638 total_peers++; 04639 } 04640 04641 if (s) 04642 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04643 else 04644 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04645 04646 if (havepattern) 04647 regfree(®exbuf); 04648 04649 return RESULT_SUCCESS; 04650 #undef FORMAT 04651 #undef FORMAT2 04652 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 959 of file chan_iax2.c.
References ast_log(), find_idle_thread(), func, IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00960 { 00961 struct iax2_thread *thread = NULL; 00962 static time_t lasterror; 00963 static time_t t; 00964 00965 thread = find_idle_thread(); 00966 00967 if (thread != NULL) { 00968 thread->schedfunc = func; 00969 thread->scheddata = data; 00970 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00971 #ifdef DEBUG_SCHED_MULTITHREAD 00972 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00973 #endif 00974 signal_condition(&thread->lock, &thread->cond); 00975 return 0; 00976 } 00977 time(&t); 00978 if (t != lasterror && option_debug) 00979 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00980 lasterror = t; 00981 00982 return -1; 00983 }
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 5033 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05035 { 05036 struct ast_frame f = { 0, }; 05037 05038 f.frametype = type; 05039 f.subclass = command; 05040 f.datalen = datalen; 05041 f.src = __FUNCTION__; 05042 f.data = (void *) data; 05043 05044 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05045 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1039 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01040 { 01041 int callno = (long) data; 01042 01043 ast_mutex_lock(&iaxsl[callno]); 01044 01045 while (iaxs[callno] && iaxs[callno]->lagid > -1) { 01046 if (iaxs[callno]->peercallno) { 01047 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01048 } 01049 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01050 break; 01051 } 01052 01053 ast_mutex_unlock(&iaxsl[callno]); 01054 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 999 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01000 { 01001 int callno = (long) data; 01002 01003 ast_mutex_lock(&iaxsl[callno]); 01004 01005 while (iaxs[callno] && iaxs[callno]->pingid != -1) { 01006 if (iaxs[callno]->peercallno) { 01007 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01008 } 01009 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01010 break; 01011 } 01012 01013 ast_mutex_unlock(&iaxsl[callno]); 01014 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11015 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, papp, peers, reload_firmware(), sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
11016 { 11017 struct iax2_thread *thread = NULL; 11018 int x; 11019 11020 /* Make sure threads do not hold shared resources when they are canceled */ 11021 11022 /* Grab the sched lock resource to keep it away from threads about to die */ 11023 /* Cancel the network thread, close the net socket */ 11024 if (netthreadid != AST_PTHREADT_NULL) { 11025 AST_LIST_LOCK(&iaxq.queue); 11026 ast_mutex_lock(&sched_lock); 11027 pthread_cancel(netthreadid); 11028 ast_cond_signal(&sched_cond); 11029 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11030 AST_LIST_UNLOCK(&iaxq.queue); 11031 pthread_join(netthreadid, NULL); 11032 } 11033 if (schedthreadid != AST_PTHREADT_NULL) { 11034 ast_mutex_lock(&sched_lock); 11035 pthread_cancel(schedthreadid); 11036 ast_cond_signal(&sched_cond); 11037 ast_mutex_unlock(&sched_lock); 11038 pthread_join(schedthreadid, NULL); 11039 } 11040 11041 /* Call for all threads to halt */ 11042 AST_LIST_LOCK(&idle_list); 11043 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11044 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11045 pthread_cancel(thread->threadid); 11046 } 11047 AST_LIST_TRAVERSE_SAFE_END 11048 AST_LIST_UNLOCK(&idle_list); 11049 11050 AST_LIST_LOCK(&active_list); 11051 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11052 AST_LIST_REMOVE_CURRENT(&active_list, list); 11053 pthread_cancel(thread->threadid); 11054 } 11055 AST_LIST_TRAVERSE_SAFE_END 11056 AST_LIST_UNLOCK(&active_list); 11057 11058 AST_LIST_LOCK(&dynamic_list); 11059 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11060 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11061 pthread_cancel(thread->threadid); 11062 } 11063 AST_LIST_TRAVERSE_SAFE_END 11064 AST_LIST_UNLOCK(&dynamic_list); 11065 11066 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11067 11068 /* Wait for threads to exit */ 11069 while(0 < iaxactivethreadcount) 11070 usleep(10000); 11071 11072 ast_netsock_release(netsock); 11073 ast_netsock_release(outsock); 11074 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11075 if (iaxs[x]) { 11076 iax2_destroy(x); 11077 } 11078 } 11079 ast_manager_unregister( "IAXpeers" ); 11080 ast_manager_unregister( "IAXnetstats" ); 11081 ast_unregister_application(papp); 11082 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11083 ast_unregister_switch(&iax2_switch); 11084 ast_channel_unregister(&iax2_tech); 11085 delete_users(); 11086 iax_provision_unload(); 11087 sched_context_destroy(sched); 11088 reload_firmware(1); 11089 11090 ast_mutex_destroy(&waresl.lock); 11091 11092 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11093 ast_mutex_destroy(&iaxsl[x]); 11094 } 11095 11096 ao2_ref(peers, -1); 11097 ao2_ref(users, -1); 11098 ao2_ref(iax_peercallno_pvts, -1); 11099 11100 return 0; 11101 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5086 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05087 { 05088 while(con) { 05089 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05090 return -1; 05091 con = con->next; 05092 } 05093 return 0; 05094 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4860 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, and chan_iax2_pvt::remote_rr.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04861 { 04862 int x; 04863 int numchans = 0; 04864 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04865 ast_mutex_lock(&iaxsl[x]); 04866 if (iaxs[x]) { 04867 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04868 char *fmt; 04869 jb_info jbinfo; 04870 04871 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04872 jb_getinfo(iaxs[x]->jb, &jbinfo); 04873 localjitter = jbinfo.jitter; 04874 localdelay = jbinfo.current - jbinfo.min; 04875 locallost = jbinfo.frames_lost; 04876 locallosspct = jbinfo.losspct/1000; 04877 localdropped = jbinfo.frames_dropped; 04878 localooo = jbinfo.frames_ooo; 04879 } else { 04880 localjitter = -1; 04881 localdelay = 0; 04882 locallost = -1; 04883 locallosspct = -1; 04884 localdropped = 0; 04885 localooo = -1; 04886 } 04887 if (limit_fmt) 04888 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04889 else 04890 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04891 if (s) 04892 04893 astman_append(s, fmt, 04894 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04895 iaxs[x]->pingtime, 04896 localjitter, 04897 localdelay, 04898 locallost, 04899 locallosspct, 04900 localdropped, 04901 localooo, 04902 iaxs[x]->frames_received/1000, 04903 iaxs[x]->remote_rr.jitter, 04904 iaxs[x]->remote_rr.delay, 04905 iaxs[x]->remote_rr.losscnt, 04906 iaxs[x]->remote_rr.losspct, 04907 iaxs[x]->remote_rr.dropped, 04908 iaxs[x]->remote_rr.ooo, 04909 iaxs[x]->remote_rr.packets/1000); 04910 else 04911 ast_cli(fd, fmt, 04912 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04913 iaxs[x]->pingtime, 04914 localjitter, 04915 localdelay, 04916 locallost, 04917 locallosspct, 04918 localdropped, 04919 localooo, 04920 iaxs[x]->frames_received/1000, 04921 iaxs[x]->remote_rr.jitter, 04922 iaxs[x]->remote_rr.delay, 04923 iaxs[x]->remote_rr.losscnt, 04924 iaxs[x]->remote_rr.losspct, 04925 iaxs[x]->remote_rr.dropped, 04926 iaxs[x]->remote_rr.ooo, 04927 iaxs[x]->remote_rr.packets/1000 04928 ); 04929 numchans++; 04930 } 04931 ast_mutex_unlock(&iaxsl[x]); 04932 } 04933 return numchans; 04934 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 3738 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().
03739 { 03740 struct ast_channel *tmp; 03741 struct chan_iax2_pvt *i; 03742 struct ast_variable *v = NULL; 03743 03744 if (!(i = iaxs[callno])) { 03745 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03746 return NULL; 03747 } 03748 03749 /* Don't hold call lock */ 03750 ast_mutex_unlock(&iaxsl[callno]); 03751 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); 03752 ast_mutex_lock(&iaxsl[callno]); 03753 if (!iaxs[callno]) { 03754 if (tmp) { 03755 ast_channel_free(tmp); 03756 } 03757 ast_mutex_unlock(&iaxsl[callno]); 03758 return NULL; 03759 } 03760 03761 if (!tmp) 03762 return NULL; 03763 tmp->tech = &iax2_tech; 03764 /* We can support any format by default, until we get restricted */ 03765 tmp->nativeformats = capability; 03766 tmp->readformat = ast_best_codec(capability); 03767 tmp->writeformat = ast_best_codec(capability); 03768 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03769 03770 /* Don't use ast_set_callerid() here because it will 03771 * generate a NewCallerID event before the NewChannel event */ 03772 if (!ast_strlen_zero(i->ani)) 03773 tmp->cid.cid_ani = ast_strdup(i->ani); 03774 else 03775 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03776 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03777 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03778 tmp->cid.cid_pres = i->calling_pres; 03779 tmp->cid.cid_ton = i->calling_ton; 03780 tmp->cid.cid_tns = i->calling_tns; 03781 if (!ast_strlen_zero(i->language)) 03782 ast_string_field_set(tmp, language, i->language); 03783 if (!ast_strlen_zero(i->accountcode)) 03784 ast_string_field_set(tmp, accountcode, i->accountcode); 03785 if (i->amaflags) 03786 tmp->amaflags = i->amaflags; 03787 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03788 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03789 if (i->adsi) 03790 tmp->adsicpe = i->peeradsicpe; 03791 else 03792 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03793 i->owner = tmp; 03794 i->capability = capability; 03795 03796 for (v = i->vars ; v ; v = v->next) 03797 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03798 03799 if (state != AST_STATE_DOWN) { 03800 if (ast_pbx_start(tmp)) { 03801 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03802 ast_hangup(tmp); 03803 i->owner = NULL; 03804 return NULL; 03805 } 03806 } 03807 03808 ast_module_ref(ast_module_info->self); 03809 03810 return tmp; 03811 }
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 2231 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02232 { 02233 #ifdef SCHED_MULTITHREADED 02234 if (schedule_action(__attempt_transmit, data)) 02235 #endif 02236 __attempt_transmit(data); 02237 return 0; 02238 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6439 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), and iaxs.
Referenced by socket_process().
06440 { 06441 /* Schedule sending the authentication failure in one second, to prevent 06442 guessing */ 06443 if (iaxs[callno]) { 06444 iaxs[callno]->authfail = failcode; 06445 if (delayreject) { 06446 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06447 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06448 } else 06449 auth_reject((void *)(long)callno); 06450 } 06451 return 0; 06452 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6425 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06426 { 06427 int callno = (int)(long)(data); 06428 ast_mutex_lock(&iaxsl[callno]); 06429 if (iaxs[callno]) 06430 iaxs[callno]->authid = -1; 06431 ast_mutex_unlock(&iaxsl[callno]); 06432 #ifdef SCHED_MULTITHREADED 06433 if (schedule_action(__auth_reject, data)) 06434 #endif 06435 __auth_reject(data); 06436 return 0; 06437 }
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 5646 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, MD5Final(), MD5Init(), and MD5Update().
05647 { 05648 int res = -1; 05649 int x; 05650 if (!ast_strlen_zero(keyn)) { 05651 if (!(authmethods & IAX_AUTH_RSA)) { 05652 if (ast_strlen_zero(secret)) 05653 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)); 05654 } else if (ast_strlen_zero(challenge)) { 05655 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05656 } else { 05657 char sig[256]; 05658 struct ast_key *key; 05659 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05660 if (!key) { 05661 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05662 } else { 05663 if (ast_sign(key, (char*)challenge, sig)) { 05664 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05665 res = -1; 05666 } else { 05667 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05668 res = 0; 05669 } 05670 } 05671 } 05672 } 05673 /* Fall back */ 05674 if (res && !ast_strlen_zero(secret)) { 05675 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05676 struct MD5Context md5; 05677 unsigned char digest[16]; 05678 char digres[128]; 05679 MD5Init(&md5); 05680 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05681 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05682 MD5Final(digest, &md5); 05683 /* If they support md5, authenticate with it. */ 05684 for (x=0;x<16;x++) 05685 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05686 if (ecx && dcx) 05687 build_enc_keys(digest, ecx, dcx); 05688 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05689 res = 0; 05690 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05691 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05692 res = 0; 05693 } else 05694 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05695 } 05696 return res; 05697 }
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 5703 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(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, iax2_registry::callno, iax_ies::challenge, chan_iax2_pvt::dcx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, iax2_peer::mask, merge_encryption(), peer_unref(), peers, iax_ie_data::pos, realtime_peer(), send_command(), and iax_ies::username.
Referenced by socket_process().
05704 { 05705 struct iax2_peer *peer = NULL; 05706 /* Start pessimistic */ 05707 int res = -1; 05708 int authmethods = 0; 05709 struct iax_ie_data ied; 05710 uint16_t callno = p->callno; 05711 05712 memset(&ied, 0, sizeof(ied)); 05713 05714 if (ies->username) 05715 ast_string_field_set(p, username, ies->username); 05716 if (ies->challenge) 05717 ast_string_field_set(p, challenge, ies->challenge); 05718 if (ies->authmethods) 05719 authmethods = ies->authmethods; 05720 if (authmethods & IAX_AUTH_MD5) 05721 merge_encryption(p, ies->encmethods); 05722 else 05723 p->encmethods = 0; 05724 05725 /* Check for override RSA authentication first */ 05726 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05727 /* Normal password authentication */ 05728 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05729 } else { 05730 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05731 while ((peer = ao2_iterator_next(&i))) { 05732 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05733 /* No peer specified at our end, or this is the peer */ 05734 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05735 /* No username specified in peer rule, or this is the right username */ 05736 && (!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))) 05737 /* No specified host, or this is our host */ 05738 ) { 05739 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05740 if (!res) { 05741 peer_unref(peer); 05742 break; 05743 } 05744 } 05745 peer_unref(peer); 05746 } 05747 if (!peer) { 05748 /* We checked our list and didn't find one. It's unlikely, but possible, 05749 that we're trying to authenticate *to* a realtime peer */ 05750 const char *peer_name = ast_strdupa(p->peer); 05751 ast_mutex_unlock(&iaxsl[callno]); 05752 if ((peer = realtime_peer(peer_name, NULL))) { 05753 ast_mutex_lock(&iaxsl[callno]); 05754 if (!(p = iaxs[callno])) { 05755 peer_unref(peer); 05756 return -1; 05757 } 05758 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05759 peer_unref(peer); 05760 } 05761 if (!peer) { 05762 ast_mutex_lock(&iaxsl[callno]); 05763 if (!(p = iaxs[callno])) 05764 return -1; 05765 } 05766 } 05767 } 05768 if (ies->encmethods) 05769 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05770 if (!res) 05771 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05772 return res; 05773 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5358 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, iax_ie_data::buf, 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, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and users.
Referenced by socket_process().
05359 { 05360 struct iax_ie_data ied; 05361 int res = -1, authreq_restrict = 0; 05362 char challenge[10]; 05363 struct chan_iax2_pvt *p = iaxs[call_num]; 05364 05365 memset(&ied, 0, sizeof(ied)); 05366 05367 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05368 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05369 struct iax2_user *user, tmp_user = { 05370 .name = p->username, 05371 }; 05372 05373 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05374 if (user) { 05375 if (user->curauthreq == user->maxauthreq) 05376 authreq_restrict = 1; 05377 else 05378 user->curauthreq++; 05379 user = user_unref(user); 05380 } 05381 } 05382 05383 /* If the AUTHREQ limit test failed, send back an error */ 05384 if (authreq_restrict) { 05385 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05386 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05387 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05388 return 0; 05389 } 05390 05391 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05392 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05393 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05394 ast_string_field_set(p, challenge, challenge); 05395 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05396 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05397 } 05398 if (p->encmethods) 05399 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05400 05401 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05402 05403 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05404 05405 if (p->encmethods) 05406 ast_set_flag(p, IAX_ENCRYPTED); 05407 05408 return res; 05409 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5411 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, chan_iax2_pvt::authrej, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, iax_ies::rsa_result, iax2_registry::secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05412 { 05413 char requeststr[256]; 05414 char md5secret[256] = ""; 05415 char secret[256] = ""; 05416 char rsasecret[256] = ""; 05417 int res = -1; 05418 int x; 05419 struct iax2_user *user, tmp_user = { 05420 .name = p->username, 05421 }; 05422 05423 if (p->authrej) { 05424 return res; 05425 } 05426 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05427 if (user) { 05428 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05429 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05430 ast_clear_flag(p, IAX_MAXAUTHREQ); 05431 } 05432 ast_string_field_set(p, host, user->name); 05433 user = user_unref(user); 05434 } 05435 05436 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05437 return res; 05438 if (ies->password) 05439 ast_copy_string(secret, ies->password, sizeof(secret)); 05440 if (ies->md5_result) 05441 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05442 if (ies->rsa_result) 05443 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05444 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05445 struct ast_key *key; 05446 char *keyn; 05447 char tmpkey[256]; 05448 char *stringp=NULL; 05449 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05450 stringp=tmpkey; 05451 keyn = strsep(&stringp, ":"); 05452 while(keyn) { 05453 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05454 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05455 res = 0; 05456 break; 05457 } else if (!key) 05458 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05459 keyn = strsep(&stringp, ":"); 05460 } 05461 } else if (p->authmethods & IAX_AUTH_MD5) { 05462 struct MD5Context md5; 05463 unsigned char digest[16]; 05464 char *tmppw, *stringp; 05465 05466 tmppw = ast_strdupa(p->secret); 05467 stringp = tmppw; 05468 while((tmppw = strsep(&stringp, ";"))) { 05469 MD5Init(&md5); 05470 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05471 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05472 MD5Final(digest, &md5); 05473 /* If they support md5, authenticate with it. */ 05474 for (x=0;x<16;x++) 05475 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05476 if (!strcasecmp(requeststr, md5secret)) { 05477 res = 0; 05478 break; 05479 } 05480 } 05481 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05482 if (!strcmp(secret, p->secret)) 05483 res = 0; 05484 } 05485 return res; 05486 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3118 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03119 { 03120 #ifdef SCHED_MULTITHREADED 03121 if (schedule_action(__auto_congest, data)) 03122 #endif 03123 __auto_congest(data); 03124 return 0; 03125 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6469 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06470 { 06471 int callno = (int)(long)(data); 06472 ast_mutex_lock(&iaxsl[callno]); 06473 if (iaxs[callno]) { 06474 iaxs[callno]->autoid = -1; 06475 } 06476 ast_mutex_unlock(&iaxsl[callno]); 06477 #ifdef SCHED_MULTITHREADED 06478 if (schedule_action(__auto_hangup, data)) 06479 #endif 06480 __auto_hangup(data); 06481 return 0; 06482 }
static struct iax2_context* build_context | ( | char * | context | ) | [static, read] |
Definition at line 9209 of file chan_iax2.c.
References ast_calloc, and iax2_context::context.
Referenced by build_user().
09210 { 09211 struct iax2_context *con; 09212 09213 if ((con = ast_calloc(1, sizeof(*con)))) 09214 ast_copy_string(con->context, context, sizeof(con->context)); 09215 09216 return con; 09217 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4118 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04119 { 04120 aes_encrypt_key128(digest, ecx); 04121 aes_decrypt_key128(digest, dcx); 04122 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create peer structure based on configuration.
Definition at line 9355 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, 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(), iax2_peer::authmethods, iax2_peer::capability, cid_name, cid_num, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), 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, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, iax2_registry::secret, iax2_peer::smoothing, iax2_peer::sockfd, unlink_peer(), and ast_variable::value.
09356 { 09357 struct iax2_peer *peer = NULL; 09358 struct ast_ha *oldha = NULL; 09359 int maskfound=0; 09360 int found=0; 09361 int firstpass=1; 09362 struct iax2_peer tmp_peer = { 09363 .name = name, 09364 }; 09365 09366 if (!temponly) { 09367 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09368 if (peer && !ast_test_flag(peer, IAX_DELME)) 09369 firstpass = 0; 09370 } 09371 09372 if (peer) { 09373 found++; 09374 if (firstpass) { 09375 oldha = peer->ha; 09376 peer->ha = NULL; 09377 } 09378 unlink_peer(peer); 09379 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09380 peer->expire = -1; 09381 peer->pokeexpire = -1; 09382 peer->sockfd = defaultsockfd; 09383 if (ast_string_field_init(peer, 32)) 09384 peer = peer_unref(peer); 09385 } 09386 09387 if (peer) { 09388 if (firstpass) { 09389 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09390 peer->encmethods = iax2_encryption; 09391 peer->adsi = adsi; 09392 ast_string_field_set(peer,secret,""); 09393 if (!found) { 09394 ast_string_field_set(peer, name, name); 09395 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09396 peer->expiry = min_reg_expire; 09397 } 09398 peer->prefs = prefs; 09399 peer->capability = iax2_capability; 09400 peer->smoothing = 0; 09401 peer->pokefreqok = DEFAULT_FREQ_OK; 09402 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09403 ast_string_field_set(peer,context,""); 09404 ast_string_field_set(peer,peercontext,""); 09405 ast_clear_flag(peer, IAX_HASCALLERID); 09406 ast_string_field_set(peer, cid_name, ""); 09407 ast_string_field_set(peer, cid_num, ""); 09408 } 09409 09410 if (!v) { 09411 v = alt; 09412 alt = NULL; 09413 } 09414 while(v) { 09415 if (!strcasecmp(v->name, "secret")) { 09416 ast_string_field_set(peer, secret, v->value); 09417 } else if (!strcasecmp(v->name, "mailbox")) { 09418 ast_string_field_set(peer, mailbox, v->value); 09419 } else if (!strcasecmp(v->name, "mohinterpret")) { 09420 ast_string_field_set(peer, mohinterpret, v->value); 09421 } else if (!strcasecmp(v->name, "mohsuggest")) { 09422 ast_string_field_set(peer, mohsuggest, v->value); 09423 } else if (!strcasecmp(v->name, "dbsecret")) { 09424 ast_string_field_set(peer, dbsecret, v->value); 09425 } else if (!strcasecmp(v->name, "trunk")) { 09426 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09427 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09428 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09429 ast_clear_flag(peer, IAX_TRUNK); 09430 } 09431 } else if (!strcasecmp(v->name, "auth")) { 09432 peer->authmethods = get_auth_methods(v->value); 09433 } else if (!strcasecmp(v->name, "encryption")) { 09434 peer->encmethods = get_encrypt_methods(v->value); 09435 } else if (!strcasecmp(v->name, "notransfer")) { 09436 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09437 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09438 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09439 } else if (!strcasecmp(v->name, "transfer")) { 09440 if (!strcasecmp(v->value, "mediaonly")) { 09441 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09442 } else if (ast_true(v->value)) { 09443 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09444 } else 09445 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09446 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09447 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09448 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09449 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09450 } else if (!strcasecmp(v->name, "host")) { 09451 if (!strcasecmp(v->value, "dynamic")) { 09452 /* They'll register with us */ 09453 ast_set_flag(peer, IAX_DYNAMIC); 09454 if (!found) { 09455 /* Initialize stuff iff we're not found, otherwise 09456 we keep going with what we had */ 09457 memset(&peer->addr.sin_addr, 0, 4); 09458 if (peer->addr.sin_port) { 09459 /* If we've already got a port, make it the default rather than absolute */ 09460 peer->defaddr.sin_port = peer->addr.sin_port; 09461 peer->addr.sin_port = 0; 09462 } 09463 } 09464 } else { 09465 /* Non-dynamic. Make sure we become that way if we're not */ 09466 AST_SCHED_DEL(sched, peer->expire); 09467 ast_clear_flag(peer, IAX_DYNAMIC); 09468 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09469 return peer_unref(peer); 09470 if (!peer->addr.sin_port) 09471 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09472 } 09473 if (!maskfound) 09474 inet_aton("255.255.255.255", &peer->mask); 09475 } else if (!strcasecmp(v->name, "defaultip")) { 09476 if (ast_get_ip(&peer->defaddr, v->value)) 09477 return peer_unref(peer); 09478 } else if (!strcasecmp(v->name, "sourceaddress")) { 09479 peer_set_srcaddr(peer, v->value); 09480 } else if (!strcasecmp(v->name, "permit") || 09481 !strcasecmp(v->name, "deny")) { 09482 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09483 } else if (!strcasecmp(v->name, "mask")) { 09484 maskfound++; 09485 inet_aton(v->value, &peer->mask); 09486 } else if (!strcasecmp(v->name, "context")) { 09487 ast_string_field_set(peer, context, v->value); 09488 } else if (!strcasecmp(v->name, "regexten")) { 09489 ast_string_field_set(peer, regexten, v->value); 09490 } else if (!strcasecmp(v->name, "peercontext")) { 09491 ast_string_field_set(peer, peercontext, v->value); 09492 } else if (!strcasecmp(v->name, "port")) { 09493 if (ast_test_flag(peer, IAX_DYNAMIC)) 09494 peer->defaddr.sin_port = htons(atoi(v->value)); 09495 else 09496 peer->addr.sin_port = htons(atoi(v->value)); 09497 } else if (!strcasecmp(v->name, "username")) { 09498 ast_string_field_set(peer, username, v->value); 09499 } else if (!strcasecmp(v->name, "allow")) { 09500 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09501 } else if (!strcasecmp(v->name, "disallow")) { 09502 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09503 } else if (!strcasecmp(v->name, "callerid")) { 09504 if (!ast_strlen_zero(v->value)) { 09505 char name2[80]; 09506 char num2[80]; 09507 ast_callerid_split(v->value, name2, 80, num2, 80); 09508 ast_string_field_set(peer, cid_name, name2); 09509 ast_string_field_set(peer, cid_num, num2); 09510 ast_set_flag(peer, IAX_HASCALLERID); 09511 } else { 09512 ast_clear_flag(peer, IAX_HASCALLERID); 09513 ast_string_field_set(peer, cid_name, ""); 09514 ast_string_field_set(peer, cid_num, ""); 09515 } 09516 } else if (!strcasecmp(v->name, "fullname")) { 09517 if (!ast_strlen_zero(v->value)) { 09518 ast_string_field_set(peer, cid_name, v->value); 09519 ast_set_flag(peer, IAX_HASCALLERID); 09520 } else { 09521 ast_string_field_set(peer, cid_name, ""); 09522 if (ast_strlen_zero(peer->cid_num)) 09523 ast_clear_flag(peer, IAX_HASCALLERID); 09524 } 09525 } else if (!strcasecmp(v->name, "cid_number")) { 09526 if (!ast_strlen_zero(v->value)) { 09527 ast_string_field_set(peer, cid_num, v->value); 09528 ast_set_flag(peer, IAX_HASCALLERID); 09529 } else { 09530 ast_string_field_set(peer, cid_num, ""); 09531 if (ast_strlen_zero(peer->cid_name)) 09532 ast_clear_flag(peer, IAX_HASCALLERID); 09533 } 09534 } else if (!strcasecmp(v->name, "sendani")) { 09535 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09536 } else if (!strcasecmp(v->name, "inkeys")) { 09537 ast_string_field_set(peer, inkeys, v->value); 09538 } else if (!strcasecmp(v->name, "outkey")) { 09539 ast_string_field_set(peer, outkey, v->value); 09540 } else if (!strcasecmp(v->name, "qualify")) { 09541 if (!strcasecmp(v->value, "no")) { 09542 peer->maxms = 0; 09543 } else if (!strcasecmp(v->value, "yes")) { 09544 peer->maxms = DEFAULT_MAXMS; 09545 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09546 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); 09547 peer->maxms = 0; 09548 } 09549 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09550 peer->smoothing = ast_true(v->value); 09551 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09552 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09553 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); 09554 } 09555 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09556 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09557 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); 09558 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09559 } else if (!strcasecmp(v->name, "timezone")) { 09560 ast_string_field_set(peer, zonetag, v->value); 09561 } else if (!strcasecmp(v->name, "adsi")) { 09562 peer->adsi = ast_true(v->value); 09563 }/* else if (strcasecmp(v->name,"type")) */ 09564 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09565 v = v->next; 09566 if (!v) { 09567 v = alt; 09568 alt = NULL; 09569 } 09570 } 09571 if (!peer->authmethods) 09572 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09573 ast_clear_flag(peer, IAX_DELME); 09574 /* Make sure these are IPv4 addresses */ 09575 peer->addr.sin_family = AF_INET; 09576 } 09577 if (oldha) 09578 ast_free_ha(oldha); 09579 return peer; 09580 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 9596 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(), 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_context::next, prefs, iax2_user::prefs, iax2_registry::secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09597 { 09598 struct iax2_user *user = NULL; 09599 struct iax2_context *con, *conl = NULL; 09600 struct ast_ha *oldha = NULL; 09601 struct iax2_context *oldcon = NULL; 09602 int format; 09603 int firstpass=1; 09604 int oldcurauthreq = 0; 09605 char *varname = NULL, *varval = NULL; 09606 struct ast_variable *tmpvar = NULL; 09607 struct iax2_user tmp_user = { 09608 .name = name, 09609 }; 09610 09611 if (!temponly) { 09612 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09613 if (user && !ast_test_flag(user, IAX_DELME)) 09614 firstpass = 0; 09615 } 09616 09617 if (user) { 09618 if (firstpass) { 09619 oldcurauthreq = user->curauthreq; 09620 oldha = user->ha; 09621 oldcon = user->contexts; 09622 user->ha = NULL; 09623 user->contexts = NULL; 09624 } 09625 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09626 ao2_unlink(users, user); 09627 } else { 09628 user = ao2_alloc(sizeof(*user), user_destructor); 09629 } 09630 09631 if (user) { 09632 if (firstpass) { 09633 ast_string_field_free_memory(user); 09634 memset(user, 0, sizeof(struct iax2_user)); 09635 if (ast_string_field_init(user, 32)) { 09636 user = user_unref(user); 09637 goto cleanup; 09638 } 09639 user->maxauthreq = maxauthreq; 09640 user->curauthreq = oldcurauthreq; 09641 user->prefs = prefs; 09642 user->capability = iax2_capability; 09643 user->encmethods = iax2_encryption; 09644 user->adsi = adsi; 09645 ast_string_field_set(user, name, name); 09646 ast_string_field_set(user, language, language); 09647 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09648 ast_clear_flag(user, IAX_HASCALLERID); 09649 ast_string_field_set(user, cid_name, ""); 09650 ast_string_field_set(user, cid_num, ""); 09651 } 09652 if (!v) { 09653 v = alt; 09654 alt = NULL; 09655 } 09656 while(v) { 09657 if (!strcasecmp(v->name, "context")) { 09658 con = build_context(v->value); 09659 if (con) { 09660 if (conl) 09661 conl->next = con; 09662 else 09663 user->contexts = con; 09664 conl = con; 09665 } 09666 } else if (!strcasecmp(v->name, "permit") || 09667 !strcasecmp(v->name, "deny")) { 09668 user->ha = ast_append_ha(v->name, v->value, user->ha); 09669 } else if (!strcasecmp(v->name, "setvar")) { 09670 varname = ast_strdupa(v->value); 09671 if (varname && (varval = strchr(varname,'='))) { 09672 *varval = '\0'; 09673 varval++; 09674 if((tmpvar = ast_variable_new(varname, varval))) { 09675 tmpvar->next = user->vars; 09676 user->vars = tmpvar; 09677 } 09678 } 09679 } else if (!strcasecmp(v->name, "allow")) { 09680 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09681 } else if (!strcasecmp(v->name, "disallow")) { 09682 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09683 } else if (!strcasecmp(v->name, "trunk")) { 09684 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09685 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09686 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09687 ast_clear_flag(user, IAX_TRUNK); 09688 } 09689 } else if (!strcasecmp(v->name, "auth")) { 09690 user->authmethods = get_auth_methods(v->value); 09691 } else if (!strcasecmp(v->name, "encryption")) { 09692 user->encmethods = get_encrypt_methods(v->value); 09693 } else if (!strcasecmp(v->name, "notransfer")) { 09694 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09695 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09696 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09697 } else if (!strcasecmp(v->name, "transfer")) { 09698 if (!strcasecmp(v->value, "mediaonly")) { 09699 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09700 } else if (ast_true(v->value)) { 09701 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09702 } else 09703 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09704 } else if (!strcasecmp(v->name, "codecpriority")) { 09705 if(!strcasecmp(v->value, "caller")) 09706 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09707 else if(!strcasecmp(v->value, "disabled")) 09708 ast_set_flag(user, IAX_CODEC_NOPREFS); 09709 else if(!strcasecmp(v->value, "reqonly")) { 09710 ast_set_flag(user, IAX_CODEC_NOCAP); 09711 ast_set_flag(user, IAX_CODEC_NOPREFS); 09712 } 09713 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09714 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09715 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09716 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09717 } else if (!strcasecmp(v->name, "dbsecret")) { 09718 ast_string_field_set(user, dbsecret, v->value); 09719 } else if (!strcasecmp(v->name, "secret")) { 09720 if (!ast_strlen_zero(user->secret)) { 09721 char *old = ast_strdupa(user->secret); 09722 09723 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09724 } else 09725 ast_string_field_set(user, secret, v->value); 09726 } else if (!strcasecmp(v->name, "callerid")) { 09727 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09728 char name2[80]; 09729 char num2[80]; 09730 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09731 ast_string_field_set(user, cid_name, name2); 09732 ast_string_field_set(user, cid_num, num2); 09733 ast_set_flag(user, IAX_HASCALLERID); 09734 } else { 09735 ast_clear_flag(user, IAX_HASCALLERID); 09736 ast_string_field_set(user, cid_name, ""); 09737 ast_string_field_set(user, cid_num, ""); 09738 } 09739 } else if (!strcasecmp(v->name, "fullname")) { 09740 if (!ast_strlen_zero(v->value)) { 09741 ast_string_field_set(user, cid_name, v->value); 09742 ast_set_flag(user, IAX_HASCALLERID); 09743 } else { 09744 ast_string_field_set(user, cid_name, ""); 09745 if (ast_strlen_zero(user->cid_num)) 09746 ast_clear_flag(user, IAX_HASCALLERID); 09747 } 09748 } else if (!strcasecmp(v->name, "cid_number")) { 09749 if (!ast_strlen_zero(v->value)) { 09750 ast_string_field_set(user, cid_num, v->value); 09751 ast_set_flag(user, IAX_HASCALLERID); 09752 } else { 09753 ast_string_field_set(user, cid_num, ""); 09754 if (ast_strlen_zero(user->cid_name)) 09755 ast_clear_flag(user, IAX_HASCALLERID); 09756 } 09757 } else if (!strcasecmp(v->name, "accountcode")) { 09758 ast_string_field_set(user, accountcode, v->value); 09759 } else if (!strcasecmp(v->name, "mohinterpret")) { 09760 ast_string_field_set(user, mohinterpret, v->value); 09761 } else if (!strcasecmp(v->name, "mohsuggest")) { 09762 ast_string_field_set(user, mohsuggest, v->value); 09763 } else if (!strcasecmp(v->name, "language")) { 09764 ast_string_field_set(user, language, v->value); 09765 } else if (!strcasecmp(v->name, "amaflags")) { 09766 format = ast_cdr_amaflags2int(v->value); 09767 if (format < 0) { 09768 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09769 } else { 09770 user->amaflags = format; 09771 } 09772 } else if (!strcasecmp(v->name, "inkeys")) { 09773 ast_string_field_set(user, inkeys, v->value); 09774 } else if (!strcasecmp(v->name, "maxauthreq")) { 09775 user->maxauthreq = atoi(v->value); 09776 if (user->maxauthreq < 0) 09777 user->maxauthreq = 0; 09778 } else if (!strcasecmp(v->name, "adsi")) { 09779 user->adsi = ast_true(v->value); 09780 }/* else if (strcasecmp(v->name,"type")) */ 09781 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09782 v = v->next; 09783 if (!v) { 09784 v = alt; 09785 alt = NULL; 09786 } 09787 } 09788 if (!user->authmethods) { 09789 if (!ast_strlen_zero(user->secret)) { 09790 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09791 if (!ast_strlen_zero(user->inkeys)) 09792 user->authmethods |= IAX_AUTH_RSA; 09793 } else if (!ast_strlen_zero(user->inkeys)) { 09794 user->authmethods = IAX_AUTH_RSA; 09795 } else { 09796 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09797 } 09798 } 09799 ast_clear_flag(user, IAX_DELME); 09800 } 09801 cleanup: 09802 if (oldha) 09803 ast_free_ha(oldha); 09804 if (oldcon) 09805 free_context(oldcon); 09806 return user; 09807 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10312 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(), iax_ie_data::buf, iax2_registry::callno, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, 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, parsed_dial_string::key, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, iax2_registry::secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
10313 { 10314 struct sockaddr_in sin; 10315 int x; 10316 int callno; 10317 struct iax_ie_data ied; 10318 struct create_addr_info cai; 10319 struct parsed_dial_string pds; 10320 char *tmpstr; 10321 10322 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10323 /* Look for an *exact match* call. Once a call is negotiated, it can only 10324 look up entries for a single context */ 10325 if (!ast_mutex_trylock(&iaxsl[x])) { 10326 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10327 return x; 10328 ast_mutex_unlock(&iaxsl[x]); 10329 } 10330 } 10331 10332 /* No match found, we need to create a new one */ 10333 10334 memset(&cai, 0, sizeof(cai)); 10335 memset(&ied, 0, sizeof(ied)); 10336 memset(&pds, 0, sizeof(pds)); 10337 10338 tmpstr = ast_strdupa(data); 10339 parse_dial_string(tmpstr, &pds); 10340 10341 if (ast_strlen_zero(pds.peer)) { 10342 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10343 return -1; 10344 } 10345 10346 /* Populate our address from the given */ 10347 if (create_addr(pds.peer, NULL, &sin, &cai)) 10348 return -1; 10349 10350 if (option_debug) 10351 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10352 pds.peer, pds.username, pds.password, pds.context); 10353 10354 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10355 if (callno < 1) { 10356 ast_log(LOG_WARNING, "Unable to create call\n"); 10357 return -1; 10358 } 10359 10360 ast_string_field_set(iaxs[callno], dproot, data); 10361 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10362 10363 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10364 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10365 /* the string format is slightly different from a standard dial string, 10366 because the context appears in the 'exten' position 10367 */ 10368 if (pds.exten) 10369 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10370 if (pds.username) 10371 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10372 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10373 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10374 /* Keep password handy */ 10375 if (pds.password) 10376 ast_string_field_set(iaxs[callno], secret, pds.password); 10377 if (pds.key) 10378 ast_string_field_set(iaxs[callno], outkey, pds.key); 10379 /* Start the call going */ 10380 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10381 10382 return callno; 10383 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3986 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, LOG_DEBUG, option_debug, and chan_iax2_pvt::rxcore.
03987 { 03988 /* Returns where in "receive time" we are. That is, how many ms 03989 since we received (or would have received) the frame with timestamp 0 */ 03990 int ms; 03991 #ifdef IAXTESTS 03992 int jit; 03993 #endif /* IAXTESTS */ 03994 /* Setup rxcore if necessary */ 03995 if (ast_tvzero(p->rxcore)) { 03996 p->rxcore = ast_tvnow(); 03997 if (option_debug && iaxdebug) 03998 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03999 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 04000 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 04001 #if 1 04002 if (option_debug && iaxdebug) 04003 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 04004 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 04005 #endif 04006 } 04007 04008 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 04009 #ifdef IAXTESTS 04010 if (test_jit) { 04011 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04012 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04013 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04014 jit = -jit; 04015 ms += jit; 04016 } 04017 } 04018 if (test_late) { 04019 ms += test_late; 04020 test_late = 0; 04021 } 04022 #endif /* IAXTESTS */ 04023 return ms; 04024 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3857 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, ast_frame::delivery, ast_frame::frametype, iaxs, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples.
Referenced by iax2_send(), and socket_process().
03858 { 03859 int ms; 03860 int voice = 0; 03861 int genuine = 0; 03862 int adjust; 03863 struct timeval *delivery = NULL; 03864 03865 03866 /* What sort of frame do we have?: voice is self-explanatory 03867 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03868 non-genuine frames are CONTROL frames [ringing etc], DTMF 03869 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03870 the others need a timestamp slaved to the voice frames so that they go in sequence 03871 */ 03872 if (f) { 03873 if (f->frametype == AST_FRAME_VOICE) { 03874 voice = 1; 03875 delivery = &f->delivery; 03876 } else if (f->frametype == AST_FRAME_IAX) { 03877 genuine = 1; 03878 } else if (f->frametype == AST_FRAME_CNG) { 03879 p->notsilenttx = 0; 03880 } 03881 } 03882 if (ast_tvzero(p->offset)) { 03883 gettimeofday(&p->offset, NULL); 03884 /* Round to nearest 20ms for nice looking traces */ 03885 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03886 } 03887 /* If the timestamp is specified, just send it as is */ 03888 if (ts) 03889 return ts; 03890 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03891 if (delivery && !ast_tvzero(*delivery)) { 03892 ms = ast_tvdiff_ms(*delivery, p->offset); 03893 if (option_debug > 2 && iaxdebug) 03894 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03895 } else { 03896 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03897 if (ms < 0) 03898 ms = 0; 03899 if (voice) { 03900 /* On a voice frame, use predicted values if appropriate */ 03901 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03902 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03903 /* AN EXPLANATION: 03904 When we send voice, we usually send "calculated" timestamps worked out 03905 on the basis of the number of samples sent. When we send other frames, 03906 we usually send timestamps worked out from the real clock. 03907 The problem is that they can tend to drift out of step because the 03908 source channel's clock and our clock may not be exactly at the same rate. 03909 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03910 for this call. Moving it adjusts timestamps for non-voice frames. 03911 We make the adjustment in the style of a moving average. Each time we 03912 adjust p->offset by 10% of the difference between our clock-derived 03913 timestamp and the predicted timestamp. That's why you see "10000" 03914 below even though IAX2 timestamps are in milliseconds. 03915 The use of a moving average avoids offset moving too radically. 03916 Generally, "adjust" roams back and forth around 0, with offset hardly 03917 changing at all. But if a consistent different starts to develop it 03918 will be eliminated over the course of 10 frames (200-300msecs) 03919 */ 03920 adjust = (ms - p->nextpred); 03921 if (adjust < 0) 03922 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03923 else if (adjust > 0) 03924 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03925 03926 if (!p->nextpred) { 03927 p->nextpred = ms; /*f->samples / 8;*/ 03928 if (p->nextpred <= p->lastsent) 03929 p->nextpred = p->lastsent + 3; 03930 } 03931 ms = p->nextpred; 03932 } else { 03933 /* in this case, just use the actual 03934 * time, since we're either way off 03935 * (shouldn't happen), or we're ending a 03936 * silent period -- and seed the next 03937 * predicted time. Also, round ms to the 03938 * next multiple of frame size (so our 03939 * silent periods are multiples of 03940 * frame size too) */ 03941 03942 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03943 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03944 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03945 03946 if (f->samples >= 8) /* check to make sure we dont core dump */ 03947 { 03948 int diff = ms % (f->samples / 8); 03949 if (diff) 03950 ms += f->samples/8 - diff; 03951 } 03952 03953 p->nextpred = ms; 03954 p->notsilenttx = 1; 03955 } 03956 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03957 /* 03958 * IAX2 draft 03 says that timestamps MUST be in order. 03959 * It does not say anything about several frames having the same timestamp 03960 * When transporting video, we can have a frame that spans multiple iax packets 03961 * (so called slices), so it would make sense to use the same timestamp for all of 03962 * them 03963 * We do want to make sure that frames don't go backwards though 03964 */ 03965 if ( (unsigned int)ms < p->lastsent ) 03966 ms = p->lastsent; 03967 } else { 03968 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03969 it's a genuine frame */ 03970 if (genuine) { 03971 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03972 if (ms <= p->lastsent) 03973 ms = p->lastsent + 3; 03974 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03975 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03976 ms = p->lastsent + 3; 03977 } 03978 } 03979 } 03980 p->lastsent = ms; 03981 if (voice) 03982 p->nextpred = p->nextpred + f->samples / 8; 03983 return ms; 03984 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3813 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().
03814 { 03815 unsigned long int mssincetx; /* unsigned to handle overflows */ 03816 long int ms, pred; 03817 03818 tpeer->trunkact = *tv; 03819 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03820 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03821 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03822 tpeer->txtrunktime = *tv; 03823 tpeer->lastsent = 999999; 03824 } 03825 /* Update last transmit time now */ 03826 tpeer->lasttxtime = *tv; 03827 03828 /* Calculate ms offset */ 03829 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03830 /* Predict from last value */ 03831 pred = tpeer->lastsent + sampms; 03832 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03833 ms = pred; 03834 03835 /* We never send the same timestamp twice, so fudge a little if we must */ 03836 if (ms == tpeer->lastsent) 03837 ms = tpeer->lastsent + 1; 03838 tpeer->lastsent = ms; 03839 return ms; 03840 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5097 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, iax2_context::context, iax2_user::contexts, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, 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, iax_ies::rdnis, realtime_user(), iax2_registry::secret, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version.
Referenced by socket_process().
05098 { 05099 /* Start pessimistic */ 05100 int res = -1; 05101 int version = 2; 05102 struct iax2_user *user = NULL, *best = NULL; 05103 int bestscore = 0; 05104 int gotcapability = 0; 05105 struct ast_variable *v = NULL, *tmpvar = NULL; 05106 struct ao2_iterator i; 05107 05108 if (!iaxs[callno]) 05109 return res; 05110 if (ies->called_number) 05111 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05112 if (ies->calling_number) { 05113 ast_shrink_phone_number(ies->calling_number); 05114 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05115 } 05116 if (ies->calling_name) 05117 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05118 if (ies->calling_ani) 05119 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05120 if (ies->dnid) 05121 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05122 if (ies->rdnis) 05123 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05124 if (ies->called_context) 05125 ast_string_field_set(iaxs[callno], context, ies->called_context); 05126 if (ies->language) 05127 ast_string_field_set(iaxs[callno], language, ies->language); 05128 if (ies->username) 05129 ast_string_field_set(iaxs[callno], username, ies->username); 05130 if (ies->calling_ton > -1) 05131 iaxs[callno]->calling_ton = ies->calling_ton; 05132 if (ies->calling_tns > -1) 05133 iaxs[callno]->calling_tns = ies->calling_tns; 05134 if (ies->calling_pres > -1) 05135 iaxs[callno]->calling_pres = ies->calling_pres; 05136 if (ies->format) 05137 iaxs[callno]->peerformat = ies->format; 05138 if (ies->adsicpe) 05139 iaxs[callno]->peeradsicpe = ies->adsicpe; 05140 if (ies->capability) { 05141 gotcapability = 1; 05142 iaxs[callno]->peercapability = ies->capability; 05143 } 05144 if (ies->version) 05145 version = ies->version; 05146 05147 /* Use provided preferences until told otherwise for actual preferences */ 05148 if(ies->codec_prefs) { 05149 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05150 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05151 } 05152 05153 if (!gotcapability) 05154 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05155 if (version > IAX_PROTO_VERSION) { 05156 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05157 ast_inet_ntoa(sin->sin_addr), version); 05158 return res; 05159 } 05160 /* Search the userlist for a compatible entry, and fill in the rest */ 05161 i = ao2_iterator_init(users, 0); 05162 while ((user = ao2_iterator_next(&i))) { 05163 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05164 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05165 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05166 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05167 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05168 if (!ast_strlen_zero(iaxs[callno]->username)) { 05169 /* Exact match, stop right now. */ 05170 if (best) 05171 user_unref(best); 05172 best = user; 05173 break; 05174 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05175 /* No required authentication */ 05176 if (user->ha) { 05177 /* There was host authentication and we passed, bonus! */ 05178 if (bestscore < 4) { 05179 bestscore = 4; 05180 if (best) 05181 user_unref(best); 05182 best = user; 05183 continue; 05184 } 05185 } else { 05186 /* No host access, but no secret, either, not bad */ 05187 if (bestscore < 3) { 05188 bestscore = 3; 05189 if (best) 05190 user_unref(best); 05191 best = user; 05192 continue; 05193 } 05194 } 05195 } else { 05196 if (user->ha) { 05197 /* Authentication, but host access too, eh, it's something.. */ 05198 if (bestscore < 2) { 05199 bestscore = 2; 05200 if (best) 05201 user_unref(best); 05202 best = user; 05203 continue; 05204 } 05205 } else { 05206 /* Authentication and no host access... This is our baseline */ 05207 if (bestscore < 1) { 05208 bestscore = 1; 05209 if (best) 05210 user_unref(best); 05211 best = user; 05212 continue; 05213 } 05214 } 05215 } 05216 } 05217 user_unref(user); 05218 } 05219 user = best; 05220 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05221 user = realtime_user(iaxs[callno]->username, sin); 05222 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05223 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05224 user = user_unref(user); 05225 } 05226 } 05227 if (user) { 05228 /* We found our match (use the first) */ 05229 /* copy vars */ 05230 for (v = user->vars ; v ; v = v->next) { 05231 if((tmpvar = ast_variable_new(v->name, v->value))) { 05232 tmpvar->next = iaxs[callno]->vars; 05233 iaxs[callno]->vars = tmpvar; 05234 } 05235 } 05236 /* If a max AUTHREQ restriction is in place, activate it */ 05237 if (user->maxauthreq > 0) 05238 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05239 iaxs[callno]->prefs = user->prefs; 05240 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05241 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05242 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05243 iaxs[callno]->encmethods = user->encmethods; 05244 /* Store the requested username if not specified */ 05245 if (ast_strlen_zero(iaxs[callno]->username)) 05246 ast_string_field_set(iaxs[callno], username, user->name); 05247 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05248 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05249 iaxs[callno]->capability = user->capability; 05250 /* And use the default context */ 05251 if (ast_strlen_zero(iaxs[callno]->context)) { 05252 if (user->contexts) 05253 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05254 else 05255 ast_string_field_set(iaxs[callno], context, context); 05256 } 05257 /* And any input keys */ 05258 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05259 /* And the permitted authentication methods */ 05260 iaxs[callno]->authmethods = user->authmethods; 05261 iaxs[callno]->adsi = user->adsi; 05262 /* If they have callerid, override the given caller id. Always store the ANI */ 05263 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05264 if (ast_test_flag(user, IAX_HASCALLERID)) { 05265 iaxs[callno]->calling_tns = 0; 05266 iaxs[callno]->calling_ton = 0; 05267 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05268 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05269 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05270 } 05271 if (ast_strlen_zero(iaxs[callno]->ani)) 05272 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05273 } else { 05274 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05275 } 05276 if (!ast_strlen_zero(user->accountcode)) 05277 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05278 if (!ast_strlen_zero(user->mohinterpret)) 05279 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05280 if (!ast_strlen_zero(user->mohsuggest)) 05281 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05282 if (user->amaflags) 05283 iaxs[callno]->amaflags = user->amaflags; 05284 if (!ast_strlen_zero(user->language)) 05285 ast_string_field_set(iaxs[callno], language, user->language); 05286 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05287 /* Keep this check last */ 05288 if (!ast_strlen_zero(user->dbsecret)) { 05289 char *family, *key=NULL; 05290 char buf[80]; 05291 family = ast_strdupa(user->dbsecret); 05292 key = strchr(family, '/'); 05293 if (key) { 05294 *key = '\0'; 05295 key++; 05296 } 05297 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05298 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05299 else 05300 ast_string_field_set(iaxs[callno], secret, buf); 05301 } else 05302 ast_string_field_set(iaxs[callno], secret, user->secret); 05303 res = 0; 05304 user = user_unref(user); 05305 } else { 05306 /* user was not found, but we should still fake an AUTHREQ. 05307 * Set authmethods to the last known authmethod used by the system 05308 * Set a fake secret, it's not looked at, just required to attempt authentication. 05309 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 05310 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 05311 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05312 iaxs[callno]->authrej = 1; 05313 if (!ast_strlen_zero(iaxs[callno]->username)) { 05314 /* only send the AUTHREQ if a username was specified. */ 05315 res = 0; 05316 } 05317 } 05318 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05319 return res; 05320 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6827 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.
Referenced by socket_process().
06828 { 06829 unsigned int ourver; 06830 char rsi[80]; 06831 snprintf(rsi, sizeof(rsi), "si-%s", si); 06832 if (iax_provision_version(&ourver, rsi, 1)) 06833 return 0; 06834 if (option_debug) 06835 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06836 if (ourver != ver) 06837 iax2_provision(sin, sockfd, NULL, rsi, 1); 06838 return 0; 06839 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9235 of file chan_iax2.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09236 { 09237 int sd; 09238 int res; 09239 09240 sd = socket(AF_INET, SOCK_DGRAM, 0); 09241 if (sd < 0) { 09242 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09243 return -1; 09244 } 09245 09246 res = bind(sd, sa, salen); 09247 if (res < 0) { 09248 if (option_debug) 09249 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09250 close(sd); 09251 return 1; 09252 } 09253 09254 close(sd); 09255 return 0; 09256 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5822 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, iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, 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, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.
Referenced by socket_process().
05823 { 05824 char exten[256] = ""; 05825 int status = CACHE_FLAG_UNKNOWN; 05826 int expiry = iaxdefaultdpcache; 05827 int x; 05828 int matchmore = 0; 05829 struct iax2_dpcache *dp, *prev; 05830 05831 if (ies->called_number) 05832 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05833 05834 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05835 status = CACHE_FLAG_EXISTS; 05836 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05837 status = CACHE_FLAG_CANEXIST; 05838 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05839 status = CACHE_FLAG_NONEXISTENT; 05840 05841 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05842 /* Don't really do anything with this */ 05843 } 05844 if (ies->refresh) 05845 expiry = ies->refresh; 05846 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05847 matchmore = CACHE_FLAG_MATCHMORE; 05848 ast_mutex_lock(&dpcache_lock); 05849 prev = NULL; 05850 dp = pvt->dpentries; 05851 while(dp) { 05852 if (!strcmp(dp->exten, exten)) { 05853 /* Let them go */ 05854 if (prev) 05855 prev->peer = dp->peer; 05856 else 05857 pvt->dpentries = dp->peer; 05858 dp->peer = NULL; 05859 dp->callno = 0; 05860 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05861 if (dp->flags & CACHE_FLAG_PENDING) { 05862 dp->flags &= ~CACHE_FLAG_PENDING; 05863 dp->flags |= status; 05864 dp->flags |= matchmore; 05865 } 05866 /* Wake up waiters */ 05867 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05868 if (dp->waiters[x] > -1) 05869 write(dp->waiters[x], "asdf", 4); 05870 } 05871 prev = dp; 05872 dp = dp->peer; 05873 } 05874 ast_mutex_unlock(&dpcache_lock); 05875 return 0; 05876 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2393 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02394 { 02395 int which = 0; 02396 struct iax2_peer *peer; 02397 char *res = NULL; 02398 int wordlen = strlen(word); 02399 struct ao2_iterator i; 02400 02401 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02402 if (pos != 3) 02403 return NULL; 02404 02405 i = ao2_iterator_init(peers, 0); 02406 while ((peer = ao2_iterator_next(&i))) { 02407 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02408 res = ast_strdup(peer->name); 02409 peer_unref(peer); 02410 break; 02411 } 02412 peer_unref(peer); 02413 } 02414 02415 return res; 02416 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5878 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, 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().
05879 { 05880 int peercallno = 0; 05881 struct chan_iax2_pvt *pvt = iaxs[callno]; 05882 struct iax_frame *cur; 05883 jb_frame frame; 05884 05885 if (ies->callno) 05886 peercallno = ies->callno; 05887 05888 if (peercallno < 1) { 05889 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05890 return -1; 05891 } 05892 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05893 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05894 /* Reset sequence numbers */ 05895 pvt->oseqno = 0; 05896 pvt->rseqno = 0; 05897 pvt->iseqno = 0; 05898 pvt->aseqno = 0; 05899 05900 if (pvt->peercallno) { 05901 remove_by_peercallno(pvt); 05902 } 05903 pvt->peercallno = peercallno; 05904 store_by_peercallno(pvt); 05905 05906 pvt->transferring = TRANSFER_NONE; 05907 pvt->svoiceformat = -1; 05908 pvt->voiceformat = 0; 05909 pvt->svideoformat = -1; 05910 pvt->videoformat = 0; 05911 pvt->transfercallno = -1; 05912 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05913 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05914 /* reset jitterbuffer */ 05915 while(jb_getall(pvt->jb,&frame) == JB_OK) 05916 iax2_frame_free(frame.data); 05917 jb_reset(pvt->jb); 05918 pvt->lag = 0; 05919 pvt->last = 0; 05920 pvt->lastsent = 0; 05921 pvt->nextpred = 0; 05922 pvt->pingtime = DEFAULT_RETRY_TIME; 05923 AST_LIST_LOCK(&iaxq.queue); 05924 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05925 /* We must cancel any packets that would have been transmitted 05926 because now we're talking to someone new. It's okay, they 05927 were transmitted to someone that didn't care anyway. */ 05928 if (callno == cur->callno) 05929 cur->retries = -1; 05930 } 05931 AST_LIST_UNLOCK(&iaxq.queue); 05932 return 0; 05933 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1065 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01066 { 01067 int x; 01068 int power=-1; 01069 /* If it's 128 or smaller, just return it */ 01070 if (subclass < IAX_FLAG_SC_LOG) 01071 return subclass; 01072 /* Otherwise find its power */ 01073 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01074 if (subclass & (1 << x)) { 01075 if (power > -1) { 01076 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01077 return 0; 01078 } else 01079 power = x; 01080 } 01081 } 01082 return power | IAX_FLAG_SC_LOG; 01083 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6841 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().
06842 { 06843 jb_info stats; 06844 jb_getinfo(pvt->jb, &stats); 06845 06846 memset(iep, 0, sizeof(*iep)); 06847 06848 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06849 if(stats.frames_in == 0) stats.frames_in = 1; 06850 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06851 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06852 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06853 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06854 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06855 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3010 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_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_DEBUG, 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.
03011 { 03012 struct ast_hostent ahp; 03013 struct hostent *hp; 03014 struct iax2_peer *peer; 03015 int res = -1; 03016 struct ast_codec_pref ourprefs; 03017 03018 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03019 cai->sockfd = defaultsockfd; 03020 cai->maxtime = 0; 03021 sin->sin_family = AF_INET; 03022 03023 if (!(peer = find_peer(peername, 1))) { 03024 cai->found = 0; 03025 03026 hp = ast_gethostbyname(peername, &ahp); 03027 if (hp) { 03028 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03029 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03030 /* use global iax prefs for unknown peer/user */ 03031 /* But move the calling channel's native codec to the top of the preference list */ 03032 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03033 if (c) 03034 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03035 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03036 return 0; 03037 } else { 03038 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03039 return -1; 03040 } 03041 } 03042 03043 cai->found = 1; 03044 03045 /* if the peer has no address (current or default), return failure */ 03046 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03047 goto return_unref; 03048 03049 /* if the peer is being monitored and is currently unreachable, return failure */ 03050 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03051 goto return_unref; 03052 03053 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03054 cai->maxtime = peer->maxms; 03055 cai->capability = peer->capability; 03056 cai->encmethods = peer->encmethods; 03057 cai->sockfd = peer->sockfd; 03058 cai->adsi = peer->adsi; 03059 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03060 /* Move the calling channel's native codec to the top of the preference list */ 03061 if (c) { 03062 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03063 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03064 } 03065 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03066 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03067 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03068 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03069 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03070 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03071 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03072 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03073 if (ast_strlen_zero(peer->dbsecret)) { 03074 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03075 } else { 03076 char *family; 03077 char *key = NULL; 03078 03079 family = ast_strdupa(peer->dbsecret); 03080 key = strchr(family, '/'); 03081 if (key) 03082 *key++ = '\0'; 03083 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03084 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03085 goto return_unref; 03086 } 03087 } 03088 03089 if (peer->addr.sin_addr.s_addr) { 03090 sin->sin_addr = peer->addr.sin_addr; 03091 sin->sin_port = peer->addr.sin_port; 03092 } else { 03093 sin->sin_addr = peer->defaddr.sin_addr; 03094 sin->sin_port = peer->defaddr.sin_port; 03095 } 03096 03097 res = 0; 03098 03099 return_unref: 03100 peer_unref(peer); 03101 03102 return res; 03103 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4172 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, ast_frame::frametype, IAX_FLAG_FULL, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
04173 { 04174 int padding; 04175 unsigned char *workspace; 04176 04177 workspace = alloca(*datalen); 04178 memset(f, 0, sizeof(*f)); 04179 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04180 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04181 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04182 return -1; 04183 /* Decrypt */ 04184 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04185 04186 padding = 16 + (workspace[15] & 0xf); 04187 if (option_debug && iaxdebug) 04188 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04189 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04190 return -1; 04191 04192 *datalen -= padding; 04193 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04194 f->frametype = fh->type; 04195 if (f->frametype == AST_FRAME_VIDEO) { 04196 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04197 } else { 04198 f->subclass = uncompress_subclass(fh->csub); 04199 } 04200 } else { 04201 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04202 if (option_debug && iaxdebug) 04203 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04204 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04205 return -1; 04206 /* Decrypt */ 04207 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04208 padding = 16 + (workspace[15] & 0x0f); 04209 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04210 return -1; 04211 *datalen -= padding; 04212 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04213 } 04214 return 0; 04215 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4258 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), iax2_registry::secret, and strsep().
Referenced by socket_process().
04259 { 04260 int res=-1; 04261 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04262 /* Search for possible keys, given secrets */ 04263 struct MD5Context md5; 04264 unsigned char digest[16]; 04265 char *tmppw, *stringp; 04266 04267 tmppw = ast_strdupa(iaxs[callno]->secret); 04268 stringp = tmppw; 04269 while ((tmppw = strsep(&stringp, ";"))) { 04270 MD5Init(&md5); 04271 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04272 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04273 MD5Final(digest, &md5); 04274 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04275 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04276 if (!res) { 04277 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04278 break; 04279 } 04280 } 04281 } else 04282 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04283 return res; 04284 }
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 6903 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().
06904 { 06905 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06906 struct ast_iax2_full_hdr *fh, *cur_fh; 06907 06908 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06909 return; 06910 06911 pkt_buf->len = from_here->buf_len; 06912 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06913 06914 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06915 ast_mutex_lock(&to_here->lock); 06916 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06917 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06918 if (fh->oseqno < cur_fh->oseqno) { 06919 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06920 break; 06921 } 06922 } 06923 AST_LIST_TRAVERSE_SAFE_END 06924 06925 if (!cur_pkt_buf) 06926 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06927 06928 ast_mutex_unlock(&to_here->lock); 06929 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9827 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, user_delme_cb(), and users.
09828 { 09829 struct iax2_registry *reg; 09830 09831 ao2_callback(users, 0, user_delme_cb, NULL); 09832 09833 AST_LIST_LOCK(®istrations); 09834 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09835 ast_sched_del(sched, reg->expire); 09836 if (reg->callno) { 09837 ast_mutex_lock(&iaxsl[reg->callno]); 09838 if (iaxs[reg->callno]) { 09839 iaxs[reg->callno]->reg = NULL; 09840 iax2_destroy(reg->callno); 09841 } 09842 ast_mutex_unlock(&iaxsl[reg->callno]); 09843 } 09844 if (reg->dnsmgr) 09845 ast_dnsmgr_release(reg->dnsmgr); 09846 free(reg); 09847 } 09848 AST_LIST_UNLOCK(®istrations); 09849 09850 ao2_callback(peers, 0, peer_delme_cb, NULL); 09851 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1744 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01745 { 01746 /* Close firmware */ 01747 if (cur->fwh) { 01748 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01749 } 01750 close(cur->fd); 01751 free(cur); 01752 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6675 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_ie_data::buf, 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, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06676 { 06677 unsigned short dpstatus = 0; 06678 struct iax_ie_data ied1; 06679 int mm; 06680 06681 memset(&ied1, 0, sizeof(ied1)); 06682 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06683 /* Must be started */ 06684 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06685 dpstatus = IAX_DPSTATUS_EXISTS; 06686 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06687 dpstatus = IAX_DPSTATUS_CANEXIST; 06688 } else { 06689 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06690 } 06691 if (ast_ignore_pattern(context, callednum)) 06692 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06693 if (mm) 06694 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06695 if (!skiplock) 06696 ast_mutex_lock(&iaxsl[callno]); 06697 if (iaxs[callno]) { 06698 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06699 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06700 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06701 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06702 } 06703 if (!skiplock) 06704 ast_mutex_unlock(&iaxsl[callno]); 06705 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6707 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().
06708 { 06709 /* Look up for dpreq */ 06710 struct dpreq_data *dpr = data; 06711 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06712 if (dpr->callerid) 06713 free(dpr->callerid); 06714 free(dpr); 06715 return NULL; 06716 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4217 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, LOG_DEBUG, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
04218 { 04219 int padding; 04220 unsigned char *workspace; 04221 workspace = alloca(*datalen + 32); 04222 if (!workspace) 04223 return -1; 04224 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04225 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04226 if (option_debug && iaxdebug) 04227 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04228 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04229 padding = 16 + (padding & 0xf); 04230 memcpy(workspace, poo, padding); 04231 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04232 workspace[15] &= 0xf0; 04233 workspace[15] |= (padding & 0xf); 04234 if (option_debug && iaxdebug) 04235 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]); 04236 *datalen += padding; 04237 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04238 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04239 memcpy(poo, workspace + *datalen - 32, 32); 04240 } else { 04241 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04242 if (option_debug && iaxdebug) 04243 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04244 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04245 padding = 16 + (padding & 0xf); 04246 memcpy(workspace, poo, padding); 04247 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04248 workspace[15] &= 0xf0; 04249 workspace[15] |= (padding & 0x0f); 04250 *datalen += padding; 04251 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04252 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04253 memcpy(poo, workspace + *datalen - 32, 32); 04254 } 04255 return 0; 04256 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6115 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
06116 { 06117 #ifdef SCHED_MULTITHREADED 06118 if (schedule_action(__expire_registry, data)) 06119 #endif 06120 __expire_registry(data); 06121 return 0; 06122 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static, read] |
Definition at line 10385 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, iax2_registry::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().
10386 { 10387 struct iax2_dpcache *dp, *prev = NULL, *next; 10388 struct timeval tv; 10389 int x; 10390 int com[2]; 10391 int timeout; 10392 int old=0; 10393 int outfd; 10394 int abort; 10395 int callno; 10396 struct ast_channel *c; 10397 struct ast_frame *f; 10398 gettimeofday(&tv, NULL); 10399 dp = dpcache; 10400 while(dp) { 10401 next = dp->next; 10402 /* Expire old caches */ 10403 if (ast_tvcmp(tv, dp->expiry) > 0) { 10404 /* It's expired, let it disappear */ 10405 if (prev) 10406 prev->next = dp->next; 10407 else 10408 dpcache = dp->next; 10409 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10410 /* Free memory and go again */ 10411 free(dp); 10412 } else { 10413 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); 10414 } 10415 dp = next; 10416 continue; 10417 } 10418 /* We found an entry that matches us! */ 10419 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10420 break; 10421 prev = dp; 10422 dp = next; 10423 } 10424 if (!dp) { 10425 /* No matching entry. Create a new one. */ 10426 /* First, can we make a callno? */ 10427 callno = cache_get_callno_locked(data); 10428 if (callno < 0) { 10429 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10430 return NULL; 10431 } 10432 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10433 ast_mutex_unlock(&iaxsl[callno]); 10434 return NULL; 10435 } 10436 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10437 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10438 gettimeofday(&dp->expiry, NULL); 10439 dp->orig = dp->expiry; 10440 /* Expires in 30 mins by default */ 10441 dp->expiry.tv_sec += iaxdefaultdpcache; 10442 dp->next = dpcache; 10443 dp->flags = CACHE_FLAG_PENDING; 10444 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10445 dp->waiters[x] = -1; 10446 dpcache = dp; 10447 dp->peer = iaxs[callno]->dpentries; 10448 iaxs[callno]->dpentries = dp; 10449 /* Send the request if we're already up */ 10450 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10451 iax2_dprequest(dp, callno); 10452 ast_mutex_unlock(&iaxsl[callno]); 10453 } 10454 /* By here we must have a dp */ 10455 if (dp->flags & CACHE_FLAG_PENDING) { 10456 /* Okay, here it starts to get nasty. We need a pipe now to wait 10457 for a reply to come back so long as it's pending */ 10458 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10459 /* Find an empty slot */ 10460 if (dp->waiters[x] < 0) 10461 break; 10462 } 10463 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10464 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10465 return NULL; 10466 } 10467 if (pipe(com)) { 10468 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10469 return NULL; 10470 } 10471 dp->waiters[x] = com[1]; 10472 /* Okay, now we wait */ 10473 timeout = iaxdefaulttimeout * 1000; 10474 /* Temporarily unlock */ 10475 ast_mutex_unlock(&dpcache_lock); 10476 /* Defer any dtmf */ 10477 if (chan) 10478 old = ast_channel_defer_dtmf(chan); 10479 abort = 0; 10480 while(timeout) { 10481 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10482 if (outfd > -1) { 10483 break; 10484 } 10485 if (c) { 10486 f = ast_read(c); 10487 if (f) 10488 ast_frfree(f); 10489 else { 10490 /* Got hung up on, abort! */ 10491 break; 10492 abort = 1; 10493 } 10494 } 10495 } 10496 if (!timeout) { 10497 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10498 } 10499 ast_mutex_lock(&dpcache_lock); 10500 dp->waiters[x] = -1; 10501 close(com[1]); 10502 close(com[0]); 10503 if (abort) { 10504 /* Don't interpret anything, just abort. Not sure what th epoint 10505 of undeferring dtmf on a hung up channel is but hey whatever */ 10506 if (!old && chan) 10507 ast_channel_undefer_dtmf(chan); 10508 return NULL; 10509 } 10510 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10511 /* Now to do non-independent analysis the results of our wait */ 10512 if (dp->flags & CACHE_FLAG_PENDING) { 10513 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10514 pending. Don't let it take as long to timeout. */ 10515 dp->flags &= ~CACHE_FLAG_PENDING; 10516 dp->flags |= CACHE_FLAG_TIMEOUT; 10517 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10518 systems without leaving it unavailable once the server comes back online */ 10519 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10520 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10521 if (dp->waiters[x] > -1) 10522 write(dp->waiters[x], "asdf", 4); 10523 } 10524 } 10525 /* Our caller will obtain the rest */ 10526 if (!old && chan) 10527 ast_channel_undefer_dtmf(chan); 10528 } 10529 return dp; 10530 }
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 1644 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01644 { 01645 01646 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01647 }
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 1649 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01649 { 01650 01651 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01652 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 910 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, iax2_thread::ffinfo, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00911 { 00912 pthread_attr_t attr; 00913 struct iax2_thread *thread = NULL; 00914 00915 /* Pop the head of the list off */ 00916 AST_LIST_LOCK(&idle_list); 00917 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00918 AST_LIST_UNLOCK(&idle_list); 00919 00920 /* If no idle thread is available from the regular list, try dynamic */ 00921 if (thread == NULL) { 00922 AST_LIST_LOCK(&dynamic_list); 00923 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00924 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00925 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00926 /* We need to MAKE a thread! */ 00927 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00928 thread->threadnum = iaxdynamicthreadcount; 00929 thread->type = IAX_TYPE_DYNAMIC; 00930 ast_mutex_init(&thread->lock); 00931 ast_cond_init(&thread->cond, NULL); 00932 pthread_attr_init(&attr); 00933 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00934 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00935 free(thread); 00936 thread = NULL; 00937 } else { 00938 /* All went well and the thread is up, so increment our count */ 00939 iaxdynamicthreadcount++; 00940 00941 /* Wait for the thread to be ready before returning it to the caller */ 00942 while (!thread->ready_for_signal) 00943 usleep(1); 00944 } 00945 } 00946 } 00947 AST_LIST_UNLOCK(&dynamic_list); 00948 } 00949 00950 /* this thread is not processing a full frame (since it is idle), 00951 so ensure that the field for the full frame call number is empty */ 00952 if (thread) 00953 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00954 00955 return thread; 00956 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1143 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01144 { 01145 struct iax2_peer *peer = NULL; 01146 struct iax2_peer tmp_peer = { 01147 .name = name, 01148 }; 01149 01150 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01151 01152 /* Now go for realtime if applicable */ 01153 if(!peer && realtime) 01154 peer = realtime_peer(name, NULL); 01155 01156 return peer; 01157 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 4026 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, iax2_trunk_peer::next, option_debug, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process().
04027 { 04028 struct iax2_trunk_peer *tpeer; 04029 04030 /* Finds and locks trunk peer */ 04031 ast_mutex_lock(&tpeerlock); 04032 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04033 /* We don't lock here because tpeer->addr *never* changes */ 04034 if (!inaddrcmp(&tpeer->addr, sin)) { 04035 ast_mutex_lock(&tpeer->lock); 04036 break; 04037 } 04038 } 04039 if (!tpeer) { 04040 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04041 ast_mutex_init(&tpeer->lock); 04042 tpeer->lastsent = 9999; 04043 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04044 tpeer->trunkact = ast_tvnow(); 04045 ast_mutex_lock(&tpeer->lock); 04046 tpeer->next = tpeers; 04047 tpeer->sockfd = fd; 04048 tpeers = tpeer; 04049 #ifdef SO_NO_CHECK 04050 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04051 #endif 04052 if (option_debug) 04053 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04054 } 04055 } 04056 ast_mutex_unlock(&tpeerlock); 04057 return tpeer; 04058 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3842 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03843 { 03844 long ms; /* NOT unsigned */ 03845 if (ast_tvzero(iaxs[callno]->rxcore)) { 03846 /* Initialize rxcore time if appropriate */ 03847 gettimeofday(&iaxs[callno]->rxcore, NULL); 03848 /* Round to nearest 20ms so traces look pretty */ 03849 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03850 } 03851 /* Calculate difference between trunk and channel */ 03852 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03853 /* Return as the sum of trunk time and the difference between trunk and real time */ 03854 return ms + ts; 03855 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8994 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08995 { 08996 struct iax2_context *conl; 08997 while(con) { 08998 conl = con; 08999 con = con->next; 09000 free(conl); 09001 } 09002 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10654 of file chan_iax2.c.
References iax2_peer::addr, iax2_registry::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_registry::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.
10655 { 10656 struct iax2_peer *peer; 10657 char *peername, *colname; 10658 10659 peername = ast_strdupa(data); 10660 10661 /* if our channel, return the IP address of the endpoint of current channel */ 10662 if (!strcmp(peername,"CURRENTCHANNEL")) { 10663 unsigned short callno; 10664 if (chan->tech != &iax2_tech) 10665 return -1; 10666 callno = PTR_TO_CALLNO(chan->tech_pvt); 10667 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10668 return 0; 10669 } 10670 10671 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10672 *colname++ = '\0'; 10673 else if ((colname = strchr(peername, '|'))) 10674 *colname++ = '\0'; 10675 else 10676 colname = "ip"; 10677 10678 if (!(peer = find_peer(peername, 1))) 10679 return -1; 10680 10681 if (!strcasecmp(colname, "ip")) { 10682 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10683 } else if (!strcasecmp(colname, "status")) { 10684 peer_status(peer, buf, len); 10685 } else if (!strcasecmp(colname, "mailbox")) { 10686 ast_copy_string(buf, peer->mailbox, len); 10687 } else if (!strcasecmp(colname, "context")) { 10688 ast_copy_string(buf, peer->context, len); 10689 } else if (!strcasecmp(colname, "expire")) { 10690 snprintf(buf, len, "%d", peer->expire); 10691 } else if (!strcasecmp(colname, "dynamic")) { 10692 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10693 } else if (!strcasecmp(colname, "callerid_name")) { 10694 ast_copy_string(buf, peer->cid_name, len); 10695 } else if (!strcasecmp(colname, "callerid_num")) { 10696 ast_copy_string(buf, peer->cid_num, len); 10697 } else if (!strcasecmp(colname, "codecs")) { 10698 ast_getformatname_multiple(buf, len -1, peer->capability); 10699 } else if (!strncasecmp(colname, "codec[", 6)) { 10700 char *codecnum, *ptr; 10701 int index = 0, codec = 0; 10702 10703 codecnum = strchr(colname, '['); 10704 *codecnum = '\0'; 10705 codecnum++; 10706 if ((ptr = strchr(codecnum, ']'))) { 10707 *ptr = '\0'; 10708 } 10709 index = atoi(codecnum); 10710 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10711 ast_copy_string(buf, ast_getformatname(codec), len); 10712 } 10713 } 10714 10715 peer_unref(peer); 10716 10717 return 0; 10718 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9219 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09220 { 09221 int methods = 0; 09222 if (strstr(value, "rsa")) 09223 methods |= IAX_AUTH_RSA; 09224 if (strstr(value, "md5")) 09225 methods |= IAX_AUTH_MD5; 09226 if (strstr(value, "plaintext")) 09227 methods |= IAX_AUTH_PLAINTEXT; 09228 return methods; 09229 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1025 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01026 { 01027 int e; 01028 if (!strcasecmp(s, "aes128")) 01029 e = IAX_ENCRYPT_AES128; 01030 else if (ast_true(s)) 01031 e = IAX_ENCRYPT_AES128; 01032 else 01033 e = 0; 01034 return e; 01035 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2624 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02625 { 02626 #ifdef SCHED_MULTITHREADED 02627 if (schedule_action(__get_from_jb, data)) 02628 #endif 02629 __get_from_jb(data); 02630 return 0; 02631 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6873 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and socket_process().
Referenced by iax2_process_thread().
06874 { 06875 struct iax2_pkt_buf *pkt_buf; 06876 06877 ast_mutex_lock(&thread->lock); 06878 06879 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06880 ast_mutex_unlock(&thread->lock); 06881 06882 thread->buf = pkt_buf->buf; 06883 thread->buf_len = pkt_buf->len; 06884 thread->buf_size = pkt_buf->len + 1; 06885 06886 socket_process(thread); 06887 06888 thread->buf = NULL; 06889 ast_free(pkt_buf); 06890 06891 ast_mutex_lock(&thread->lock); 06892 } 06893 06894 ast_mutex_unlock(&thread->lock); 06895 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2032 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().
02033 { 02034 /* XXX Ideally we should figure out why an error occured and then abort those 02035 rather than continuing to try. Unfortunately, the published interface does 02036 not seem to work XXX */ 02037 #if 0 02038 struct sockaddr_in *sin; 02039 int res; 02040 struct msghdr m; 02041 struct sock_extended_err e; 02042 m.msg_name = NULL; 02043 m.msg_namelen = 0; 02044 m.msg_iov = NULL; 02045 m.msg_control = &e; 02046 m.msg_controllen = sizeof(e); 02047 m.msg_flags = 0; 02048 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02049 if (res < 0) 02050 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02051 else { 02052 if (m.msg_controllen) { 02053 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02054 if (sin) 02055 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02056 else 02057 ast_log(LOG_WARNING, "No address detected??\n"); 02058 } else { 02059 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02060 } 02061 } 02062 #endif 02063 return 0; 02064 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5936 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05937 { 05938 struct iax2_registry *reg; 05939 /* Start pessimistic */ 05940 char peer[256] = ""; 05941 char msgstatus[60]; 05942 int refresh = 60; 05943 char ourip[256] = "<Unspecified>"; 05944 struct sockaddr_in oldus; 05945 struct sockaddr_in us; 05946 int oldmsgs; 05947 05948 memset(&us, 0, sizeof(us)); 05949 if (ies->apparent_addr) 05950 bcopy(ies->apparent_addr, &us, sizeof(us)); 05951 if (ies->username) 05952 ast_copy_string(peer, ies->username, sizeof(peer)); 05953 if (ies->refresh) 05954 refresh = ies->refresh; 05955 if (ies->calling_number) { 05956 /* We don't do anything with it really, but maybe we should */ 05957 } 05958 reg = iaxs[callno]->reg; 05959 if (!reg) { 05960 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05961 return -1; 05962 } 05963 memcpy(&oldus, ®->us, sizeof(oldus)); 05964 oldmsgs = reg->messages; 05965 if (inaddrcmp(®->addr, sin)) { 05966 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05967 return -1; 05968 } 05969 memcpy(®->us, &us, sizeof(reg->us)); 05970 if (ies->msgcount >= 0) 05971 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05972 /* always refresh the registration at the interval requested by the server 05973 we are registering to 05974 */ 05975 reg->refresh = refresh; 05976 AST_SCHED_DEL(sched, reg->expire); 05977 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05978 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05979 if (option_verbose > 2) { 05980 if (reg->messages > 255) 05981 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05982 else if (reg->messages > 1) 05983 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05984 else if (reg->messages > 0) 05985 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05986 else 05987 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05988 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05989 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05990 } 05991 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05992 } 05993 reg->regstate = REG_STATE_REGISTERED; 05994 return 0; 05995 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3642 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), iax2_registry::callno, LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03643 { 03644 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03645 if (option_debug) 03646 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03647 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03648 }
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 3492 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, lock_both(), LOG_WARNING, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, tv, unlock_both(), and VERBOSE_PREFIX_3.
03493 { 03494 struct ast_channel *cs[3]; 03495 struct ast_channel *who, *other; 03496 int to = -1; 03497 int res = -1; 03498 int transferstarted=0; 03499 struct ast_frame *f; 03500 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03501 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03502 struct timeval waittimer = {0, 0}, tv; 03503 03504 lock_both(callno0, callno1); 03505 if (!iaxs[callno0] || !iaxs[callno1]) { 03506 unlock_both(callno0, callno1); 03507 return AST_BRIDGE_FAILED; 03508 } 03509 /* Put them in native bridge mode */ 03510 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03511 iaxs[callno0]->bridgecallno = callno1; 03512 iaxs[callno1]->bridgecallno = callno0; 03513 } 03514 unlock_both(callno0, callno1); 03515 03516 /* If not, try to bridge until we can execute a transfer, if we can */ 03517 cs[0] = c0; 03518 cs[1] = c1; 03519 for (/* ever */;;) { 03520 /* Check in case we got masqueraded into */ 03521 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03522 if (option_verbose > 2) 03523 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03524 /* Remove from native mode */ 03525 if (c0->tech == &iax2_tech) { 03526 ast_mutex_lock(&iaxsl[callno0]); 03527 iaxs[callno0]->bridgecallno = 0; 03528 ast_mutex_unlock(&iaxsl[callno0]); 03529 } 03530 if (c1->tech == &iax2_tech) { 03531 ast_mutex_lock(&iaxsl[callno1]); 03532 iaxs[callno1]->bridgecallno = 0; 03533 ast_mutex_unlock(&iaxsl[callno1]); 03534 } 03535 return AST_BRIDGE_FAILED_NOWARN; 03536 } 03537 if (c0->nativeformats != c1->nativeformats) { 03538 if (option_verbose > 2) { 03539 char buf0[255]; 03540 char buf1[255]; 03541 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03542 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03543 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03544 } 03545 /* Remove from native mode */ 03546 lock_both(callno0, callno1); 03547 if (iaxs[callno0]) 03548 iaxs[callno0]->bridgecallno = 0; 03549 if (iaxs[callno1]) 03550 iaxs[callno1]->bridgecallno = 0; 03551 unlock_both(callno0, callno1); 03552 return AST_BRIDGE_FAILED_NOWARN; 03553 } 03554 /* check if transfered and if we really want native bridging */ 03555 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03556 /* Try the transfer */ 03557 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03558 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03559 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03560 transferstarted = 1; 03561 } 03562 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03563 /* Call has been transferred. We're no longer involved */ 03564 gettimeofday(&tv, NULL); 03565 if (ast_tvzero(waittimer)) { 03566 waittimer = tv; 03567 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03568 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03569 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03570 *fo = NULL; 03571 *rc = c0; 03572 res = AST_BRIDGE_COMPLETE; 03573 break; 03574 } 03575 } 03576 to = 1000; 03577 who = ast_waitfor_n(cs, 2, &to); 03578 if (timeoutms > -1) { 03579 timeoutms -= (1000 - to); 03580 if (timeoutms < 0) 03581 timeoutms = 0; 03582 } 03583 if (!who) { 03584 if (!timeoutms) { 03585 res = AST_BRIDGE_RETRY; 03586 break; 03587 } 03588 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03589 res = AST_BRIDGE_FAILED; 03590 break; 03591 } 03592 continue; 03593 } 03594 f = ast_read(who); 03595 if (!f) { 03596 *fo = NULL; 03597 *rc = who; 03598 res = AST_BRIDGE_COMPLETE; 03599 break; 03600 } 03601 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03602 *fo = f; 03603 *rc = who; 03604 res = AST_BRIDGE_COMPLETE; 03605 break; 03606 } 03607 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03608 if ((f->frametype == AST_FRAME_VOICE) || 03609 (f->frametype == AST_FRAME_TEXT) || 03610 (f->frametype == AST_FRAME_VIDEO) || 03611 (f->frametype == AST_FRAME_IMAGE) || 03612 (f->frametype == AST_FRAME_DTMF)) { 03613 /* monitored dtmf take out of the bridge. 03614 * check if we monitor the specific source. 03615 */ 03616 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03617 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03618 *rc = who; 03619 *fo = f; 03620 res = AST_BRIDGE_COMPLETE; 03621 /* Remove from native mode */ 03622 break; 03623 } 03624 /* everything else goes to the other side */ 03625 ast_write(other, f); 03626 } 03627 ast_frfree(f); 03628 /* Swap who gets priority */ 03629 cs[2] = cs[0]; 03630 cs[0] = cs[1]; 03631 cs[1] = cs[2]; 03632 } 03633 lock_both(callno0, callno1); 03634 if(iaxs[callno0]) 03635 iaxs[callno0]->bridgecallno = 0; 03636 if(iaxs[callno1]) 03637 iaxs[callno1]->bridgecallno = 0; 03638 unlock_both(callno0, callno1); 03639 return res; 03640 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3224 of file chan_iax2.c.
References ast_channel::_state, create_addr_info::adsi, 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(), iax_ie_data::buf, iax2_registry::callno, 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, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, 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, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, iax2_registry::secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, and parsed_dial_string::username.
03225 { 03226 struct sockaddr_in sin; 03227 char *l=NULL, *n=NULL, *tmpstr; 03228 struct iax_ie_data ied; 03229 char *defaultrdest = "s"; 03230 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03231 struct parsed_dial_string pds; 03232 struct create_addr_info cai; 03233 03234 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03235 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03236 return -1; 03237 } 03238 03239 memset(&cai, 0, sizeof(cai)); 03240 cai.encmethods = iax2_encryption; 03241 03242 memset(&pds, 0, sizeof(pds)); 03243 tmpstr = ast_strdupa(dest); 03244 parse_dial_string(tmpstr, &pds); 03245 03246 if (ast_strlen_zero(pds.peer)) { 03247 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03248 return -1; 03249 } 03250 03251 if (!pds.exten) { 03252 pds.exten = defaultrdest; 03253 } 03254 03255 if (create_addr(pds.peer, c, &sin, &cai)) { 03256 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03257 return -1; 03258 } 03259 03260 if (!pds.username && !ast_strlen_zero(cai.username)) 03261 pds.username = cai.username; 03262 if (!pds.password && !ast_strlen_zero(cai.secret)) 03263 pds.password = cai.secret; 03264 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03265 pds.key = cai.outkey; 03266 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03267 pds.context = cai.peercontext; 03268 03269 /* Keep track of the context for outgoing calls too */ 03270 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03271 03272 if (pds.port) 03273 sin.sin_port = htons(atoi(pds.port)); 03274 03275 l = c->cid.cid_num; 03276 n = c->cid.cid_name; 03277 03278 /* Now build request */ 03279 memset(&ied, 0, sizeof(ied)); 03280 03281 /* On new call, first IE MUST be IAX version of caller */ 03282 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03283 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03284 if (pds.options && strchr(pds.options, 'a')) { 03285 /* Request auto answer */ 03286 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03287 } 03288 03289 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03290 03291 if (l) { 03292 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03293 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03294 } else { 03295 if (n) 03296 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03297 else 03298 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03299 } 03300 03301 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03302 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03303 03304 if (n) 03305 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03306 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03307 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03308 03309 if (!ast_strlen_zero(c->language)) 03310 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03311 if (!ast_strlen_zero(c->cid.cid_dnid)) 03312 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03313 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03314 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03315 03316 if (pds.context) 03317 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03318 03319 if (pds.username) 03320 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03321 03322 if (cai.encmethods) 03323 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03324 03325 ast_mutex_lock(&iaxsl[callno]); 03326 03327 if (!ast_strlen_zero(c->context)) 03328 ast_string_field_set(iaxs[callno], context, c->context); 03329 03330 if (pds.username) 03331 ast_string_field_set(iaxs[callno], username, pds.username); 03332 03333 iaxs[callno]->encmethods = cai.encmethods; 03334 03335 iaxs[callno]->adsi = cai.adsi; 03336 03337 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03338 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03339 03340 if (pds.key) 03341 ast_string_field_set(iaxs[callno], outkey, pds.key); 03342 if (pds.password) 03343 ast_string_field_set(iaxs[callno], secret, pds.password); 03344 03345 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03346 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03347 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03348 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03349 03350 if (iaxs[callno]->maxtime) { 03351 /* Initialize pingtime and auto-congest time */ 03352 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03353 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03354 } else if (autokill) { 03355 iaxs[callno]->pingtime = autokill / 2; 03356 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03357 } 03358 03359 /* send the command using the appropriate socket for this peer */ 03360 iaxs[callno]->sockfd = cai.sockfd; 03361 03362 /* Transmit the string in a "NEW" request */ 03363 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03364 03365 ast_mutex_unlock(&iaxsl[callno]); 03366 ast_setstate(c, AST_STATE_RINGING); 03367 03368 return 0; 03369 }
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 10556 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.
10557 { 10558 int res = 0; 10559 struct iax2_dpcache *dp; 10560 #if 0 10561 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10562 #endif 10563 if ((priority != 1) && (priority != 2)) 10564 return 0; 10565 ast_mutex_lock(&dpcache_lock); 10566 dp = find_cache(chan, data, context, exten, priority); 10567 if (dp) { 10568 if (dp->flags & CACHE_FLAG_CANEXIST) 10569 res= 1; 10570 } 10571 ast_mutex_unlock(&dpcache_lock); 10572 if (!dp) { 10573 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10574 } 10575 return res; 10576 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3127 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03128 { 03129 time_t t; 03130 struct tm tm; 03131 unsigned int tmp; 03132 time(&t); 03133 if (!ast_strlen_zero(tz)) 03134 ast_localtime(&t, &tm, tz); 03135 else 03136 ast_localtime(&t, &tm, NULL); 03137 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03138 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03139 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03140 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03141 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03142 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03143 return tmp; 03144 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1283 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, lastused, 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().
01284 { 01285 struct chan_iax2_pvt *pvt; 01286 struct ast_channel *owner; 01287 01288 retry: 01289 pvt = iaxs[callno]; 01290 gettimeofday(&lastused[callno], NULL); 01291 01292 owner = pvt ? pvt->owner : NULL; 01293 01294 if (owner) { 01295 if (ast_mutex_trylock(&owner->lock)) { 01296 if (option_debug > 2) 01297 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01298 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01299 goto retry; 01300 } 01301 } 01302 if (!owner) { 01303 iaxs[callno] = NULL; 01304 } 01305 01306 if (pvt) { 01307 if (!owner) { 01308 pvt->owner = NULL; 01309 } else { 01310 /* If there's an owner, prod it to give up */ 01311 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01312 * because we already hold the owner channel lock. */ 01313 ast_queue_hangup(owner); 01314 } 01315 01316 if (pvt->peercallno) { 01317 remove_by_peercallno(pvt); 01318 } 01319 01320 if (!owner) { 01321 ao2_ref(pvt, -1); 01322 pvt = NULL; 01323 } 01324 } 01325 01326 if (owner) { 01327 ast_mutex_unlock(&owner->lock); 01328 } 01329 01330 if (callno & 0x4000) { 01331 update_max_trunk(); 01332 } 01333 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1213 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, user_unref(), and users.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01214 { 01215 /* Decrement AUTHREQ count if needed */ 01216 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01217 struct iax2_user *user; 01218 struct iax2_user tmp_user = { 01219 .name = pvt->username, 01220 }; 01221 01222 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01223 if (user) { 01224 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01225 user = user_unref(user); 01226 } 01227 01228 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01229 } 01230 01231 /* No more pings or lagrq's */ 01232 AST_SCHED_DEL(sched, pvt->pingid); 01233 AST_SCHED_DEL(sched, pvt->lagid); 01234 AST_SCHED_DEL(sched, pvt->autoid); 01235 AST_SCHED_DEL(sched, pvt->authid); 01236 AST_SCHED_DEL(sched, pvt->initid); 01237 AST_SCHED_DEL(sched, pvt->jbid); 01238 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10743 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_DEBUG, LOG_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
10744 { 10745 struct parsed_dial_string pds; 10746 char *tmp = ast_strdupa(data); 10747 struct iax2_peer *p; 10748 int res = AST_DEVICE_INVALID; 10749 10750 memset(&pds, 0, sizeof(pds)); 10751 parse_dial_string(tmp, &pds); 10752 10753 if (ast_strlen_zero(pds.peer)) { 10754 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10755 return res; 10756 } 10757 10758 if (option_debug > 2) 10759 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10760 10761 /* SLD: FIXME: second call to find_peer during registration */ 10762 if (!(p = find_peer(pds.peer, 1))) 10763 return res; 10764 10765 res = AST_DEVICE_UNAVAILABLE; 10766 if (option_debug > 2) 10767 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10768 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10769 10770 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10771 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10772 /* Peer is registered, or have default IP address 10773 and a valid registration */ 10774 if (p->historicms == 0 || p->historicms <= p->maxms) 10775 /* let the core figure out whether it is in use or not */ 10776 res = AST_DEVICE_UNKNOWN; 10777 } 10778 10779 peer_unref(p); 10780 10781 return res; 10782 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2743 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02744 { 02745 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02746 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2748 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02749 { 02750 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02751 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4948 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04949 { 04950 if (argc < 2 || argc > 3) 04951 return RESULT_SHOWUSAGE; 04952 iaxdebug = 1; 04953 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04954 return RESULT_SUCCESS; 04955 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4966 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04967 { 04968 if (argc < 3 || argc > 4) 04969 return RESULT_SHOWUSAGE; 04970 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04971 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04972 return RESULT_SUCCESS; 04973 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8713 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, iax_ie_data::buf, 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_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08714 { 08715 struct iax_ie_data ied; 08716 if (option_debug && iaxdebug) 08717 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08718 08719 if (reg->dnsmgr && 08720 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08721 /* Maybe the IP has changed, force DNS refresh */ 08722 ast_dnsmgr_refresh(reg->dnsmgr); 08723 } 08724 08725 /* 08726 * if IP has Changed, free allocated call to create a new one with new IP 08727 * call has the pointer to IP and must be updated to the new one 08728 */ 08729 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08730 ast_mutex_lock(&iaxsl[reg->callno]); 08731 iax2_destroy(reg->callno); 08732 ast_mutex_unlock(&iaxsl[reg->callno]); 08733 reg->callno = 0; 08734 } 08735 if (!reg->addr.sin_addr.s_addr) { 08736 if (option_debug && iaxdebug) 08737 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08738 /* Setup the next registration attempt */ 08739 AST_SCHED_DEL(sched, reg->expire); 08740 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08741 return -1; 08742 } 08743 08744 if (!reg->callno) { 08745 if (option_debug) 08746 ast_log(LOG_DEBUG, "Allocate call number\n"); 08747 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08748 if (reg->callno < 1) { 08749 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08750 return -1; 08751 } else if (option_debug) 08752 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08753 iaxs[reg->callno]->reg = reg; 08754 ast_mutex_unlock(&iaxsl[reg->callno]); 08755 } 08756 /* Schedule the next registration attempt */ 08757 AST_SCHED_DEL(sched, reg->expire); 08758 /* Setup the next registration a little early */ 08759 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08760 /* Send the request */ 08761 memset(&ied, 0, sizeof(ied)); 08762 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08763 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08764 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08765 reg->regstate = REG_STATE_REGSENT; 08766 return 0; 08767 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5784 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05785 { 05786 #ifdef SCHED_MULTITHREADED 05787 if (schedule_action(__iax2_do_register_s, data)) 05788 #endif 05789 __iax2_do_register_s(data); 05790 return 0; 05791 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4957 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04958 { 04959 if (argc < 3 || argc > 4) 04960 return RESULT_SHOWUSAGE; 04961 iaxtrunkdebug = 1; 04962 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04963 return RESULT_SUCCESS; 04964 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6484 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
06485 { 06486 struct iax_ie_data ied; 06487 /* Auto-hangup with 30 seconds of inactivity */ 06488 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06489 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06490 memset(&ied, 0, sizeof(ied)); 06491 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06492 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06493 dp->flags |= CACHE_FLAG_TRANSMITTED; 06494 }
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 10602 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.
10603 { 10604 char odata[256]; 10605 char req[256]; 10606 char *ncontext; 10607 struct iax2_dpcache *dp; 10608 struct ast_app *dial; 10609 #if 0 10610 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); 10611 #endif 10612 if (priority == 2) { 10613 /* Indicate status, can be overridden in dialplan */ 10614 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10615 if (dialstatus) { 10616 dial = pbx_findapp(dialstatus); 10617 if (dial) 10618 pbx_exec(chan, dial, ""); 10619 } 10620 return -1; 10621 } else if (priority != 1) 10622 return -1; 10623 ast_mutex_lock(&dpcache_lock); 10624 dp = find_cache(chan, data, context, exten, priority); 10625 if (dp) { 10626 if (dp->flags & CACHE_FLAG_EXISTS) { 10627 ast_copy_string(odata, data, sizeof(odata)); 10628 ncontext = strchr(odata, '/'); 10629 if (ncontext) { 10630 *ncontext = '\0'; 10631 ncontext++; 10632 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10633 } else { 10634 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10635 } 10636 if (option_verbose > 2) 10637 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10638 } else { 10639 ast_mutex_unlock(&dpcache_lock); 10640 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10641 return -1; 10642 } 10643 } 10644 ast_mutex_unlock(&dpcache_lock); 10645 dial = pbx_findapp("Dial"); 10646 if (dial) { 10647 return pbx_exec(chan, dial, req); 10648 } else { 10649 ast_log(LOG_WARNING, "No dial application registered\n"); 10650 } 10651 return -1; 10652 }
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 10533 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.
10534 { 10535 struct iax2_dpcache *dp; 10536 int res = 0; 10537 #if 0 10538 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10539 #endif 10540 if ((priority != 1) && (priority != 2)) 10541 return 0; 10542 ast_mutex_lock(&dpcache_lock); 10543 dp = find_cache(chan, data, context, exten, priority); 10544 if (dp) { 10545 if (dp->flags & CACHE_FLAG_EXISTS) 10546 res= 1; 10547 } 10548 ast_mutex_unlock(&dpcache_lock); 10549 if (!dp) { 10550 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10551 } 10552 return res; 10553 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2770 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02771 { 02772 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02773 ast_mutex_lock(&iaxsl[callno]); 02774 if (iaxs[callno]) 02775 iaxs[callno]->owner = newchan; 02776 else 02777 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02778 ast_mutex_unlock(&iaxsl[callno]); 02779 return 0; 02780 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1277 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), and schedule_delivery().
01278 { 01279 AST_SCHED_DEL(sched, fr->retrans); 01280 iax_frame_free(fr); 01281 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1183 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().
01184 { 01185 struct iax2_peer *peer = NULL; 01186 int res = 0; 01187 struct ao2_iterator i; 01188 01189 i = ao2_iterator_init(peers, 0); 01190 while ((peer = ao2_iterator_next(&i))) { 01191 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01192 (peer->addr.sin_port == sin.sin_port)) { 01193 ast_copy_string(host, peer->name, len); 01194 peer_unref(peer); 01195 res = 1; 01196 break; 01197 } 01198 peer_unref(peer); 01199 } 01200 01201 if (!peer) { 01202 peer = realtime_peer(NULL, &sin); 01203 if (peer) { 01204 ast_copy_string(host, peer->name, len); 01205 peer_unref(peer); 01206 res = 1; 01207 } 01208 } 01209 01210 return res; 01211 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3717 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().
03718 { 03719 struct iax2_peer *peer; 03720 int res = 0; 03721 struct ao2_iterator i; 03722 03723 i = ao2_iterator_init(peers, 0); 03724 while ((peer = ao2_iterator_next(&i))) { 03725 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03726 (peer->addr.sin_port == sin.sin_port)) { 03727 res = ast_test_flag(peer, IAX_TRUNK); 03728 peer_unref(peer); 03729 break; 03730 } 03731 peer_unref(peer); 03732 } 03733 03734 return res; 03735 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3371 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), iax_ie_data::buf, iax2_registry::callno, error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_DEBUG, option_debug, option_verbose, iax_ie_data::pos, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03372 { 03373 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03374 int alreadygone; 03375 struct iax_ie_data ied; 03376 memset(&ied, 0, sizeof(ied)); 03377 ast_mutex_lock(&iaxsl[callno]); 03378 if (callno && iaxs[callno]) { 03379 if (option_debug) 03380 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03381 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03382 /* Send the hangup unless we have had a transmission error or are already gone */ 03383 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03384 if (!iaxs[callno]->error && !alreadygone) { 03385 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03386 if (!iaxs[callno]) { 03387 ast_mutex_unlock(&iaxsl[callno]); 03388 return 0; 03389 } 03390 } 03391 /* Explicitly predestroy it */ 03392 iax2_predestroy(callno); 03393 /* If we were already gone to begin with, destroy us now */ 03394 if (alreadygone && iaxs[callno]) { 03395 if (option_debug) 03396 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03397 iax2_destroy(callno); 03398 } 03399 } 03400 ast_mutex_unlock(&iaxsl[callno]); 03401 if (option_verbose > 2) 03402 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03403 return 0; 03404 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3650 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(), iax2_registry::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03651 { 03652 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03653 struct chan_iax2_pvt *pvt; 03654 int res = 0; 03655 03656 if (option_debug && iaxdebug) 03657 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03658 03659 ast_mutex_lock(&iaxsl[callno]); 03660 pvt = iaxs[callno]; 03661 03662 if (!pvt->peercallno) { 03663 /* We don't know the remote side's call number, yet. :( */ 03664 int count = 10; 03665 while (count-- && pvt && !pvt->peercallno) { 03666 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03667 pvt = iaxs[callno]; 03668 } 03669 if (!pvt->peercallno) { 03670 res = -1; 03671 goto done; 03672 } 03673 } 03674 03675 switch (condition) { 03676 case AST_CONTROL_HOLD: 03677 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03678 ast_moh_start(c, data, pvt->mohinterpret); 03679 goto done; 03680 } 03681 break; 03682 case AST_CONTROL_UNHOLD: 03683 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03684 ast_moh_stop(c); 03685 goto done; 03686 } 03687 } 03688 03689 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03690 03691 done: 03692 ast_mutex_unlock(&iaxsl[callno]); 03693 03694 return res; 03695 }
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 10579 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.
10580 { 10581 int res = 0; 10582 struct iax2_dpcache *dp; 10583 #if 0 10584 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10585 #endif 10586 if ((priority != 1) && (priority != 2)) 10587 return 0; 10588 ast_mutex_lock(&dpcache_lock); 10589 dp = find_cache(chan, data, context, exten, priority); 10590 if (dp) { 10591 if (dp->flags & CACHE_FLAG_MATCHMORE) 10592 res= 1; 10593 } 10594 ast_mutex_unlock(&dpcache_lock); 10595 if (!dp) { 10596 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10597 } 10598 return res; 10599 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4975 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04976 { 04977 if (argc < 3 || argc > 4) 04978 return RESULT_SHOWUSAGE; 04979 iaxdebug = 0; 04980 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04981 return RESULT_SUCCESS; 04982 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4993 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04994 { 04995 if (argc < 4 || argc > 5) 04996 return RESULT_SHOWUSAGE; 04997 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04998 jb_debug_output("\n"); 04999 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 05000 return RESULT_SUCCESS; 05001 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4984 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04985 { 04986 if (argc < 4 || argc > 5) 04987 return RESULT_SHOWUSAGE; 04988 iaxtrunkdebug = 0; 04989 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04990 return RESULT_SUCCESS; 04991 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8911 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08912 { 08913 struct iax2_peer *peer = (struct iax2_peer *)data; 08914 peer->pokeexpire = -1; 08915 #ifdef SCHED_MULTITHREADED 08916 if (schedule_action(__iax2_poke_noanswer, data)) 08917 #endif 08918 __iax2_poke_noanswer(data); 08919 peer_unref(peer); 08920 return 0; 08921 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8932 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, iax2_registry::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, 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().
08933 { 08934 int callno; 08935 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08936 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08937 immediately after clearing things out */ 08938 peer->lastms = 0; 08939 peer->historicms = 0; 08940 peer->pokeexpire = -1; 08941 peer->callno = 0; 08942 return 0; 08943 } 08944 08945 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 08946 if ((callno = peer->callno) > 0) { 08947 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08948 ast_mutex_lock(&iaxsl[callno]); 08949 iax2_destroy(callno); 08950 ast_mutex_unlock(&iaxsl[callno]); 08951 } 08952 if (heldcall) 08953 ast_mutex_unlock(&iaxsl[heldcall]); 08954 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08955 if (heldcall) 08956 ast_mutex_lock(&iaxsl[heldcall]); 08957 if (peer->callno < 1) { 08958 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08959 return -1; 08960 } 08961 08962 /* Speed up retransmission times for this qualify call */ 08963 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08964 iaxs[peer->callno]->peerpoke = peer; 08965 08966 /* Remove any pending pokeexpire task */ 08967 if (peer->pokeexpire > -1) { 08968 if (!ast_sched_del(sched, peer->pokeexpire)) { 08969 peer->pokeexpire = -1; 08970 peer_unref(peer); 08971 } 08972 } 08973 08974 /* Queue up a new task to handle no reply */ 08975 /* If the host is already unreachable then use the unreachable interval instead */ 08976 if (peer->lastms < 0) { 08977 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08978 } else 08979 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08980 08981 if (peer->pokeexpire == -1) 08982 peer_unref(peer); 08983 08984 /* And send the poke */ 08985 ast_mutex_lock(&iaxsl[callno]); 08986 if (iaxs[callno]) { 08987 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08988 } 08989 ast_mutex_unlock(&iaxsl[callno]); 08990 08991 return 0; 08992 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8923 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08924 { 08925 struct iax2_peer *peer = obj; 08926 08927 iax2_poke_peer(peer, 0); 08928 08929 return 0; 08930 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6524 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06525 { 06526 struct iax2_peer *peer = (struct iax2_peer *)data; 06527 peer->pokeexpire = -1; 06528 #ifdef SCHED_MULTITHREADED 06529 if (schedule_action(__iax2_poke_peer_s, data)) 06530 #endif 06531 __iax2_poke_peer_s(data); 06532 return 0; 06533 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2116 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().
02117 { 02118 struct ast_channel *c; 02119 struct chan_iax2_pvt *pvt = iaxs[callno]; 02120 02121 if (!pvt) 02122 return -1; 02123 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02124 iax2_destroy_helper(pvt); 02125 ast_set_flag(pvt, IAX_ALREADYGONE); 02126 } 02127 c = pvt->owner; 02128 if (c) { 02129 c->tech_pvt = NULL; 02130 iax2_queue_hangup(callno); 02131 pvt->owner = NULL; 02132 ast_module_unref(ast_module_info->self); 02133 } 02134 return 0; 02135 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8588 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), socket_process(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08589 { 08590 struct iax2_thread *thread = data; 08591 struct timeval tv; 08592 struct timespec ts; 08593 int put_into_idle = 0; 08594 08595 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08596 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08597 for(;;) { 08598 /* Wait for something to signal us to be awake */ 08599 ast_mutex_lock(&thread->lock); 08600 08601 /* Flag that we're ready to accept signals */ 08602 thread->ready_for_signal = 1; 08603 08604 /* Put into idle list if applicable */ 08605 if (put_into_idle) 08606 insert_idle_thread(thread); 08607 08608 if (thread->type == IAX_TYPE_DYNAMIC) { 08609 struct iax2_thread *t = NULL; 08610 /* Wait to be signalled or time out */ 08611 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08612 ts.tv_sec = tv.tv_sec; 08613 ts.tv_nsec = tv.tv_usec * 1000; 08614 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08615 /* This thread was never put back into the available dynamic 08616 * thread list, so just go away. */ 08617 if (!put_into_idle) { 08618 ast_mutex_unlock(&thread->lock); 08619 break; 08620 } 08621 AST_LIST_LOCK(&dynamic_list); 08622 /* Account for the case where this thread is acquired *right* after a timeout */ 08623 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08624 iaxdynamicthreadcount--; 08625 AST_LIST_UNLOCK(&dynamic_list); 08626 if (t) { 08627 /* This dynamic thread timed out waiting for a task and was 08628 * not acquired immediately after the timeout, 08629 * so it's time to go away. */ 08630 ast_mutex_unlock(&thread->lock); 08631 break; 08632 } 08633 /* Someone grabbed our thread *right* after we timed out. 08634 * Wait for them to set us up with something to do and signal 08635 * us to continue. */ 08636 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08637 ts.tv_sec = tv.tv_sec; 08638 ts.tv_nsec = tv.tv_usec * 1000; 08639 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08640 { 08641 ast_mutex_unlock(&thread->lock); 08642 break; 08643 } 08644 } 08645 } else { 08646 ast_cond_wait(&thread->cond, &thread->lock); 08647 } 08648 08649 /* Go back into our respective list */ 08650 put_into_idle = 1; 08651 08652 ast_mutex_unlock(&thread->lock); 08653 08654 if (thread->iostate == IAX_IOSTATE_IDLE) 08655 continue; 08656 08657 /* Add ourselves to the active list now */ 08658 AST_LIST_LOCK(&active_list); 08659 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08660 AST_LIST_UNLOCK(&active_list); 08661 08662 /* See what we need to do */ 08663 switch(thread->iostate) { 08664 case IAX_IOSTATE_READY: 08665 thread->actions++; 08666 thread->iostate = IAX_IOSTATE_PROCESSING; 08667 socket_process(thread); 08668 handle_deferred_full_frames(thread); 08669 break; 08670 case IAX_IOSTATE_SCHEDREADY: 08671 thread->actions++; 08672 thread->iostate = IAX_IOSTATE_PROCESSING; 08673 #ifdef SCHED_MULTITHREADED 08674 thread->schedfunc(thread->scheddata); 08675 #endif 08676 break; 08677 } 08678 time(&thread->checktime); 08679 thread->iostate = IAX_IOSTATE_IDLE; 08680 #ifdef DEBUG_SCHED_MULTITHREAD 08681 thread->curfunc[0]='\0'; 08682 #endif 08683 08684 /* Now... remove ourselves from the active list, and return to the idle list */ 08685 AST_LIST_LOCK(&active_list); 08686 AST_LIST_REMOVE(&active_list, thread, list); 08687 AST_LIST_UNLOCK(&active_list); 08688 08689 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08690 handle_deferred_full_frames(thread); 08691 } 08692 08693 /*!\note For some reason, idle threads are exiting without being removed 08694 * from an idle list, which is causing memory corruption. Forcibly remove 08695 * it from the list, if it's there. 08696 */ 08697 AST_LIST_LOCK(&idle_list); 08698 AST_LIST_REMOVE(&idle_list, thread, list); 08699 AST_LIST_UNLOCK(&idle_list); 08700 08701 AST_LIST_LOCK(&dynamic_list); 08702 AST_LIST_REMOVE(&dynamic_list, thread, list); 08703 AST_LIST_UNLOCK(&dynamic_list); 08704 08705 /* I am exiting here on my own volition, I need to clean up my own data structures 08706 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08707 */ 08708 pthread_cleanup_pop(1); 08709 08710 return NULL; 08711 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8579 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08580 { 08581 struct iax2_thread *thread = data; 08582 ast_mutex_destroy(&thread->lock); 08583 ast_cond_destroy(&thread->cond); 08584 free(thread); 08585 ast_atomic_dec_and_test(&iaxactivethreadcount); 08586 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8866 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08867 { 08868 int force = 0; 08869 int res; 08870 if (argc < 4) 08871 return RESULT_SHOWUSAGE; 08872 if ((argc > 4)) { 08873 if (!strcasecmp(argv[4], "forced")) 08874 force = 1; 08875 else 08876 return RESULT_SHOWUSAGE; 08877 } 08878 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08879 if (res < 0) 08880 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08881 else if (res < 1) 08882 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08883 else 08884 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08885 return RESULT_SUCCESS; 08886 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8769 of file chan_iax2.c.
References iax_prov_complete_template().
08770 { 08771 if (pos != 3) 08772 return NULL; 08773 return iax_prov_complete_template(line, word, pos, state); 08774 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8776 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, iax2_registry::callno, 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, LOG_DEBUG, NEW_FORCE, option_debug, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08777 { 08778 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08779 is found for template */ 08780 struct iax_ie_data provdata; 08781 struct iax_ie_data ied; 08782 unsigned int sig; 08783 struct sockaddr_in sin; 08784 int callno; 08785 struct create_addr_info cai; 08786 08787 memset(&cai, 0, sizeof(cai)); 08788 08789 if (option_debug) 08790 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08791 08792 if (iax_provision_build(&provdata, &sig, template, force)) { 08793 if (option_debug) 08794 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08795 return 0; 08796 } 08797 08798 if (end) { 08799 memcpy(&sin, end, sizeof(sin)); 08800 cai.sockfd = sockfd; 08801 } else if (create_addr(dest, NULL, &sin, &cai)) 08802 return -1; 08803 08804 /* Build the rest of the message */ 08805 memset(&ied, 0, sizeof(ied)); 08806 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08807 08808 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08809 if (!callno) 08810 return -1; 08811 08812 if (iaxs[callno]) { 08813 /* Schedule autodestruct in case they don't ever give us anything back */ 08814 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08815 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08816 ast_set_flag(iaxs[callno], IAX_PROVISION); 08817 /* Got a call number now, so go ahead and send the provisioning information */ 08818 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08819 } 08820 ast_mutex_unlock(&iaxsl[callno]); 08821 08822 return 1; 08823 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2240 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.
02241 { 02242 struct iax2_peer *peer; 02243 02244 if (argc != 4) 02245 return RESULT_SHOWUSAGE; 02246 if (!strcmp(argv[3],"all")) { 02247 reload_config(); 02248 ast_cli(fd, "OK cache is flushed.\n"); 02249 } else if ((peer = find_peer(argv[3], 0))) { 02250 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02251 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02252 expire_registry(peer_ref(peer)); 02253 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02254 } else { 02255 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02256 } 02257 peer_unref(peer); 02258 } else { 02259 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02260 } 02261 02262 return RESULT_SUCCESS; 02263 }
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 1726 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01728 { 01729 for (;;) { 01730 if (iaxs[callno] && iaxs[callno]->owner) { 01731 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01732 /* Avoid deadlock by pausing and trying again */ 01733 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01734 } else { 01735 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01736 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01737 break; 01738 } 01739 } else 01740 break; 01741 } 01742 return 0; 01743 }
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 1664 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01665 { 01666 for (;;) { 01667 if (iaxs[callno] && iaxs[callno]->owner) { 01668 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01669 /* Avoid deadlock by pausing and trying again */ 01670 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01671 } else { 01672 ast_queue_frame(iaxs[callno]->owner, f); 01673 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01674 break; 01675 } 01676 } else 01677 break; 01678 } 01679 return 0; 01680 }
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 1695 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01696 { 01697 for (;;) { 01698 if (iaxs[callno] && iaxs[callno]->owner) { 01699 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01700 /* Avoid deadlock by pausing and trying again */ 01701 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01702 } else { 01703 ast_queue_hangup(iaxs[callno]->owner); 01704 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01705 break; 01706 } 01707 } else 01708 break; 01709 } 01710 return 0; 01711 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 3444 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03445 { 03446 if (option_verbose > 3) 03447 ast_log(LOG_NOTICE, "I should never be called!\n"); 03448 return &ast_null_frame; 03449 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5997 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::dnsmgr, iax2_registry::expire, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, iax2_registry::refresh, iax2_registry::secret, strsep(), and iax2_registry::username.
Referenced by set_config().
05998 { 05999 struct iax2_registry *reg; 06000 char copy[256]; 06001 char *username, *hostname, *secret; 06002 char *porta; 06003 char *stringp=NULL; 06004 06005 if (!value) 06006 return -1; 06007 ast_copy_string(copy, value, sizeof(copy)); 06008 stringp=copy; 06009 username = strsep(&stringp, "@"); 06010 hostname = strsep(&stringp, "@"); 06011 if (!hostname) { 06012 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06013 return -1; 06014 } 06015 stringp=username; 06016 username = strsep(&stringp, ":"); 06017 secret = strsep(&stringp, ":"); 06018 stringp=hostname; 06019 hostname = strsep(&stringp, ":"); 06020 porta = strsep(&stringp, ":"); 06021 06022 if (porta && !atoi(porta)) { 06023 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06024 return -1; 06025 } 06026 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06027 return -1; 06028 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06029 free(reg); 06030 return -1; 06031 } 06032 ast_copy_string(reg->username, username, sizeof(reg->username)); 06033 if (secret) 06034 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06035 reg->expire = -1; 06036 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06037 reg->addr.sin_family = AF_INET; 06038 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06039 AST_LIST_LOCK(®istrations); 06040 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06041 AST_LIST_UNLOCK(®istrations); 06042 06043 return 0; 06044 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10302 of file chan_iax2.c.
References reload_config().
10303 { 10304 return reload_config(); 10305 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 9004 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(), iax2_registry::callno, create_addr_info::capability, create_addr(), find_callno_locked(), fmt, create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
09005 { 09006 int callno; 09007 int res; 09008 int fmt, native; 09009 struct sockaddr_in sin; 09010 struct ast_channel *c; 09011 struct parsed_dial_string pds; 09012 struct create_addr_info cai; 09013 char *tmpstr; 09014 09015 memset(&pds, 0, sizeof(pds)); 09016 tmpstr = ast_strdupa(data); 09017 parse_dial_string(tmpstr, &pds); 09018 09019 if (ast_strlen_zero(pds.peer)) { 09020 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09021 return NULL; 09022 } 09023 09024 memset(&cai, 0, sizeof(cai)); 09025 cai.capability = iax2_capability; 09026 09027 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09028 09029 /* Populate our address from the given */ 09030 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09031 *cause = AST_CAUSE_UNREGISTERED; 09032 return NULL; 09033 } 09034 09035 if (pds.port) 09036 sin.sin_port = htons(atoi(pds.port)); 09037 09038 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09039 if (callno < 1) { 09040 ast_log(LOG_WARNING, "Unable to create call\n"); 09041 *cause = AST_CAUSE_CONGESTION; 09042 return NULL; 09043 } 09044 09045 /* If this is a trunk, update it now */ 09046 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09047 if (ast_test_flag(&cai, IAX_TRUNK)) { 09048 int new_callno; 09049 if ((new_callno = make_trunk(callno, 1)) != -1) 09050 callno = new_callno; 09051 } 09052 iaxs[callno]->maxtime = cai.maxtime; 09053 if (cai.found) 09054 ast_string_field_set(iaxs[callno], host, pds.peer); 09055 09056 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09057 09058 ast_mutex_unlock(&iaxsl[callno]); 09059 09060 if (c) { 09061 /* Choose a format we can live with */ 09062 if (c->nativeformats & format) 09063 c->nativeformats &= format; 09064 else { 09065 native = c->nativeformats; 09066 fmt = format; 09067 res = ast_translator_best_choice(&fmt, &native); 09068 if (res < 0) { 09069 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09070 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09071 ast_hangup(c); 09072 return NULL; 09073 } 09074 c->nativeformats = native; 09075 } 09076 c->readformat = ast_best_codec(c->nativeformats); 09077 c->writeformat = c->readformat; 09078 } 09079 09080 return c; 09081 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 987 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(), realtime_peer(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00988 { 00989 int res; 00990 00991 res = ast_sched_add(con, when, callback, data); 00992 signal_condition(&sched_lock, &sched_cond); 00993 00994 return res; 00995 }
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 4286 of file chan_iax2.c.
References chan_iax2_pvt::addr, 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, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, chan_iax2_pvt::ecx, encrypt_frame(), 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, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, 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().
04287 { 04288 /* Queue a packet for delivery on a given private structure. Use "ts" for 04289 timestamp, or calculate if ts is 0. Send immediately without retransmission 04290 or delayed, with retransmission */ 04291 struct ast_iax2_full_hdr *fh; 04292 struct ast_iax2_mini_hdr *mh; 04293 struct ast_iax2_video_hdr *vh; 04294 struct { 04295 struct iax_frame fr2; 04296 unsigned char buffer[4096]; 04297 } frb; 04298 struct iax_frame *fr; 04299 int res; 04300 int sendmini=0; 04301 unsigned int lastsent; 04302 unsigned int fts; 04303 04304 frb.fr2.afdatalen = sizeof(frb.buffer); 04305 04306 if (!pvt) { 04307 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04308 return -1; 04309 } 04310 04311 lastsent = pvt->lastsent; 04312 04313 /* Calculate actual timestamp */ 04314 fts = calc_timestamp(pvt, ts, f); 04315 04316 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04317 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04318 * increment the "predicted timestamps" for voice, if we're predecting */ 04319 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04320 return 0; 04321 04322 04323 if ((ast_test_flag(pvt, IAX_TRUNK) || 04324 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04325 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04326 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04327 (f->frametype == AST_FRAME_VOICE) 04328 /* is a voice frame */ && 04329 (f->subclass == pvt->svoiceformat) 04330 /* is the same type */ ) { 04331 /* Force immediate rather than delayed transmission */ 04332 now = 1; 04333 /* Mark that mini-style frame is appropriate */ 04334 sendmini = 1; 04335 } 04336 if ( f->frametype == AST_FRAME_VIDEO ) { 04337 /* 04338 * If the lower 15 bits of the timestamp roll over, or if 04339 * the video format changed then send a full frame. 04340 * Otherwise send a mini video frame 04341 */ 04342 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04343 ((f->subclass & ~0x1) == pvt->svideoformat) 04344 ) { 04345 now = 1; 04346 sendmini = 1; 04347 } else { 04348 now = 0; 04349 sendmini = 0; 04350 } 04351 pvt->lastvsent = fts; 04352 } 04353 /* Allocate an iax_frame */ 04354 if (now) { 04355 fr = &frb.fr2; 04356 } else 04357 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)); 04358 if (!fr) { 04359 ast_log(LOG_WARNING, "Out of memory\n"); 04360 return -1; 04361 } 04362 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04363 iax_frame_wrap(fr, f); 04364 04365 fr->ts = fts; 04366 fr->callno = pvt->callno; 04367 fr->transfer = transfer; 04368 fr->final = final; 04369 if (!sendmini) { 04370 /* We need a full frame */ 04371 if (seqno > -1) 04372 fr->oseqno = seqno; 04373 else 04374 fr->oseqno = pvt->oseqno++; 04375 fr->iseqno = pvt->iseqno; 04376 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04377 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04378 fh->ts = htonl(fr->ts); 04379 fh->oseqno = fr->oseqno; 04380 if (transfer) { 04381 fh->iseqno = 0; 04382 } else 04383 fh->iseqno = fr->iseqno; 04384 /* Keep track of the last thing we've acknowledged */ 04385 if (!transfer) 04386 pvt->aseqno = fr->iseqno; 04387 fh->type = fr->af.frametype & 0xFF; 04388 if (fr->af.frametype == AST_FRAME_VIDEO) 04389 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04390 else 04391 fh->csub = compress_subclass(fr->af.subclass); 04392 if (transfer) { 04393 fr->dcallno = pvt->transfercallno; 04394 } else 04395 fr->dcallno = pvt->peercallno; 04396 fh->dcallno = htons(fr->dcallno); 04397 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04398 fr->data = fh; 04399 fr->retries = 0; 04400 /* Retry after 2x the ping time has passed */ 04401 fr->retrytime = pvt->pingtime * 2; 04402 if (fr->retrytime < MIN_RETRY_TIME) 04403 fr->retrytime = MIN_RETRY_TIME; 04404 if (fr->retrytime > MAX_RETRY_TIME) 04405 fr->retrytime = MAX_RETRY_TIME; 04406 /* Acks' don't get retried */ 04407 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04408 fr->retries = -1; 04409 else if (f->frametype == AST_FRAME_VOICE) 04410 pvt->svoiceformat = f->subclass; 04411 else if (f->frametype == AST_FRAME_VIDEO) 04412 pvt->svideoformat = f->subclass & ~0x1; 04413 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04414 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04415 if (iaxdebug) { 04416 if (fr->transfer) 04417 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04418 else 04419 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04420 } 04421 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04422 } else 04423 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04424 } 04425 04426 if (now) { 04427 res = send_packet(fr); 04428 } else 04429 res = iax2_transmit(fr); 04430 } else { 04431 if (ast_test_flag(pvt, IAX_TRUNK)) { 04432 iax2_trunk_queue(pvt, fr); 04433 res = 0; 04434 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04435 /* Video frame have no sequence number */ 04436 fr->oseqno = -1; 04437 fr->iseqno = -1; 04438 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04439 vh->zeros = 0; 04440 vh->callno = htons(0x8000 | fr->callno); 04441 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04442 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04443 fr->data = vh; 04444 fr->retries = -1; 04445 res = send_packet(fr); 04446 } else { 04447 /* Mini-frames have no sequence number */ 04448 fr->oseqno = -1; 04449 fr->iseqno = -1; 04450 /* Mini frame will do */ 04451 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04452 mh->callno = htons(fr->callno); 04453 mh->ts = htons(fr->ts & 0xFFFF); 04454 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04455 fr->data = mh; 04456 fr->retries = -1; 04457 if (pvt->transferring == TRANSFER_MEDIAPASS) 04458 fr->transfer = 1; 04459 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04460 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04461 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04462 } else 04463 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04464 } 04465 res = send_packet(fr); 04466 } 04467 } 04468 return res; 04469 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2765 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02766 { 02767 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02768 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2760 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.
02761 { 02762 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02763 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2753 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02754 { 02755 02756 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02757 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02758 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3406 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_AUDIO_MODE, AST_OPTION_FLAG_REQUEST, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_option_header::data, errno, ast_option_header::flag, free, ast_option_header::option, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03407 { 03408 struct ast_option_header *h; 03409 int res; 03410 03411 switch (option) { 03412 case AST_OPTION_TXGAIN: 03413 case AST_OPTION_RXGAIN: 03414 /* these two cannot be sent, because they require a result */ 03415 errno = ENOSYS; 03416 return -1; 03417 /* These options are sent to the other side across the network where 03418 * they will be passed to whatever channel is bridged there. Don't 03419 * do anything silly like pass an option that transmits pointers to 03420 * memory on this machine to a remote machine to use */ 03421 case AST_OPTION_TONE_VERIFY: 03422 case AST_OPTION_TDD: 03423 case AST_OPTION_RELAXDTMF: 03424 case AST_OPTION_AUDIO_MODE: 03425 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03426 return -1; 03427 03428 h->flag = AST_OPTION_FLAG_REQUEST; 03429 h->option = htons(option); 03430 memcpy(h->data, data, datalen); 03431 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03432 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03433 datalen + sizeof(*h), -1); 03434 free(h); 03435 return res; 03436 default: 03437 return -1; 03438 } 03439 03440 /* Just in case someone does a break instead of a return */ 03441 return -1; 03442 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2444 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.
02445 { 02446 struct iax2_dpcache *dp; 02447 char tmp[1024], *pc; 02448 int s; 02449 int x,y; 02450 struct timeval tv; 02451 gettimeofday(&tv, NULL); 02452 ast_mutex_lock(&dpcache_lock); 02453 dp = dpcache; 02454 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02455 while(dp) { 02456 s = dp->expiry.tv_sec - tv.tv_sec; 02457 tmp[0] = '\0'; 02458 if (dp->flags & CACHE_FLAG_EXISTS) 02459 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02460 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02461 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02462 if (dp->flags & CACHE_FLAG_CANEXIST) 02463 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02464 if (dp->flags & CACHE_FLAG_PENDING) 02465 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02466 if (dp->flags & CACHE_FLAG_TIMEOUT) 02467 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02468 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02469 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02470 if (dp->flags & CACHE_FLAG_MATCHMORE) 02471 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02472 if (dp->flags & CACHE_FLAG_UNKNOWN) 02473 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02474 /* Trim trailing pipe */ 02475 if (!ast_strlen_zero(tmp)) 02476 tmp[strlen(tmp) - 1] = '\0'; 02477 else 02478 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02479 y=0; 02480 pc = strchr(dp->peercontext, '@'); 02481 if (!pc) 02482 pc = dp->peercontext; 02483 else 02484 pc++; 02485 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02486 if (dp->waiters[x] > -1) 02487 y++; 02488 if (s > 0) 02489 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02490 else 02491 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02492 dp = dp->next; 02493 } 02494 ast_mutex_unlock(&dpcache_lock); 02495 return RESULT_SUCCESS; 02496 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4813 of file chan_iax2.c.
References iax2_registry::addr, 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.
04814 { 04815 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04816 #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" 04817 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04818 int x; 04819 int numchans = 0; 04820 04821 if (argc != 3) 04822 return RESULT_SHOWUSAGE; 04823 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04824 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04825 ast_mutex_lock(&iaxsl[x]); 04826 if (iaxs[x]) { 04827 int lag, jitter, localdelay; 04828 jb_info jbinfo; 04829 04830 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04831 jb_getinfo(iaxs[x]->jb, &jbinfo); 04832 jitter = jbinfo.jitter; 04833 localdelay = jbinfo.current - jbinfo.min; 04834 } else { 04835 jitter = -1; 04836 localdelay = 0; 04837 } 04838 lag = iaxs[x]->remote_rr.delay; 04839 ast_cli(fd, FORMAT, 04840 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04841 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04842 S_OR(iaxs[x]->username, "(None)"), 04843 iaxs[x]->callno, iaxs[x]->peercallno, 04844 iaxs[x]->oseqno, iaxs[x]->iseqno, 04845 lag, 04846 jitter, 04847 localdelay, 04848 ast_getformatname(iaxs[x]->voiceformat) ); 04849 numchans++; 04850 } 04851 ast_mutex_unlock(&iaxsl[x]); 04852 } 04853 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04854 return RESULT_SUCCESS; 04855 #undef FORMAT 04856 #undef FORMAT2 04857 #undef FORMATB 04858 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4724 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.
04725 { 04726 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04727 #if !defined(__FreeBSD__) 04728 #define FORMAT "%-15.15s %-15d %-15d\n" 04729 #else /* __FreeBSD__ */ 04730 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04731 #endif /* __FreeBSD__ */ 04732 struct iax_firmware *cur; 04733 if ((argc != 3) && (argc != 4)) 04734 return RESULT_SHOWUSAGE; 04735 ast_mutex_lock(&waresl.lock); 04736 04737 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04738 for (cur = waresl.wares;cur;cur = cur->next) { 04739 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04740 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04741 (int)ntohl(cur->fwh->datalen)); 04742 } 04743 ast_mutex_unlock(&waresl.lock); 04744 return RESULT_SUCCESS; 04745 #undef FORMAT 04746 #undef FORMAT2 04747 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4936 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04937 { 04938 int numchans = 0; 04939 if (argc != 3) 04940 return RESULT_SHOWUSAGE; 04941 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04942 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04943 numchans = ast_cli_netstats(NULL, fd, 1); 04944 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04945 return RESULT_SUCCESS; 04946 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2334 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.
02335 { 02336 char status[30]; 02337 char cbuf[256]; 02338 struct iax2_peer *peer; 02339 char codec_buf[512]; 02340 int x = 0, codec = 0, load_realtime = 0; 02341 02342 if (argc < 4) 02343 return RESULT_SHOWUSAGE; 02344 02345 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02346 02347 peer = find_peer(argv[3], load_realtime); 02348 if (peer) { 02349 ast_cli(fd,"\n\n"); 02350 ast_cli(fd, " * Name : %s\n", peer->name); 02351 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02352 ast_cli(fd, " Context : %s\n", peer->context); 02353 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02354 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02355 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02356 ast_cli(fd, " Expire : %d\n", peer->expire); 02357 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02358 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)); 02359 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02360 ast_cli(fd, " Username : %s\n", peer->username); 02361 ast_cli(fd, " Codecs : "); 02362 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02363 ast_cli(fd, "%s\n", codec_buf); 02364 02365 ast_cli(fd, " Codec Order : ("); 02366 for(x = 0; x < 32 ; x++) { 02367 codec = ast_codec_pref_index(&peer->prefs,x); 02368 if(!codec) 02369 break; 02370 ast_cli(fd, "%s", ast_getformatname(codec)); 02371 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02372 ast_cli(fd, "|"); 02373 } 02374 02375 if (!x) 02376 ast_cli(fd, "none"); 02377 ast_cli(fd, ")\n"); 02378 02379 ast_cli(fd, " Status : "); 02380 peer_status(peer, status, sizeof(status)); 02381 ast_cli(fd, "%s\n",status); 02382 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02383 ast_cli(fd,"\n"); 02384 peer_unref(peer); 02385 } else { 02386 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02387 ast_cli(fd,"\n"); 02388 } 02389 02390 return RESULT_SUCCESS; 02391 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4713 of file chan_iax2.c.
References __iax2_show_peers().
04714 { 04715 return __iax2_show_peers(0, fd, NULL, argc, argv); 04716 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4785 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.
04786 { 04787 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04788 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04789 struct iax2_registry *reg = NULL; 04790 04791 char host[80]; 04792 char perceived[80]; 04793 if (argc != 3) 04794 return RESULT_SHOWUSAGE; 04795 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04796 AST_LIST_LOCK(®istrations); 04797 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04798 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04799 if (reg->us.sin_addr.s_addr) 04800 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04801 else 04802 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04803 ast_cli(fd, FORMAT, host, 04804 (reg->dnsmgr) ? "Y" : "N", 04805 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04806 } 04807 AST_LIST_UNLOCK(®istrations); 04808 return RESULT_SUCCESS; 04809 #undef FORMAT 04810 #undef FORMAT2 04811 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2418 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.
02419 { 02420 struct iax_frame *cur; 02421 int cnt = 0, dead=0, final=0; 02422 02423 if (argc != 3) 02424 return RESULT_SHOWUSAGE; 02425 02426 AST_LIST_LOCK(&iaxq.queue); 02427 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02428 if (cur->retries < 0) 02429 dead++; 02430 if (cur->final) 02431 final++; 02432 cnt++; 02433 } 02434 AST_LIST_UNLOCK(&iaxq.queue); 02435 02436 ast_cli(fd, " IAX Statistics\n"); 02437 ast_cli(fd, "---------------------\n"); 02438 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02439 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02440 02441 return RESULT_SUCCESS; 02442 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4654 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, and thread.
04655 { 04656 struct iax2_thread *thread = NULL; 04657 time_t t; 04658 int threadcount = 0, dynamiccount = 0; 04659 char type; 04660 04661 if (argc != 3) 04662 return RESULT_SHOWUSAGE; 04663 04664 ast_cli(fd, "IAX2 Thread Information\n"); 04665 time(&t); 04666 ast_cli(fd, "Idle Threads:\n"); 04667 AST_LIST_LOCK(&idle_list); 04668 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04669 #ifdef DEBUG_SCHED_MULTITHREAD 04670 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04671 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04672 #else 04673 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04674 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04675 #endif 04676 threadcount++; 04677 } 04678 AST_LIST_UNLOCK(&idle_list); 04679 ast_cli(fd, "Active Threads:\n"); 04680 AST_LIST_LOCK(&active_list); 04681 AST_LIST_TRAVERSE(&active_list, thread, list) { 04682 if (thread->type == IAX_TYPE_DYNAMIC) 04683 type = 'D'; 04684 else 04685 type = 'P'; 04686 #ifdef DEBUG_SCHED_MULTITHREAD 04687 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04688 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04689 #else 04690 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04691 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04692 #endif 04693 threadcount++; 04694 } 04695 AST_LIST_UNLOCK(&active_list); 04696 ast_cli(fd, "Dynamic Threads:\n"); 04697 AST_LIST_LOCK(&dynamic_list); 04698 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04699 #ifdef DEBUG_SCHED_MULTITHREAD 04700 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04701 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04702 #else 04703 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04704 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04705 #endif 04706 dynamiccount++; 04707 } 04708 AST_LIST_UNLOCK(&dynamic_list); 04709 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04710 return RESULT_SUCCESS; 04711 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4471 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.
04472 { 04473 regex_t regexbuf; 04474 int havepattern = 0; 04475 04476 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04477 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04478 04479 struct iax2_user *user = NULL; 04480 char auth[90]; 04481 char *pstr = ""; 04482 struct ao2_iterator i; 04483 04484 switch (argc) { 04485 case 5: 04486 if (!strcasecmp(argv[3], "like")) { 04487 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04488 return RESULT_SHOWUSAGE; 04489 havepattern = 1; 04490 } else 04491 return RESULT_SHOWUSAGE; 04492 case 3: 04493 break; 04494 default: 04495 return RESULT_SHOWUSAGE; 04496 } 04497 04498 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04499 i = ao2_iterator_init(users, 0); 04500 for (user = ao2_iterator_next(&i); user; 04501 user_unref(user), user = ao2_iterator_next(&i)) { 04502 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04503 continue; 04504 04505 if (!ast_strlen_zero(user->secret)) { 04506 ast_copy_string(auth,user->secret,sizeof(auth)); 04507 } else if (!ast_strlen_zero(user->inkeys)) { 04508 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04509 } else 04510 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04511 04512 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04513 pstr = "REQ Only"; 04514 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04515 pstr = "Disabled"; 04516 else 04517 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04518 04519 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04520 user->contexts ? user->contexts->context : context, 04521 user->ha ? "Yes" : "No", pstr); 04522 } 04523 04524 if (havepattern) 04525 regfree(®exbuf); 04526 04527 return RESULT_SUCCESS; 04528 #undef FORMAT 04529 #undef FORMAT2 04530 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3451 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_random(), iax_ie_data::buf, 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, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
03452 { 03453 int res; 03454 struct iax_ie_data ied0; 03455 struct iax_ie_data ied1; 03456 unsigned int transferid = (unsigned int)ast_random(); 03457 memset(&ied0, 0, sizeof(ied0)); 03458 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03459 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03460 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03461 03462 memset(&ied1, 0, sizeof(ied1)); 03463 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03464 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03465 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03466 03467 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03468 if (res) 03469 return -1; 03470 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03471 if (res) 03472 return -1; 03473 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03474 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03475 return 0; 03476 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2265 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02266 { 02267 if (argc != 4) 02268 return RESULT_SHOWUSAGE; 02269 02270 test_losspct = atoi(argv[3]); 02271 02272 return RESULT_SUCCESS; 02273 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3697 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, LOG_DEBUG, option_debug, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03698 { 03699 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03700 struct iax_ie_data ied; 03701 char tmp[256], *context; 03702 ast_copy_string(tmp, dest, sizeof(tmp)); 03703 context = strchr(tmp, '@'); 03704 if (context) { 03705 *context = '\0'; 03706 context++; 03707 } 03708 memset(&ied, 0, sizeof(ied)); 03709 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03710 if (context) 03711 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03712 if (option_debug) 03713 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03714 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03715 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2724 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().
02725 { 02726 /* Lock the queue and place this packet at the end */ 02727 /* By setting this to 0, the network thread will send it for us, and 02728 queue retransmission if necessary */ 02729 fr->sentyet = 0; 02730 AST_LIST_LOCK(&iaxq.queue); 02731 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02732 iaxq.count++; 02733 AST_LIST_UNLOCK(&iaxq.queue); 02734 /* Wake up the network and scheduler thread */ 02735 if (netthreadid != AST_PTHREADT_NULL) 02736 pthread_kill(netthreadid, SIGURG); 02737 signal_condition(&sched_lock, &sched_cond); 02738 return 0; 02739 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6579 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06580 { 06581 /* Drop when trunk is about 5 seconds idle */ 06582 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06583 return 1; 06584 return 0; 06585 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4060 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, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_DEBUG, 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().
04061 { 04062 struct ast_frame *f; 04063 struct iax2_trunk_peer *tpeer; 04064 void *tmp, *ptr; 04065 struct ast_iax2_meta_trunk_entry *met; 04066 struct ast_iax2_meta_trunk_mini *mtm; 04067 04068 f = &fr->af; 04069 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04070 if (tpeer) { 04071 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04072 /* Need to reallocate space */ 04073 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04074 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04075 ast_mutex_unlock(&tpeer->lock); 04076 return -1; 04077 } 04078 04079 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04080 tpeer->trunkdata = tmp; 04081 if (option_debug) 04082 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); 04083 } else { 04084 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)); 04085 ast_mutex_unlock(&tpeer->lock); 04086 return -1; 04087 } 04088 } 04089 04090 /* Append to meta frame */ 04091 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04092 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04093 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04094 mtm->len = htons(f->datalen); 04095 mtm->mini.callno = htons(pvt->callno); 04096 mtm->mini.ts = htons(0xffff & fr->ts); 04097 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04098 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04099 } else { 04100 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04101 /* Store call number and length in meta header */ 04102 met->callno = htons(pvt->callno); 04103 met->len = htons(f->datalen); 04104 /* Advance pointers/decrease length past trunk entry header */ 04105 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04106 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04107 } 04108 /* Copy actual trunk data */ 04109 memcpy(ptr, f->data, f->datalen); 04110 tpeer->trunkdatalen += f->datalen; 04111 04112 tpeer->calls++; 04113 ast_mutex_unlock(&tpeer->lock); 04114 } 04115 return 0; 04116 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6496 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06497 { 06498 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06499 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 5003 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(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, LOG_DEBUG, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05004 { 05005 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05006 int res = -1; 05007 ast_mutex_lock(&iaxsl[callno]); 05008 if (iaxs[callno]) { 05009 /* If there's an outstanding error, return failure now */ 05010 if (!iaxs[callno]->error) { 05011 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05012 res = 0; 05013 /* Don't waste bandwidth sending null frames */ 05014 else if (f->frametype == AST_FRAME_NULL) 05015 res = 0; 05016 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05017 res = 0; 05018 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05019 res = 0; 05020 else 05021 /* Simple, just queue for transmission */ 05022 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05023 } else { 05024 if (option_debug) 05025 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05026 } 05027 } 05028 /* If it's already gone, just return */ 05029 ast_mutex_unlock(&iaxsl[callno]); 05030 return res; 05031 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1899 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().
01900 { 01901 int res = 0; 01902 struct iax_firmware *cur; 01903 if (!ast_strlen_zero(dev)) { 01904 ast_mutex_lock(&waresl.lock); 01905 cur = waresl.wares; 01906 while(cur) { 01907 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01908 res = ntohs(cur->fwh->version); 01909 break; 01910 } 01911 cur = cur->next; 01912 } 01913 ast_mutex_unlock(&waresl.lock); 01914 } 01915 return res; 01916 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 765 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00766 { 00767 if (iaxdebug) 00768 ast_verbose("%s", data); 00769 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 771 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00772 { 00773 ast_log(LOG_WARNING, "%s", data); 00774 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1918 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().
01919 { 01920 int res = -1; 01921 unsigned int bs = desc & 0xff; 01922 unsigned int start = (desc >> 8) & 0xffffff; 01923 unsigned int bytes; 01924 struct iax_firmware *cur; 01925 if (!ast_strlen_zero((char *)dev) && bs) { 01926 start *= bs; 01927 ast_mutex_lock(&waresl.lock); 01928 cur = waresl.wares; 01929 while(cur) { 01930 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01931 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01932 if (start < ntohl(cur->fwh->datalen)) { 01933 bytes = ntohl(cur->fwh->datalen) - start; 01934 if (bytes > bs) 01935 bytes = bs; 01936 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01937 } else { 01938 bytes = 0; 01939 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01940 } 01941 if (bytes == bs) 01942 res = 0; 01943 else 01944 res = 1; 01945 break; 01946 } 01947 cur = cur->next; 01948 } 01949 ast_mutex_unlock(&waresl.lock); 01950 } 01951 return res; 01952 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6767 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, iax_dual::chan1, iax_dual::chan2, 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().
06768 { 06769 struct iax_dual *d; 06770 struct ast_channel *chan1m, *chan2m; 06771 pthread_t th; 06772 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06773 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06774 if (chan2m && chan1m) { 06775 /* Make formats okay */ 06776 chan1m->readformat = chan1->readformat; 06777 chan1m->writeformat = chan1->writeformat; 06778 ast_channel_masquerade(chan1m, chan1); 06779 /* Setup the extensions and such */ 06780 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06781 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06782 chan1m->priority = chan1->priority; 06783 06784 /* We make a clone of the peer channel too, so we can play 06785 back the announcement */ 06786 /* Make formats okay */ 06787 chan2m->readformat = chan2->readformat; 06788 chan2m->writeformat = chan2->writeformat; 06789 ast_channel_masquerade(chan2m, chan2); 06790 /* Setup the extensions and such */ 06791 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06792 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06793 chan2m->priority = chan2->priority; 06794 if (ast_do_masquerade(chan2m)) { 06795 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06796 ast_hangup(chan2m); 06797 return -1; 06798 } 06799 } else { 06800 if (chan1m) 06801 ast_hangup(chan1m); 06802 if (chan2m) 06803 ast_hangup(chan2m); 06804 return -1; 06805 } 06806 if ((d = ast_calloc(1, sizeof(*d)))) { 06807 pthread_attr_t attr; 06808 06809 pthread_attr_init(&attr); 06810 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06811 06812 d->chan1 = chan1m; 06813 d->chan2 = chan2m; 06814 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06815 pthread_attr_destroy(&attr); 06816 return 0; 06817 } 06818 pthread_attr_destroy(&attr); 06819 free(d); 06820 } 06821 return -1; 06822 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6747 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().
06748 { 06749 struct ast_channel *chan1, *chan2; 06750 struct iax_dual *d; 06751 struct ast_frame *f; 06752 int ext; 06753 int res; 06754 d = stuff; 06755 chan1 = d->chan1; 06756 chan2 = d->chan2; 06757 free(d); 06758 f = ast_read(chan1); 06759 if (f) 06760 ast_frfree(f); 06761 res = ast_park_call(chan1, chan2, 0, &ext); 06762 ast_hangup(chan2); 06763 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06764 return NULL; 06765 }
Definition at line 1413 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().
01414 { 01415 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01416 if (new) { 01417 size_t afdatalen = new->afdatalen; 01418 memcpy(new, fr, sizeof(*new)); 01419 iax_frame_wrap(new, &fr->af); 01420 new->afdatalen = afdatalen; 01421 new->data = NULL; 01422 new->datalen = 0; 01423 new->direction = DIRECTION_INGRESS; 01424 new->retrans = -1; 01425 } 01426 return new; 01427 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 895 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
00896 { 00897 if (thread->type == IAX_TYPE_DYNAMIC) { 00898 AST_LIST_LOCK(&dynamic_list); 00899 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00900 AST_LIST_UNLOCK(&dynamic_list); 00901 } else { 00902 AST_LIST_LOCK(&idle_list); 00903 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00904 AST_LIST_UNLOCK(&idle_list); 00905 } 00906 00907 return; 00908 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 800 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00801 { 00802 va_list args; 00803 char buf[1024]; 00804 00805 va_start(args, fmt); 00806 vsnprintf(buf, 1024, fmt, args); 00807 va_end(args); 00808 00809 ast_verbose(buf); 00810 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 776 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00777 { 00778 va_list args; 00779 char buf[1024]; 00780 00781 va_start(args, fmt); 00782 vsnprintf(buf, 1024, fmt, args); 00783 va_end(args); 00784 00785 ast_log(LOG_ERROR, buf); 00786 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 788 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00789 { 00790 va_list args; 00791 char buf[1024]; 00792 00793 va_start(args, fmt); 00794 vsnprintf(buf, 1024, fmt, args); 00795 va_end(args); 00796 00797 ast_log(LOG_WARNING, buf); 00798 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11138 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_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, option_verbose, papp, pdescrip, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, psyn, pvt_cmp_cb(), pvt_hash_cb(), reload_firmware(), sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
11139 { 11140 char *config = "iax.conf"; 11141 int res = 0; 11142 int x; 11143 struct iax2_registry *reg = NULL; 11144 11145 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11146 if (!peers) 11147 return AST_MODULE_LOAD_FAILURE; 11148 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11149 if (!users) { 11150 ao2_ref(peers, -1); 11151 return AST_MODULE_LOAD_FAILURE; 11152 } 11153 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11154 if (!iax_peercallno_pvts) { 11155 ao2_ref(peers, -1); 11156 ao2_ref(users, -1); 11157 return AST_MODULE_LOAD_FAILURE; 11158 } 11159 11160 ast_custom_function_register(&iaxpeer_function); 11161 11162 iax_set_output(iax_debug_output); 11163 iax_set_error(iax_error_output); 11164 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11165 11166 #ifdef HAVE_ZAPTEL 11167 #ifdef ZT_TIMERACK 11168 timingfd = open("/dev/zap/timer", O_RDWR); 11169 if (timingfd < 0) 11170 #endif 11171 timingfd = open("/dev/zap/pseudo", O_RDWR); 11172 if (timingfd < 0) 11173 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11174 #endif 11175 11176 memset(iaxs, 0, sizeof(iaxs)); 11177 11178 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11179 ast_mutex_init(&iaxsl[x]); 11180 } 11181 11182 ast_cond_init(&sched_cond, NULL); 11183 11184 io = io_context_create(); 11185 sched = sched_context_create(); 11186 11187 if (!io || !sched) { 11188 ast_log(LOG_ERROR, "Out of memory\n"); 11189 return -1; 11190 } 11191 11192 netsock = ast_netsock_list_alloc(); 11193 if (!netsock) { 11194 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11195 return -1; 11196 } 11197 ast_netsock_init(netsock); 11198 11199 outsock = ast_netsock_list_alloc(); 11200 if (!outsock) { 11201 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11202 return -1; 11203 } 11204 ast_netsock_init(outsock); 11205 11206 ast_mutex_init(&waresl.lock); 11207 11208 AST_LIST_HEAD_INIT(&iaxq.queue); 11209 11210 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11211 11212 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11213 11214 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11215 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11216 11217 if(set_config(config, 0) == -1) 11218 return AST_MODULE_LOAD_DECLINE; 11219 11220 if (ast_channel_register(&iax2_tech)) { 11221 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11222 __unload_module(); 11223 return -1; 11224 } 11225 11226 if (ast_register_switch(&iax2_switch)) 11227 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11228 11229 res = start_network_thread(); 11230 if (!res) { 11231 if (option_verbose > 1) 11232 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11233 } else { 11234 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11235 ast_netsock_release(netsock); 11236 ast_netsock_release(outsock); 11237 } 11238 11239 AST_LIST_LOCK(®istrations); 11240 AST_LIST_TRAVERSE(®istrations, reg, entry) 11241 iax2_do_register(reg); 11242 AST_LIST_UNLOCK(®istrations); 11243 11244 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11245 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11246 11247 reload_firmware(0); 11248 iax_provision_reload(); 11249 return res; 11250 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3478 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03479 { 03480 ast_mutex_lock(&iaxsl[callno0]); 03481 while (ast_mutex_trylock(&iaxsl[callno1])) { 03482 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03483 } 03484 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1467 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, chan_iax2_pvt::callno, iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01468 { 01469 int x; 01470 int res= 0; 01471 struct timeval now; 01472 if (iaxs[callno]->oseqno) { 01473 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01474 return -1; 01475 } 01476 if (callno & TRUNK_CALL_START) { 01477 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01478 return -1; 01479 } 01480 gettimeofday(&now, NULL); 01481 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01482 ast_mutex_lock(&iaxsl[x]); 01483 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01484 iaxs[x] = iaxs[callno]; 01485 iaxs[x]->callno = x; 01486 iaxs[callno] = NULL; 01487 /* Update the two timers that should have been started */ 01488 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01489 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01490 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01491 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01492 if (locked) 01493 ast_mutex_unlock(&iaxsl[callno]); 01494 res = x; 01495 if (!locked) 01496 ast_mutex_unlock(&iaxsl[x]); 01497 break; 01498 } 01499 ast_mutex_unlock(&iaxsl[x]); 01500 } 01501 if (x >= ARRAY_LEN(iaxs) - 1) { 01502 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01503 return -1; 01504 } 01505 if (option_debug) 01506 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01507 /* We move this call from a non-trunked to a trunked call */ 01508 update_max_trunk(); 01509 update_max_nontrunk(); 01510 return res; 01511 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4717 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
04718 { 04719 ast_cli_netstats(s, -1, 0); 04720 astman_append(s, "\r\n"); 04721 return RESULT_SUCCESS; 04722 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4750 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by load_module().
04751 { 04752 char *a[] = { "iax2", "show", "users" }; 04753 int ret; 04754 const char *id = astman_get_header(m,"ActionID"); 04755 04756 if (!ast_strlen_zero(id)) 04757 astman_append(s, "ActionID: %s\r\n",id); 04758 ret = __iax2_show_peers(1, -1, s, 3, a ); 04759 astman_append(s, "\r\n\r\n" ); 04760 return ret; 04761 } /* /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 1433 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, 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().
01434 { 01435 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01436 (cur->addr.sin_port == sin->sin_port)) { 01437 /* This is the main host */ 01438 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01439 (check_dcallno ? dcallno == cur->callno : 1) ) { 01440 /* That's us. Be sure we keep track of the peer call number */ 01441 return 1; 01442 } 01443 } 01444 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01445 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01446 /* We're transferring */ 01447 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01448 return 1; 01449 } 01450 return 0; 01451 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4124 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04125 { 04126 #if 0 04127 /* Debug with "fake encryption" */ 04128 int x; 04129 if (len % 16) 04130 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04131 for (x=0;x<len;x++) 04132 dst[x] = src[x] ^ 0xff; 04133 #else 04134 unsigned char lastblock[16] = { 0 }; 04135 int x; 04136 while(len > 0) { 04137 aes_decrypt(src, dst, dcx); 04138 for (x=0;x<16;x++) 04139 dst[x] ^= lastblock[x]; 04140 memcpy(lastblock, src, sizeof(lastblock)); 04141 dst += 16; 04142 src += 16; 04143 len -= 16; 04144 } 04145 #endif 04146 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4148 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04149 { 04150 #if 0 04151 /* Debug with "fake encryption" */ 04152 int x; 04153 if (len % 16) 04154 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04155 for (x=0;x<len;x++) 04156 dst[x] = src[x] ^ 0xff; 04157 #else 04158 unsigned char curblock[16] = { 0 }; 04159 int x; 04160 while(len > 0) { 04161 for (x=0;x<16;x++) 04162 curblock[x] ^= src[x]; 04163 aes_encrypt(curblock, dst, ecx); 04164 memcpy(curblock, dst, sizeof(curblock)); 04165 dst += 16; 04166 src += 16; 04167 len -= 16; 04168 } 04169 #endif 04170 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5340 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05341 { 05342 /* Select exactly one common encryption if there are any */ 05343 p->encmethods &= enc; 05344 if (p->encmethods) { 05345 if (p->encmethods & IAX_ENCRYPT_AES128) 05346 p->encmethods = IAX_ENCRYPT_AES128; 05347 else 05348 p->encmethods = 0; 05349 } 05350 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9111 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(), iax_frame::callno, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, LOG_DEBUG, option_debug, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, and timing_read().
Referenced by start_network_thread().
09112 { 09113 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09114 from the network, and queue them for delivery to the channels */ 09115 int res, count, wakeup; 09116 struct iax_frame *f; 09117 09118 if (timingfd > -1) 09119 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09120 09121 for(;;) { 09122 pthread_testcancel(); 09123 09124 /* Go through the queue, sending messages which have not yet been 09125 sent, and scheduling retransmissions if appropriate */ 09126 AST_LIST_LOCK(&iaxq.queue); 09127 count = 0; 09128 wakeup = -1; 09129 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09130 if (f->sentyet) 09131 continue; 09132 09133 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09134 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09135 wakeup = 1; 09136 continue; 09137 } 09138 09139 f->sentyet++; 09140 09141 if (iaxs[f->callno]) { 09142 send_packet(f); 09143 count++; 09144 } 09145 09146 ast_mutex_unlock(&iaxsl[f->callno]); 09147 09148 if (f->retries < 0) { 09149 /* This is not supposed to be retransmitted */ 09150 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09151 iaxq.count--; 09152 /* Free the iax frame */ 09153 iax_frame_free(f); 09154 } else { 09155 /* We need reliable delivery. Schedule a retransmission */ 09156 f->retries++; 09157 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09158 } 09159 } 09160 AST_LIST_TRAVERSE_SAFE_END 09161 AST_LIST_UNLOCK(&iaxq.queue); 09162 09163 pthread_testcancel(); 09164 09165 if (option_debug && count >= 20) 09166 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09167 09168 /* Now do the IO, and run scheduled tasks */ 09169 res = ast_io_wait(io, wakeup); 09170 if (res >= 0) { 09171 if (option_debug && res >= 20) 09172 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09173 } 09174 } 09175 return NULL; 09176 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1374 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, exten, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno.
Referenced by __find_callno().
01375 { 01376 struct chan_iax2_pvt *tmp; 01377 jb_conf jbconf; 01378 01379 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01380 return NULL; 01381 } 01382 01383 if (ast_string_field_init(tmp, 32)) { 01384 ao2_ref(tmp, -1); 01385 tmp = NULL; 01386 return NULL; 01387 } 01388 01389 tmp->prefs = prefs; 01390 tmp->callno = 0; 01391 tmp->peercallno = 0; 01392 tmp->transfercallno = 0; 01393 tmp->bridgecallno = 0; 01394 tmp->pingid = -1; 01395 tmp->lagid = -1; 01396 tmp->autoid = -1; 01397 tmp->authid = -1; 01398 tmp->initid = -1; 01399 01400 ast_string_field_set(tmp,exten, "s"); 01401 ast_string_field_set(tmp,host, host); 01402 01403 tmp->jb = jb_new(); 01404 tmp->jbid = -1; 01405 jbconf.max_jitterbuf = maxjitterbuffer; 01406 jbconf.resync_threshold = resyncthreshold; 01407 jbconf.max_contig_interp = maxjitterinterps; 01408 jb_setconf(tmp->jb,&jbconf); 01409 01410 return tmp; 01411 }
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 3184 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().
03185 { 03186 if (ast_strlen_zero(data)) 03187 return; 03188 03189 pds->peer = strsep(&data, "/"); 03190 pds->exten = strsep(&data, "/"); 03191 pds->options = data; 03192 03193 if (pds->exten) { 03194 data = pds->exten; 03195 pds->exten = strsep(&data, "@"); 03196 pds->context = data; 03197 } 03198 03199 if (strchr(pds->peer, '@')) { 03200 data = pds->peer; 03201 pds->username = strsep(&data, "@"); 03202 pds->peer = data; 03203 } 03204 03205 if (pds->username) { 03206 data = pds->username; 03207 pds->username = strsep(&data, ":"); 03208 pds->password = data; 03209 } 03210 03211 data = pds->peer; 03212 pds->peer = strsep(&data, ":"); 03213 pds->port = data; 03214 03215 /* check for a key name wrapped in [] in the secret position, if found, 03216 move it to the key field instead 03217 */ 03218 if (pds->password && (pds->password[0] == '[')) { 03219 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03220 pds->password = NULL; 03221 } 03222 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1112 of file chan_iax2.c.
Referenced by load_module().
01113 { 01114 struct iax2_peer *peer = obj, *peer2 = arg; 01115 01116 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01117 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9809 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09810 { 09811 struct iax2_peer *peer = obj; 09812 09813 ast_set_flag(peer, IAX_DELME); 09814 09815 return 0; 09816 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9334 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().
09335 { 09336 struct iax2_peer *peer = obj; 09337 09338 ast_free_ha(peer->ha); 09339 09340 if (peer->callno > 0) { 09341 ast_mutex_lock(&iaxsl[peer->callno]); 09342 iax2_destroy(peer->callno); 09343 ast_mutex_unlock(&iaxsl[peer->callno]); 09344 } 09345 09346 register_peer_exten(peer, 0); 09347 09348 if (peer->dnsmgr) 09349 ast_dnsmgr_release(peer->dnsmgr); 09350 09351 ast_string_field_free_memory(peer); 09352 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1102 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01103 { 01104 const struct iax2_peer *peer = obj; 01105 01106 return ast_str_hash(peer->name); 01107 }
Definition at line 1159 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01160 { 01161 ao2_ref(peer, +1); 01162 return peer; 01163 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11109 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11110 { 11111 struct iax2_peer *peer = obj; 11112 11113 if (peer->sockfd < 0) 11114 peer->sockfd = defaultsockfd; 11115 11116 return 0; 11117 }
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 9261 of file chan_iax2.c.
References iax2_registry::addr, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_DEBUG, LOG_WARNING, option_debug, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
09262 { 09263 struct sockaddr_in sin; 09264 int nonlocal = 1; 09265 int port = IAX_DEFAULT_PORTNO; 09266 int sockfd = defaultsockfd; 09267 char *tmp; 09268 char *addr; 09269 char *portstr; 09270 09271 if (!(tmp = ast_strdupa(srcaddr))) 09272 return -1; 09273 09274 addr = strsep(&tmp, ":"); 09275 portstr = tmp; 09276 09277 if (portstr) { 09278 port = atoi(portstr); 09279 if (port < 1) 09280 port = IAX_DEFAULT_PORTNO; 09281 } 09282 09283 if (!ast_get_ip(&sin, addr)) { 09284 struct ast_netsock *sock; 09285 int res; 09286 09287 sin.sin_port = 0; 09288 sin.sin_family = AF_INET; 09289 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09290 if (res == 0) { 09291 /* ip address valid. */ 09292 sin.sin_port = htons(port); 09293 if (!(sock = ast_netsock_find(netsock, &sin))) 09294 sock = ast_netsock_find(outsock, &sin); 09295 if (sock) { 09296 sockfd = ast_netsock_sockfd(sock); 09297 nonlocal = 0; 09298 } else { 09299 unsigned int orig_saddr = sin.sin_addr.s_addr; 09300 /* INADDR_ANY matches anyway! */ 09301 sin.sin_addr.s_addr = INADDR_ANY; 09302 if (ast_netsock_find(netsock, &sin)) { 09303 sin.sin_addr.s_addr = orig_saddr; 09304 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09305 if (sock) { 09306 sockfd = ast_netsock_sockfd(sock); 09307 ast_netsock_unref(sock); 09308 nonlocal = 0; 09309 } else { 09310 nonlocal = 2; 09311 } 09312 } 09313 } 09314 } 09315 } 09316 09317 peer->sockfd = sockfd; 09318 09319 if (nonlocal == 1) { 09320 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09321 srcaddr, peer->name); 09322 return -1; 09323 } else if (nonlocal == 2) { 09324 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09325 srcaddr, peer->name); 09326 return -1; 09327 } else { 09328 if (option_debug) 09329 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09330 return 0; 09331 } 09332 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2311 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().
02312 { 02313 int res = 0; 02314 if (peer->maxms) { 02315 if (peer->lastms < 0) { 02316 ast_copy_string(status, "UNREACHABLE", statuslen); 02317 } else if (peer->lastms > peer->maxms) { 02318 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02319 res = 1; 02320 } else if (peer->lastms) { 02321 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02322 res = 1; 02323 } else { 02324 ast_copy_string(status, "UNKNOWN", statuslen); 02325 } 02326 } else { 02327 ast_copy_string(status, "Unmonitored", statuslen); 02328 res = -1; 02329 } 02330 return res; 02331 }
Definition at line 1165 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(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01166 { 01167 ao2_ref(peer, -1); 01168 return NULL; 01169 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10270 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10271 { 10272 struct ao2_iterator i; 10273 struct iax2_peer *peer; 10274 10275 i = ao2_iterator_init(peers, 0); 10276 while ((peer = ao2_iterator_next(&i))) { 10277 iax2_poke_peer(peer, 0); 10278 peer_unref(peer); 10279 } 10280 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9867 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09868 { 09869 struct iax2_peer *peer; 09870 struct ao2_iterator i; 09871 09872 i = ao2_iterator_init(peers, 0); 09873 while ((peer = ao2_iterator_next(&i))) { 09874 if (ast_test_flag(peer, IAX_DELME)) 09875 unlink_peer(peer); 09876 peer_unref(peer); 09877 } 09878 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9853 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().
09854 { 09855 struct iax2_user *user; 09856 struct ao2_iterator i; 09857 09858 i = ao2_iterator_init(users, 0); 09859 while ((user = ao2_iterator_next(&i))) { 09860 if (ast_test_flag(user, IAX_DELME)) 09861 ao2_unlink(users, user); 09862 user_unref(user); 09863 } 09864 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11126 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11127 { 11128 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11129 11130 /* The frames_received field is used to hold whether we're matching 11131 * against a full frame or not ... */ 11132 11133 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11134 pvt2->frames_received) ? CMP_MATCH : 0; 11135 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1335 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().
01336 { 01337 struct chan_iax2_pvt *pvt = obj; 01338 struct iax_frame *cur = NULL; 01339 01340 iax2_destroy_helper(pvt); 01341 01342 /* Already gone */ 01343 ast_set_flag(pvt, IAX_ALREADYGONE); 01344 01345 AST_LIST_LOCK(&iaxq.queue); 01346 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01347 /* Cancel any pending transmissions */ 01348 if (cur->callno == pvt->callno) { 01349 cur->retries = -1; 01350 } 01351 } 01352 AST_LIST_UNLOCK(&iaxq.queue); 01353 01354 if (pvt->reg) { 01355 pvt->reg->callno = 0; 01356 } 01357 01358 if (!pvt->owner) { 01359 jb_frame frame; 01360 if (pvt->vars) { 01361 ast_variables_destroy(pvt->vars); 01362 pvt->vars = NULL; 01363 } 01364 01365 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01366 iax2_frame_free(frame.data); 01367 } 01368 01369 jb_destroy(pvt->jb); 01370 ast_string_field_free_memory(pvt); 01371 } 01372 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11119 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11120 { 11121 const struct chan_iax2_pvt *pvt = obj; 11122 11123 return pvt->peercallno; 11124 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5322 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, LOG_DEBUG, 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().
05323 { 05324 struct ast_iax2_full_hdr fh; 05325 fh.scallno = htons(src | IAX_FLAG_FULL); 05326 fh.dcallno = htons(dst); 05327 fh.ts = 0; 05328 fh.oseqno = 0; 05329 fh.iseqno = 0; 05330 fh.type = AST_FRAME_IAX; 05331 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05332 if (iaxdebug) 05333 iax_showframe(NULL, &fh, 0, sin, 0); 05334 if (option_debug) 05335 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05336 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05337 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05338 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2786 of file chan_iax2.c.
References iax2_peer::addr, ast_copy_flags, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_DEBUG, ast_variable::name, ast_variable::next, option_debug, peer_ref(), peer_unref(), peers, realtime_update_peer(), reg_source_db(), ast_variable::value, and var.
02787 { 02788 struct ast_variable *var = NULL; 02789 struct ast_variable *tmp; 02790 struct iax2_peer *peer=NULL; 02791 time_t regseconds = 0, nowtime; 02792 int dynamic=0; 02793 02794 if (peername) { 02795 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02796 if (!var && sin) 02797 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02798 } else if (sin) { 02799 char porta[25]; 02800 sprintf(porta, "%d", ntohs(sin->sin_port)); 02801 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02802 if (var) { 02803 /* We'll need the peer name in order to build the structure! */ 02804 for (tmp = var; tmp; tmp = tmp->next) { 02805 if (!strcasecmp(tmp->name, "name")) 02806 peername = tmp->value; 02807 } 02808 } 02809 } 02810 if (!var && peername) { /* Last ditch effort */ 02811 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02812 /*!\note 02813 * If this one loaded something, then we need to ensure that the host 02814 * field matched. The only reason why we can't have this as a criteria 02815 * is because we only have the IP address and the host field might be 02816 * set as a name (and the reverse PTR might not match). 02817 */ 02818 if (var && sin) { 02819 for (tmp = var; tmp; tmp = tmp->next) { 02820 if (!strcasecmp(tmp->name, "host")) { 02821 struct ast_hostent ahp; 02822 struct hostent *hp; 02823 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02824 /* No match */ 02825 ast_variables_destroy(var); 02826 var = NULL; 02827 } 02828 break; 02829 } 02830 } 02831 } 02832 } 02833 if (!var) 02834 return NULL; 02835 02836 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02837 02838 if (!peer) { 02839 ast_variables_destroy(var); 02840 return NULL; 02841 } 02842 02843 for (tmp = var; tmp; tmp = tmp->next) { 02844 /* Make sure it's not a user only... */ 02845 if (!strcasecmp(tmp->name, "type")) { 02846 if (strcasecmp(tmp->value, "friend") && 02847 strcasecmp(tmp->value, "peer")) { 02848 /* Whoops, we weren't supposed to exist! */ 02849 peer = peer_unref(peer); 02850 break; 02851 } 02852 } else if (!strcasecmp(tmp->name, "regseconds")) { 02853 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02854 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02855 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02856 } else if (!strcasecmp(tmp->name, "port")) { 02857 peer->addr.sin_port = htons(atoi(tmp->value)); 02858 } else if (!strcasecmp(tmp->name, "host")) { 02859 if (!strcasecmp(tmp->value, "dynamic")) 02860 dynamic = 1; 02861 } 02862 } 02863 02864 ast_variables_destroy(var); 02865 02866 if (!peer) 02867 return NULL; 02868 02869 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02870 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02871 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02872 if (peer->expire > -1) { 02873 if (!ast_sched_del(sched, peer->expire)) { 02874 peer->expire = -1; 02875 peer_unref(peer); 02876 } 02877 } 02878 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02879 if (peer->expire == -1) 02880 peer_unref(peer); 02881 } 02882 ao2_link(peers, peer); 02883 if (ast_test_flag(peer, IAX_DYNAMIC)) 02884 reg_source_db(peer); 02885 } else { 02886 ast_set_flag(peer, IAX_TEMPONLY); 02887 } 02888 02889 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02890 time(&nowtime); 02891 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02892 memset(&peer->addr, 0, sizeof(peer->addr)); 02893 realtime_update_peer(peer->name, &peer->addr, 0); 02894 if (option_debug) 02895 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02896 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02897 } 02898 else { 02899 if (option_debug) 02900 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02901 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02902 } 02903 } 02904 02905 return peer; 02906 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2979 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
02980 { 02981 char port[10]; 02982 char regseconds[20]; 02983 02984 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02985 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02986 ast_update_realtime("iaxpeers", "name", peername, 02987 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02988 "regseconds", regseconds, NULL); 02989 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2908 of file chan_iax2.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, users, ast_variable::value, and var.
02909 { 02910 struct ast_variable *var; 02911 struct ast_variable *tmp; 02912 struct iax2_user *user=NULL; 02913 02914 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02915 if (!var) 02916 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02917 if (!var && sin) { 02918 char porta[6]; 02919 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02920 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02921 if (!var) 02922 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02923 } 02924 if (!var) { /* Last ditch effort */ 02925 var = ast_load_realtime("iaxusers", "name", username, NULL); 02926 /*!\note 02927 * If this one loaded something, then we need to ensure that the host 02928 * field matched. The only reason why we can't have this as a criteria 02929 * is because we only have the IP address and the host field might be 02930 * set as a name (and the reverse PTR might not match). 02931 */ 02932 if (var) { 02933 for (tmp = var; tmp; tmp = tmp->next) { 02934 if (!strcasecmp(tmp->name, "host")) { 02935 struct ast_hostent ahp; 02936 struct hostent *hp; 02937 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02938 /* No match */ 02939 ast_variables_destroy(var); 02940 var = NULL; 02941 } 02942 break; 02943 } 02944 } 02945 } 02946 } 02947 if (!var) 02948 return NULL; 02949 02950 tmp = var; 02951 while(tmp) { 02952 /* Make sure it's not a peer only... */ 02953 if (!strcasecmp(tmp->name, "type")) { 02954 if (strcasecmp(tmp->value, "friend") && 02955 strcasecmp(tmp->value, "user")) { 02956 return NULL; 02957 } 02958 } 02959 tmp = tmp->next; 02960 } 02961 02962 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02963 02964 ast_variables_destroy(var); 02965 02966 if (!user) 02967 return NULL; 02968 02969 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02970 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02971 ao2_link(users, user); 02972 } else { 02973 ast_set_flag(user, IAX_TEMPONLY); 02974 } 02975 02976 return user; 02977 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6126 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(), and VERBOSE_PREFIX_3.
Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().
06127 { 06128 char data[80]; 06129 struct in_addr in; 06130 char *c, *d; 06131 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06132 c = strchr(data, ':'); 06133 if (c) { 06134 *c = '\0'; 06135 c++; 06136 if (inet_aton(data, &in)) { 06137 d = strchr(c, ':'); 06138 if (d) { 06139 *d = '\0'; 06140 d++; 06141 if (option_verbose > 2) 06142 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06143 ast_inet_ntoa(in), atoi(c), atoi(d)); 06144 iax2_poke_peer(p, 0); 06145 p->expiry = atoi(d); 06146 memset(&p->addr, 0, sizeof(p->addr)); 06147 p->addr.sin_family = AF_INET; 06148 p->addr.sin_addr = in; 06149 p->addr.sin_port = htons(atoi(c)); 06150 if (p->expire > -1) { 06151 if (!ast_sched_del(sched, p->expire)) { 06152 p->expire = -1; 06153 peer_unref(p); 06154 } 06155 } 06156 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06157 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06158 if (p->expire == -1) 06159 peer_unref(p); 06160 if (iax2_regfunk) 06161 iax2_regfunk(p->name, 1); 06162 register_peer_exten(p, 1); 06163 } 06164 06165 } 06166 } 06167 } 06168 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6046 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().
06047 { 06048 char multi[256]; 06049 char *stringp, *ext; 06050 if (!ast_strlen_zero(regcontext)) { 06051 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06052 stringp = multi; 06053 while((ext = strsep(&stringp, "&"))) { 06054 if (onoff) { 06055 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06056 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06057 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06058 } else 06059 ast_context_remove_extension(regcontext, ext, 1, NULL); 06060 } 06061 } 06062 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5489 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_device_state_changed(), 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, iax2_registry::expire, chan_iax2_pvt::expiry, expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_registry::secret, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
05490 { 05491 char requeststr[256] = ""; 05492 char peer[256] = ""; 05493 char md5secret[256] = ""; 05494 char rsasecret[256] = ""; 05495 char secret[256] = ""; 05496 struct iax2_peer *p = NULL; 05497 struct ast_key *key; 05498 char *keyn; 05499 int x; 05500 int expire = 0; 05501 int res = -1; 05502 05503 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05504 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05505 if (ies->username) 05506 ast_copy_string(peer, ies->username, sizeof(peer)); 05507 if (ies->password) 05508 ast_copy_string(secret, ies->password, sizeof(secret)); 05509 if (ies->md5_result) 05510 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05511 if (ies->rsa_result) 05512 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05513 if (ies->refresh) 05514 expire = ies->refresh; 05515 05516 if (ast_strlen_zero(peer)) { 05517 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05518 return -1; 05519 } 05520 05521 /* SLD: first call to lookup peer during registration */ 05522 ast_mutex_unlock(&iaxsl[callno]); 05523 p = find_peer(peer, 1); 05524 ast_mutex_lock(&iaxsl[callno]); 05525 if (!p || !iaxs[callno]) { 05526 if (iaxs[callno]) { 05527 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 05528 05529 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05530 05531 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 05532 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 05533 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 05534 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 05535 * to be plaintext, indicating it is an authmethod used by other peers on the system. 05536 * 05537 * If none of these cases exist, res will be returned as 0 without authentication indicating 05538 * an AUTHREQ needs to be sent out. */ 05539 05540 if (ast_strlen_zero(iaxs[callno]->challenge) && 05541 !(!ast_strlen_zero(secret) && plaintext)) { 05542 /* by setting res to 0, an REGAUTH will be sent */ 05543 res = 0; 05544 } 05545 } 05546 if (authdebug && !p) 05547 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05548 05549 goto return_unref; 05550 } 05551 05552 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05553 if (authdebug) 05554 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05555 goto return_unref; 05556 } 05557 05558 if (!ast_apply_ha(p->ha, sin)) { 05559 if (authdebug) 05560 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05561 goto return_unref; 05562 } 05563 ast_string_field_set(iaxs[callno], secret, p->secret); 05564 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05565 /* Check secret against what we have on file */ 05566 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05567 if (!ast_strlen_zero(p->inkeys)) { 05568 char tmpkeys[256]; 05569 char *stringp=NULL; 05570 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05571 stringp=tmpkeys; 05572 keyn = strsep(&stringp, ":"); 05573 while(keyn) { 05574 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05575 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05576 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05577 break; 05578 } else if (!key) 05579 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05580 keyn = strsep(&stringp, ":"); 05581 } 05582 if (!keyn) { 05583 if (authdebug) 05584 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05585 goto return_unref; 05586 } 05587 } else { 05588 if (authdebug) 05589 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05590 goto return_unref; 05591 } 05592 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05593 struct MD5Context md5; 05594 unsigned char digest[16]; 05595 char *tmppw, *stringp; 05596 05597 tmppw = ast_strdupa(p->secret); 05598 stringp = tmppw; 05599 while((tmppw = strsep(&stringp, ";"))) { 05600 MD5Init(&md5); 05601 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05602 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05603 MD5Final(digest, &md5); 05604 for (x=0;x<16;x++) 05605 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05606 if (!strcasecmp(requeststr, md5secret)) 05607 break; 05608 } 05609 if (tmppw) { 05610 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05611 } else { 05612 if (authdebug) 05613 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05614 goto return_unref; 05615 } 05616 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05617 /* They've provided a plain text password and we support that */ 05618 if (strcmp(secret, p->secret)) { 05619 if (authdebug) 05620 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05621 goto return_unref; 05622 } else 05623 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05624 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 05625 /* if challenge has been sent, but no challenge response if given, reject. */ 05626 goto return_unref; 05627 } 05628 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05629 05630 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 05631 res = 0; 05632 return_unref: 05633 if (iaxs[callno]) { 05634 ast_string_field_set(iaxs[callno], peer, peer); 05635 } 05636 /* Choose lowest expiry number */ 05637 if (expire && (expire < iaxs[callno]->expiry)) { 05638 iaxs[callno]->expiry = expire; 05639 } 05640 05641 if (p) 05642 peer_unref(p); 05643 return res; 05644 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6305 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, iax_ie_data::buf, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
06306 { 06307 struct iax_ie_data ied; 06308 struct iax2_peer *p; 06309 char challenge[10]; 06310 const char *peer_name; 06311 int sentauthmethod; 06312 06313 peer_name = ast_strdupa(iaxs[callno]->peer); 06314 06315 /* SLD: third call to find_peer in registration */ 06316 ast_mutex_unlock(&iaxsl[callno]); 06317 if ((p = find_peer(peer_name, 1))) { 06318 last_authmethod = p->authmethods; 06319 } 06320 06321 ast_mutex_lock(&iaxsl[callno]); 06322 if (!iaxs[callno]) 06323 goto return_unref; 06324 06325 memset(&ied, 0, sizeof(ied)); 06326 /* The selection of which delayed reject is sent may leak information, 06327 * if it sets a static response. For example, if a host is known to only 06328 * use MD5 authentication, then an RSA response would indicate that the 06329 * peer does not exist, and vice-versa. 06330 * Therefore, we use whatever the last peer used (which may vary over the 06331 * course of a server, which should leak minimal information). */ 06332 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06333 if (!p) { 06334 iaxs[callno]->authmethods = sentauthmethod; 06335 } 06336 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06337 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06338 /* Build the challenge */ 06339 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06340 ast_string_field_set(iaxs[callno], challenge, challenge); 06341 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06342 } 06343 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06344 06345 return_unref: 06346 if (p) { 06347 peer_unref(p); 06348 } 06349 06350 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06351 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6353 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
06354 { 06355 struct iax2_registry *reg; 06356 /* Start pessimistic */ 06357 struct iax_ie_data ied; 06358 char peer[256] = ""; 06359 char challenge[256] = ""; 06360 int res; 06361 int authmethods = 0; 06362 if (ies->authmethods) 06363 authmethods = ies->authmethods; 06364 if (ies->username) 06365 ast_copy_string(peer, ies->username, sizeof(peer)); 06366 if (ies->challenge) 06367 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06368 memset(&ied, 0, sizeof(ied)); 06369 reg = iaxs[callno]->reg; 06370 if (reg) { 06371 if (inaddrcmp(®->addr, sin)) { 06372 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06373 return -1; 06374 } 06375 if (ast_strlen_zero(reg->secret)) { 06376 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06377 reg->regstate = REG_STATE_NOAUTH; 06378 return -1; 06379 } 06380 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06381 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06382 if (reg->secret[0] == '[') { 06383 char tmpkey[256]; 06384 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06385 tmpkey[strlen(tmpkey) - 1] = '\0'; 06386 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06387 } else 06388 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06389 if (!res) { 06390 reg->regstate = REG_STATE_AUTHSENT; 06391 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06392 } else 06393 return -1; 06394 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06395 } else 06396 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06397 return -1; 06398 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4763 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, 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().
04764 { 04765 switch(regstate) { 04766 case REG_STATE_UNREGISTERED: 04767 return "Unregistered"; 04768 case REG_STATE_REGSENT: 04769 return "Request Sent"; 04770 case REG_STATE_AUTHSENT: 04771 return "Auth. Sent"; 04772 case REG_STATE_REGISTERED: 04773 return "Registered"; 04774 case REG_STATE_REJECTED: 04775 return "Rejected"; 04776 case REG_STATE_TIMEOUT: 04777 return "Timeout"; 04778 case REG_STATE_NOAUTH: 04779 return "No Authentication"; 04780 default: 04781 return "Unknown"; 04782 } 04783 }
static int reload | ( | void | ) | [static] |
Definition at line 10307 of file chan_iax2.c.
References reload_config().
10308 { 10309 return reload_config(); 10310 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10281 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().
10282 { 10283 char *config = "iax.conf"; 10284 struct iax2_registry *reg; 10285 10286 if (set_config(config, 1) > 0) { 10287 prune_peers(); 10288 prune_users(); 10289 AST_LIST_LOCK(®istrations); 10290 AST_LIST_TRAVERSE(®istrations, reg, entry) 10291 iax2_do_register(reg); 10292 AST_LIST_UNLOCK(®istrations); 10293 /* Qualify hosts, too */ 10294 poke_all_peers(); 10295 } 10296 reload_firmware(0); 10297 iax_provision_reload(); 10298 10299 return 0; 10300 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1955 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().
01956 { 01957 struct iax_firmware *cur, *curl, *curp; 01958 DIR *fwd; 01959 struct dirent *de; 01960 char dir[256]; 01961 char fn[256]; 01962 /* Mark all as dead */ 01963 ast_mutex_lock(&waresl.lock); 01964 cur = waresl.wares; 01965 while(cur) { 01966 cur->dead = 1; 01967 cur = cur->next; 01968 } 01969 01970 /* Now that we've freed them, load the new ones */ 01971 if (!unload) { 01972 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01973 fwd = opendir(dir); 01974 if (fwd) { 01975 while((de = readdir(fwd))) { 01976 if (de->d_name[0] != '.') { 01977 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01978 if (!try_firmware(fn)) { 01979 if (option_verbose > 1) 01980 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01981 } 01982 } 01983 } 01984 closedir(fwd); 01985 } else 01986 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01987 } 01988 01989 /* Clean up leftovers */ 01990 cur = waresl.wares; 01991 curp = NULL; 01992 while(cur) { 01993 curl = cur; 01994 cur = cur->next; 01995 if (curl->dead) { 01996 if (curp) { 01997 curp->next = cur; 01998 } else { 01999 waresl.wares = cur; 02000 } 02001 destroy_firmware(curl); 02002 } else { 02003 curp = cur; 02004 } 02005 } 02006 ast_mutex_unlock(&waresl.lock); 02007 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1250 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().
01251 { 01252 if (!pvt->peercallno) { 01253 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01254 return; 01255 } 01256 01257 ao2_unlink(iax_peercallno_pvts, pvt); 01258 }
Definition at line 6857 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
06858 { 06859 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06860 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06861 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06862 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06863 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06864 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06865 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06866 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9083 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(), LOG_DEBUG, and option_debug.
Referenced by start_network_thread().
09084 { 09085 int count; 09086 int res; 09087 struct timeval tv; 09088 struct timespec ts; 09089 09090 for (;;) { 09091 res = ast_sched_wait(sched); 09092 if ((res > 1000) || (res < 0)) 09093 res = 1000; 09094 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09095 ts.tv_sec = tv.tv_sec; 09096 ts.tv_nsec = tv.tv_usec * 1000; 09097 09098 pthread_testcancel(); 09099 ast_mutex_lock(&sched_lock); 09100 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09101 ast_mutex_unlock(&sched_lock); 09102 pthread_testcancel(); 09103 09104 count = ast_sched_runq(sched); 09105 if (option_debug && count >= 20) 09106 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09107 } 09108 return NULL; 09109 }
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 2639 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, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02640 { 02641 int type, len; 02642 int ret; 02643 int needfree = 0; 02644 struct ast_channel *owner = NULL; 02645 struct ast_channel *bridge = NULL; 02646 02647 /* Attempt to recover wrapped timestamps */ 02648 unwrap_timestamp(fr); 02649 02650 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02651 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02652 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02653 else { 02654 #if 0 02655 if (option_debug) 02656 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02657 #endif 02658 fr->af.delivery = ast_tv(0,0); 02659 } 02660 02661 type = JB_TYPE_CONTROL; 02662 len = 0; 02663 02664 if(fr->af.frametype == AST_FRAME_VOICE) { 02665 type = JB_TYPE_VOICE; 02666 len = ast_codec_get_samples(&fr->af) / 8; 02667 } else if(fr->af.frametype == AST_FRAME_CNG) { 02668 type = JB_TYPE_SILENCE; 02669 } 02670 02671 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02672 if (tsout) 02673 *tsout = fr->ts; 02674 __do_deliver(fr); 02675 return -1; 02676 } 02677 02678 if ((owner = iaxs[fr->callno]->owner)) 02679 bridge = ast_bridged_channel(owner); 02680 02681 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02682 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02683 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02684 jb_frame frame; 02685 02686 /* deliver any frames in the jb */ 02687 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02688 __do_deliver(frame.data); 02689 /* __do_deliver() can make the call disappear */ 02690 if (!iaxs[fr->callno]) 02691 return -1; 02692 } 02693 02694 jb_reset(iaxs[fr->callno]->jb); 02695 02696 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02697 02698 /* deliver this frame now */ 02699 if (tsout) 02700 *tsout = fr->ts; 02701 __do_deliver(fr); 02702 return -1; 02703 } 02704 02705 /* insert into jitterbuffer */ 02706 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02707 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02708 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02709 if (ret == JB_DROP) { 02710 needfree++; 02711 } else if (ret == JB_SCHED) { 02712 update_jbsched(iaxs[fr->callno]); 02713 } 02714 if (tsout) 02715 *tsout = fr->ts; 02716 if (needfree) { 02717 /* Free our iax frame */ 02718 iax2_frame_free(fr); 02719 return -1; 02720 } 02721 return 0; 02722 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno | |||
) | [static] |
Definition at line 3157 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and ast_iax2_full_hdr::scallno.
Referenced by socket_process().
03158 { 03159 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03160 .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX, 03161 .csub = compress_subclass(command) }; 03162 03163 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03164 }
static int send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 5047 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().
05048 { 05049 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05050 }
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 5066 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().
05067 { 05068 int call_num = i->callno; 05069 /* It is assumed that the callno has already been locked */ 05070 iax2_predestroy(i->callno); 05071 if (!iaxs[call_num]) 05072 return -1; 05073 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05074 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 5076 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05077 { 05078 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05079 }
static int send_command_locked | ( | unsigned short | callno, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 5052 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().
05053 { 05054 int res; 05055 ast_mutex_lock(&iaxsl[callno]); 05056 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05057 ast_mutex_unlock(&iaxsl[callno]); 05058 return res; 05059 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5081 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05082 { 05083 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05084 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1056 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01057 { 01058 #ifdef SCHED_MULTITHREADED 01059 if (schedule_action(__send_lagrq, data)) 01060 #endif 01061 __send_lagrq(data); 01062 return 0; 01063 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2080 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_registry::addr, ast_inet_ntoa(), ast_log(), iax_frame::callno, iax2_registry::callno, iax_frame::data, iax_frame::datalen, errno, error(), handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02081 { 02082 int res; 02083 int callno = f->callno; 02084 02085 /* Don't send if there was an error, but return error instead */ 02086 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02087 return -1; 02088 02089 /* Called with iaxsl held */ 02090 if (option_debug > 2 && iaxdebug) 02091 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)); 02092 if (f->transfer) { 02093 if (iaxdebug) 02094 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02095 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02096 sizeof(iaxs[callno]->transfer)); 02097 } else { 02098 if (iaxdebug) 02099 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02100 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02101 sizeof(iaxs[callno]->addr)); 02102 } 02103 if (res < 0) { 02104 if (option_debug && iaxdebug) 02105 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02106 handle_error(); 02107 } else 02108 res = 0; 02109 return res; 02110 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1016 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01017 { 01018 #ifdef SCHED_MULTITHREADED 01019 if (schedule_action(__send_ping, data)) 01020 #endif 01021 __send_ping(data); 01022 return 0; 01023 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6535 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, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, LOG_DEBUG, 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().
06536 { 06537 int res = 0; 06538 struct iax_frame *fr; 06539 struct ast_iax2_meta_hdr *meta; 06540 struct ast_iax2_meta_trunk_hdr *mth; 06541 int calls = 0; 06542 06543 /* Point to frame */ 06544 fr = (struct iax_frame *)tpeer->trunkdata; 06545 /* Point to meta data */ 06546 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06547 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06548 if (tpeer->trunkdatalen) { 06549 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06550 meta->zeros = 0; 06551 meta->metacmd = IAX_META_TRUNK; 06552 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06553 meta->cmddata = IAX_META_TRUNK_MINI; 06554 else 06555 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06556 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06557 /* And the rest of the ast_iax2 header */ 06558 fr->direction = DIRECTION_OUTGRESS; 06559 fr->retrans = -1; 06560 fr->transfer = 0; 06561 /* Any appropriate call will do */ 06562 fr->data = fr->afdata; 06563 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06564 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06565 calls = tpeer->calls; 06566 #if 0 06567 if (option_debug) 06568 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)); 06569 #endif 06570 /* Reset transmit trunk side data */ 06571 tpeer->trunkdatalen = 0; 06572 tpeer->calls = 0; 06573 } 06574 if (res < 0) 06575 return res; 06576 return calls; 06577 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9911 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(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, ast_variable::next, option_verbose, peer_unref(), peers, portno, prefs, reg_source_db(), iax2_registry::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().
09912 { 09913 struct ast_config *cfg, *ucfg; 09914 int capability=iax2_capability; 09915 struct ast_variable *v; 09916 char *cat; 09917 const char *utype; 09918 const char *tosval; 09919 int format; 09920 int portno = IAX_DEFAULT_PORTNO; 09921 int x; 09922 struct iax2_user *user; 09923 struct iax2_peer *peer; 09924 struct ast_netsock *ns; 09925 #if 0 09926 static unsigned short int last_port=0; 09927 #endif 09928 09929 cfg = ast_config_load(config_file); 09930 09931 if (!cfg) { 09932 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09933 return -1; 09934 } 09935 09936 if (reload) { 09937 set_config_destroy(); 09938 } 09939 09940 /* Reset global codec prefs */ 09941 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09942 09943 /* Reset Global Flags */ 09944 memset(&globalflags, 0, sizeof(globalflags)); 09945 ast_set_flag(&globalflags, IAX_RTUPDATE); 09946 09947 #ifdef SO_NO_CHECK 09948 nochecksums = 0; 09949 #endif 09950 09951 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09952 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09953 09954 maxauthreq = 3; 09955 09956 v = ast_variable_browse(cfg, "general"); 09957 09958 /* Seed initial tos value */ 09959 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09960 if (tosval) { 09961 if (ast_str2tos(tosval, &tos)) 09962 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09963 } 09964 while(v) { 09965 if (!strcasecmp(v->name, "bindport")){ 09966 if (reload) 09967 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09968 else 09969 portno = atoi(v->value); 09970 } else if (!strcasecmp(v->name, "pingtime")) 09971 ping_time = atoi(v->value); 09972 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09973 if (reload) { 09974 if (atoi(v->value) != iaxthreadcount) 09975 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09976 } else { 09977 iaxthreadcount = atoi(v->value); 09978 if (iaxthreadcount < 1) { 09979 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09980 iaxthreadcount = 1; 09981 } else if (iaxthreadcount > 256) { 09982 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09983 iaxthreadcount = 256; 09984 } 09985 } 09986 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09987 if (reload) { 09988 AST_LIST_LOCK(&dynamic_list); 09989 iaxmaxthreadcount = atoi(v->value); 09990 AST_LIST_UNLOCK(&dynamic_list); 09991 } else { 09992 iaxmaxthreadcount = atoi(v->value); 09993 if (iaxmaxthreadcount < 0) { 09994 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09995 iaxmaxthreadcount = 0; 09996 } else if (iaxmaxthreadcount > 256) { 09997 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09998 iaxmaxthreadcount = 256; 09999 } 10000 } 10001 } else if (!strcasecmp(v->name, "nochecksums")) { 10002 #ifdef SO_NO_CHECK 10003 if (ast_true(v->value)) 10004 nochecksums = 1; 10005 else 10006 nochecksums = 0; 10007 #else 10008 if (ast_true(v->value)) 10009 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 10010 #endif 10011 } 10012 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10013 maxjitterbuffer = atoi(v->value); 10014 else if (!strcasecmp(v->name, "resyncthreshold")) 10015 resyncthreshold = atoi(v->value); 10016 else if (!strcasecmp(v->name, "maxjitterinterps")) 10017 maxjitterinterps = atoi(v->value); 10018 else if (!strcasecmp(v->name, "lagrqtime")) 10019 lagrq_time = atoi(v->value); 10020 else if (!strcasecmp(v->name, "maxregexpire")) 10021 max_reg_expire = atoi(v->value); 10022 else if (!strcasecmp(v->name, "minregexpire")) 10023 min_reg_expire = atoi(v->value); 10024 else if (!strcasecmp(v->name, "bindaddr")) { 10025 if (reload) { 10026 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10027 } else { 10028 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10029 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10030 } else { 10031 if (option_verbose > 1) { 10032 if (strchr(v->value, ':')) 10033 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10034 else 10035 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10036 } 10037 if (defaultsockfd < 0) 10038 defaultsockfd = ast_netsock_sockfd(ns); 10039 ast_netsock_unref(ns); 10040 } 10041 } 10042 } else if (!strcasecmp(v->name, "authdebug")) 10043 authdebug = ast_true(v->value); 10044 else if (!strcasecmp(v->name, "encryption")) 10045 iax2_encryption = get_encrypt_methods(v->value); 10046 else if (!strcasecmp(v->name, "notransfer")) { 10047 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10048 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10049 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10050 } else if (!strcasecmp(v->name, "transfer")) { 10051 if (!strcasecmp(v->value, "mediaonly")) { 10052 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10053 } else if (ast_true(v->value)) { 10054 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10055 } else 10056 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10057 } else if (!strcasecmp(v->name, "codecpriority")) { 10058 if(!strcasecmp(v->value, "caller")) 10059 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10060 else if(!strcasecmp(v->value, "disabled")) 10061 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10062 else if(!strcasecmp(v->value, "reqonly")) { 10063 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10064 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10065 } 10066 } else if (!strcasecmp(v->name, "jitterbuffer")) 10067 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10068 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10069 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10070 else if (!strcasecmp(v->name, "delayreject")) 10071 delayreject = ast_true(v->value); 10072 else if (!strcasecmp(v->name, "allowfwdownload")) 10073 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10074 else if (!strcasecmp(v->name, "rtcachefriends")) 10075 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10076 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10077 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10078 else if (!strcasecmp(v->name, "rtupdate")) 10079 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10080 else if (!strcasecmp(v->name, "trunktimestamps")) 10081 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10082 else if (!strcasecmp(v->name, "rtautoclear")) { 10083 int i = atoi(v->value); 10084 if(i > 0) 10085 global_rtautoclear = i; 10086 else 10087 i = 0; 10088 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10089 } else if (!strcasecmp(v->name, "trunkfreq")) { 10090 trunkfreq = atoi(v->value); 10091 if (trunkfreq < 10) 10092 trunkfreq = 10; 10093 } else if (!strcasecmp(v->name, "autokill")) { 10094 if (sscanf(v->value, "%d", &x) == 1) { 10095 if (x >= 0) 10096 autokill = x; 10097 else 10098 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10099 } else if (ast_true(v->value)) { 10100 autokill = DEFAULT_MAXMS; 10101 } else { 10102 autokill = 0; 10103 } 10104 } else if (!strcasecmp(v->name, "bandwidth")) { 10105 if (!strcasecmp(v->value, "low")) { 10106 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10107 } else if (!strcasecmp(v->value, "medium")) { 10108 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10109 } else if (!strcasecmp(v->value, "high")) { 10110 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10111 } else 10112 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10113 } else if (!strcasecmp(v->name, "allow")) { 10114 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10115 } else if (!strcasecmp(v->name, "disallow")) { 10116 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10117 } else if (!strcasecmp(v->name, "register")) { 10118 iax2_register(v->value, v->lineno); 10119 } else if (!strcasecmp(v->name, "iaxcompat")) { 10120 iaxcompat = ast_true(v->value); 10121 } else if (!strcasecmp(v->name, "regcontext")) { 10122 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10123 /* Create context if it doesn't exist already */ 10124 if (!ast_context_find(regcontext)) 10125 ast_context_create(NULL, regcontext, "IAX2"); 10126 } else if (!strcasecmp(v->name, "tos")) { 10127 if (ast_str2tos(v->value, &tos)) 10128 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10129 } else if (!strcasecmp(v->name, "accountcode")) { 10130 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10131 } else if (!strcasecmp(v->name, "mohinterpret")) { 10132 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 10133 } else if (!strcasecmp(v->name, "mohsuggest")) { 10134 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 10135 } else if (!strcasecmp(v->name, "amaflags")) { 10136 format = ast_cdr_amaflags2int(v->value); 10137 if (format < 0) { 10138 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10139 } else { 10140 amaflags = format; 10141 } 10142 } else if (!strcasecmp(v->name, "language")) { 10143 ast_copy_string(language, v->value, sizeof(language)); 10144 } else if (!strcasecmp(v->name, "maxauthreq")) { 10145 maxauthreq = atoi(v->value); 10146 if (maxauthreq < 0) 10147 maxauthreq = 0; 10148 } else if (!strcasecmp(v->name, "adsi")) { 10149 adsi = ast_true(v->value); 10150 } /*else if (strcasecmp(v->name,"type")) */ 10151 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10152 v = v->next; 10153 } 10154 10155 if (defaultsockfd < 0) { 10156 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10157 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10158 } else { 10159 if (option_verbose > 1) 10160 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10161 defaultsockfd = ast_netsock_sockfd(ns); 10162 ast_netsock_unref(ns); 10163 } 10164 } 10165 if (reload) { 10166 ast_netsock_release(outsock); 10167 outsock = ast_netsock_list_alloc(); 10168 if (!outsock) { 10169 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10170 return -1; 10171 } 10172 ast_netsock_init(outsock); 10173 } 10174 10175 if (min_reg_expire > max_reg_expire) { 10176 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10177 min_reg_expire, max_reg_expire, max_reg_expire); 10178 min_reg_expire = max_reg_expire; 10179 } 10180 iax2_capability = capability; 10181 10182 ucfg = ast_config_load("users.conf"); 10183 if (ucfg) { 10184 struct ast_variable *gen; 10185 int genhasiax; 10186 int genregisteriax; 10187 const char *hasiax, *registeriax; 10188 10189 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10190 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10191 gen = ast_variable_browse(ucfg, "general"); 10192 cat = ast_category_browse(ucfg, NULL); 10193 while (cat) { 10194 if (strcasecmp(cat, "general")) { 10195 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10196 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10197 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10198 /* Start with general parameters, then specific parameters, user and peer */ 10199 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10200 if (user) { 10201 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10202 user = user_unref(user); 10203 } 10204 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10205 if (peer) { 10206 if (ast_test_flag(peer, IAX_DYNAMIC)) 10207 reg_source_db(peer); 10208 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10209 peer = peer_unref(peer); 10210 } 10211 } 10212 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10213 char tmp[256]; 10214 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10215 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10216 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10217 if (!host) 10218 host = ast_variable_retrieve(ucfg, "general", "host"); 10219 if (!username) 10220 username = ast_variable_retrieve(ucfg, "general", "username"); 10221 if (!secret) 10222 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10223 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10224 if (!ast_strlen_zero(secret)) 10225 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10226 else 10227 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10228 iax2_register(tmp, 0); 10229 } 10230 } 10231 } 10232 cat = ast_category_browse(ucfg, cat); 10233 } 10234 ast_config_destroy(ucfg); 10235 } 10236 10237 cat = ast_category_browse(cfg, NULL); 10238 while(cat) { 10239 if (strcasecmp(cat, "general")) { 10240 utype = ast_variable_retrieve(cfg, cat, "type"); 10241 if (utype) { 10242 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10243 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10244 if (user) { 10245 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10246 user = user_unref(user); 10247 } 10248 } 10249 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10250 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10251 if (peer) { 10252 if (ast_test_flag(peer, IAX_DYNAMIC)) 10253 reg_source_db(peer); 10254 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10255 peer = peer_unref(peer); 10256 } 10257 } else if (strcasecmp(utype, "user")) { 10258 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10259 } 10260 } else 10261 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10262 } 10263 cat = ast_category_browse(cfg, cat); 10264 } 10265 ast_config_destroy(cfg); 10266 set_timing(); 10267 return 1; 10268 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9895 of file chan_iax2.c.
References ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09896 { 09897 strcpy(accountcode, ""); 09898 strcpy(language, ""); 09899 strcpy(mohinterpret, "default"); 09900 strcpy(mohsuggest, ""); 09901 amaflags = 0; 09902 delayreject = 0; 09903 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09904 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09905 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09906 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09907 delete_users(); 09908 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9880 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09881 { 09882 #ifdef HAVE_ZAPTEL 09883 int bs = trunkfreq * 8; 09884 if (timingfd > -1) { 09885 if ( 09886 #ifdef ZT_TIMERACK 09887 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09888 #endif 09889 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09890 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09891 } 09892 #endif 09893 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 758 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().
00759 { 00760 ast_mutex_lock(lock); 00761 ast_cond_signal(cond); 00762 ast_mutex_unlock(lock); 00763 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 7009 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, 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(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, iax2_registry::callno, iax_frame::callno, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_num, ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, ast_channel::hangupcause, 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_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxq, iaxs, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_frame::len, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, ast_channel::nativeformats, NEW_ALLOW, NEW_PREVENT, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, ast_frame::samples, save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
07010 { 07011 struct sockaddr_in sin; 07012 int res; 07013 int updatehistory=1; 07014 int new = NEW_PREVENT; 07015 void *ptr; 07016 int dcallno = 0; 07017 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07018 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07019 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07020 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07021 struct ast_iax2_meta_trunk_hdr *mth; 07022 struct ast_iax2_meta_trunk_entry *mte; 07023 struct ast_iax2_meta_trunk_mini *mtm; 07024 struct iax_frame *fr; 07025 struct iax_frame *cur; 07026 struct ast_frame f = { 0, }; 07027 struct ast_channel *c; 07028 struct iax2_dpcache *dp; 07029 struct iax2_peer *peer; 07030 struct iax2_trunk_peer *tpeer; 07031 struct timeval rxtrunktime; 07032 struct iax_ies ies; 07033 struct iax_ie_data ied0, ied1; 07034 int format; 07035 int fd; 07036 int exists; 07037 int minivid = 0; 07038 unsigned int ts; 07039 char empty[32]=""; /* Safety measure */ 07040 struct iax_frame *duped_fr; 07041 char host_pref_buf[128]; 07042 char caller_pref_buf[128]; 07043 struct ast_codec_pref pref; 07044 char *using_prefs = "mine"; 07045 07046 /* allocate an iax_frame with 4096 bytes of data buffer */ 07047 fr = alloca(sizeof(*fr) + 4096); 07048 memset(fr, 0, sizeof(*fr)); 07049 fr->afdatalen = 4096; /* From alloca() above */ 07050 07051 /* Copy frequently used parameters to the stack */ 07052 res = thread->buf_len; 07053 fd = thread->iofd; 07054 memcpy(&sin, &thread->iosin, sizeof(sin)); 07055 07056 if (res < sizeof(*mh)) { 07057 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07058 return 1; 07059 } 07060 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07061 if (res < sizeof(*vh)) { 07062 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)); 07063 return 1; 07064 } 07065 07066 /* This is a video frame, get call number */ 07067 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07068 minivid = 1; 07069 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07070 unsigned char metatype; 07071 07072 if (res < sizeof(*meta)) { 07073 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)); 07074 return 1; 07075 } 07076 07077 /* This is a meta header */ 07078 switch(meta->metacmd) { 07079 case IAX_META_TRUNK: 07080 if (res < (sizeof(*meta) + sizeof(*mth))) { 07081 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07082 sizeof(*meta) + sizeof(*mth)); 07083 return 1; 07084 } 07085 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07086 ts = ntohl(mth->ts); 07087 metatype = meta->cmddata; 07088 res -= (sizeof(*meta) + sizeof(*mth)); 07089 ptr = mth->data; 07090 tpeer = find_tpeer(&sin, fd); 07091 if (!tpeer) { 07092 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)); 07093 return 1; 07094 } 07095 tpeer->trunkact = ast_tvnow(); 07096 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07097 tpeer->rxtrunktime = tpeer->trunkact; 07098 rxtrunktime = tpeer->rxtrunktime; 07099 ast_mutex_unlock(&tpeer->lock); 07100 while(res >= sizeof(*mte)) { 07101 /* Process channels */ 07102 unsigned short callno, trunked_ts, len; 07103 07104 if (metatype == IAX_META_TRUNK_MINI) { 07105 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07106 ptr += sizeof(*mtm); 07107 res -= sizeof(*mtm); 07108 len = ntohs(mtm->len); 07109 callno = ntohs(mtm->mini.callno); 07110 trunked_ts = ntohs(mtm->mini.ts); 07111 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07112 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07113 ptr += sizeof(*mte); 07114 res -= sizeof(*mte); 07115 len = ntohs(mte->len); 07116 callno = ntohs(mte->callno); 07117 trunked_ts = 0; 07118 } else { 07119 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07120 break; 07121 } 07122 /* Stop if we don't have enough data */ 07123 if (len > res) 07124 break; 07125 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07126 if (fr->callno) { 07127 /* If it's a valid call, deliver the contents. If not, we 07128 drop it, since we don't have a scallno to use for an INVAL */ 07129 /* Process as a mini frame */ 07130 memset(&f, 0, sizeof(f)); 07131 f.frametype = AST_FRAME_VOICE; 07132 if (iaxs[fr->callno]) { 07133 if (iaxs[fr->callno]->voiceformat > 0) { 07134 f.subclass = iaxs[fr->callno]->voiceformat; 07135 f.datalen = len; 07136 if (f.datalen >= 0) { 07137 if (f.datalen) 07138 f.data = ptr; 07139 if(trunked_ts) { 07140 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07141 } else 07142 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07143 /* Don't pass any packets until we're started */ 07144 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07145 /* Common things */ 07146 f.src = "IAX2"; 07147 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07148 f.samples = ast_codec_get_samples(&f); 07149 iax_frame_wrap(fr, &f); 07150 duped_fr = iaxfrdup2(fr); 07151 if (duped_fr) { 07152 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07153 } 07154 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07155 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07156 iaxs[fr->callno]->last = fr->ts; 07157 #if 1 07158 if (option_debug && iaxdebug) 07159 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07160 #endif 07161 } 07162 } 07163 } else { 07164 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07165 } 07166 } else { 07167 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 07168 iax2_vnak(fr->callno); 07169 } 07170 } 07171 ast_mutex_unlock(&iaxsl[fr->callno]); 07172 } 07173 ptr += len; 07174 res -= len; 07175 } 07176 07177 } 07178 return 1; 07179 } 07180 07181 #ifdef DEBUG_SUPPORT 07182 if (iaxdebug && (res >= sizeof(*fh))) 07183 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07184 #endif 07185 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07186 if (res < sizeof(*fh)) { 07187 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)); 07188 return 1; 07189 } 07190 07191 /* Get the destination call number */ 07192 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07193 /* Retrieve the type and subclass */ 07194 f.frametype = fh->type; 07195 if (f.frametype == AST_FRAME_VIDEO) { 07196 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07197 } else { 07198 f.subclass = uncompress_subclass(fh->csub); 07199 } 07200 07201 /* Deal with POKE/PONG without allocating a callno */ 07202 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07203 /* Reply back with a PONG, but don't care about the result. */ 07204 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno); 07205 return 1; 07206 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07207 /* Ignore */ 07208 return 1; 07209 } 07210 07211 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07212 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07213 (f.subclass == IAX_COMMAND_REGREL))) 07214 new = NEW_ALLOW; 07215 } else { 07216 /* Don't know anything about it yet */ 07217 f.frametype = AST_FRAME_NULL; 07218 f.subclass = 0; 07219 } 07220 07221 if (!fr->callno) { 07222 int check_dcallno = 0; 07223 07224 /* 07225 * We enforce accurate destination call numbers for all full frames except 07226 * LAGRQ and PING commands. This is because older versions of Asterisk 07227 * schedule these commands to get sent very quickly, and they will sometimes 07228 * be sent before they receive the first frame from the other side. When 07229 * that happens, it doesn't contain the destination call number. However, 07230 * not checking it for these frames is safe. 07231 * 07232 * Discussed in the following thread: 07233 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07234 */ 07235 07236 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07237 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07238 } 07239 07240 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07241 } 07242 07243 if (fr->callno > 0) 07244 ast_mutex_lock(&iaxsl[fr->callno]); 07245 07246 if (!fr->callno || !iaxs[fr->callno]) { 07247 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07248 frame, reply with an inval */ 07249 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07250 /* We can only raw hangup control frames */ 07251 if (((f.subclass != IAX_COMMAND_INVAL) && 07252 (f.subclass != IAX_COMMAND_TXCNT) && 07253 (f.subclass != IAX_COMMAND_TXACC) && 07254 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07255 (f.frametype != AST_FRAME_IAX)) 07256 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07257 fd); 07258 } 07259 if (fr->callno > 0) 07260 ast_mutex_unlock(&iaxsl[fr->callno]); 07261 return 1; 07262 } 07263 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07264 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07265 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07266 ast_mutex_unlock(&iaxsl[fr->callno]); 07267 return 1; 07268 } 07269 #ifdef DEBUG_SUPPORT 07270 else if (iaxdebug) 07271 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07272 #endif 07273 } 07274 07275 /* count this frame */ 07276 iaxs[fr->callno]->frames_received++; 07277 07278 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07279 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07280 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07281 unsigned short new_peercallno; 07282 07283 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07284 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07285 if (iaxs[fr->callno]->peercallno) { 07286 remove_by_peercallno(iaxs[fr->callno]); 07287 } 07288 iaxs[fr->callno]->peercallno = new_peercallno; 07289 store_by_peercallno(iaxs[fr->callno]); 07290 } 07291 } 07292 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07293 if (option_debug && iaxdebug) 07294 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07295 /* Check if it's out of order (and not an ACK or INVAL) */ 07296 fr->oseqno = fh->oseqno; 07297 fr->iseqno = fh->iseqno; 07298 fr->ts = ntohl(fh->ts); 07299 #ifdef IAXTESTS 07300 if (test_resync) { 07301 if (option_debug) 07302 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07303 fr->ts += test_resync; 07304 } 07305 #endif /* IAXTESTS */ 07306 #if 0 07307 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07308 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07309 (f.subclass == IAX_COMMAND_NEW || 07310 f.subclass == IAX_COMMAND_AUTHREQ || 07311 f.subclass == IAX_COMMAND_ACCEPT || 07312 f.subclass == IAX_COMMAND_REJECT)) ) ) 07313 #endif 07314 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07315 updatehistory = 0; 07316 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07317 (iaxs[fr->callno]->iseqno || 07318 ((f.subclass != IAX_COMMAND_TXCNT) && 07319 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07320 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07321 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07322 (f.subclass != IAX_COMMAND_TXACC)) || 07323 (f.frametype != AST_FRAME_IAX))) { 07324 if ( 07325 ((f.subclass != IAX_COMMAND_ACK) && 07326 (f.subclass != IAX_COMMAND_INVAL) && 07327 (f.subclass != IAX_COMMAND_TXCNT) && 07328 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07329 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07330 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07331 (f.subclass != IAX_COMMAND_TXACC) && 07332 (f.subclass != IAX_COMMAND_VNAK)) || 07333 (f.frametype != AST_FRAME_IAX)) { 07334 /* If it's not an ACK packet, it's out of order. */ 07335 if (option_debug) 07336 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07337 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07338 /* Check to see if we need to request retransmission, 07339 * and take sequence number wraparound into account */ 07340 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07341 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07342 if ((f.frametype != AST_FRAME_IAX) || 07343 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07344 if (option_debug) 07345 ast_log(LOG_DEBUG, "Acking anyway\n"); 07346 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07347 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07348 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07349 } 07350 } else { 07351 /* Send a VNAK requesting retransmission */ 07352 iax2_vnak(fr->callno); 07353 } 07354 ast_mutex_unlock(&iaxsl[fr->callno]); 07355 return 1; 07356 } 07357 } else { 07358 /* Increment unless it's an ACK or VNAK */ 07359 if (((f.subclass != IAX_COMMAND_ACK) && 07360 (f.subclass != IAX_COMMAND_INVAL) && 07361 (f.subclass != IAX_COMMAND_TXCNT) && 07362 (f.subclass != IAX_COMMAND_TXACC) && 07363 (f.subclass != IAX_COMMAND_VNAK)) || 07364 (f.frametype != AST_FRAME_IAX)) 07365 iaxs[fr->callno]->iseqno++; 07366 } 07367 /* A full frame */ 07368 if (res < sizeof(*fh)) { 07369 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07370 ast_mutex_unlock(&iaxsl[fr->callno]); 07371 return 1; 07372 } 07373 /* Ensure text frames are NULL-terminated */ 07374 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07375 if (res < thread->buf_size) 07376 thread->buf[res++] = '\0'; 07377 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07378 thread->buf[res - 1] = '\0'; 07379 } 07380 f.datalen = res - sizeof(*fh); 07381 07382 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07383 from the real peer, not the transfer peer */ 07384 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07385 ((f.subclass != IAX_COMMAND_INVAL) || 07386 (f.frametype != AST_FRAME_IAX))) { 07387 unsigned char x; 07388 int call_to_destroy; 07389 /* XXX This code is not very efficient. Surely there is a better way which still 07390 properly handles boundary conditions? XXX */ 07391 /* First we have to qualify that the ACKed value is within our window */ 07392 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07393 if (fr->iseqno == x) 07394 break; 07395 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07396 /* The acknowledgement is within our window. Time to acknowledge everything 07397 that it says to */ 07398 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07399 /* Ack the packet with the given timestamp */ 07400 if (option_debug && iaxdebug) 07401 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07402 call_to_destroy = 0; 07403 AST_LIST_LOCK(&iaxq.queue); 07404 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07405 /* If it's our call, and our timestamp, mark -1 retries */ 07406 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07407 cur->retries = -1; 07408 /* Destroy call if this is the end */ 07409 if (cur->final) 07410 call_to_destroy = fr->callno; 07411 } 07412 } 07413 AST_LIST_UNLOCK(&iaxq.queue); 07414 if (call_to_destroy) { 07415 if (iaxdebug && option_debug) 07416 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07417 ast_mutex_lock(&iaxsl[call_to_destroy]); 07418 iax2_destroy(call_to_destroy); 07419 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07420 } 07421 } 07422 /* Note how much we've received acknowledgement for */ 07423 if (iaxs[fr->callno]) 07424 iaxs[fr->callno]->rseqno = fr->iseqno; 07425 else { 07426 /* Stop processing now */ 07427 ast_mutex_unlock(&iaxsl[fr->callno]); 07428 return 1; 07429 } 07430 } else if (option_debug) 07431 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07432 } 07433 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07434 ((f.frametype != AST_FRAME_IAX) || 07435 ((f.subclass != IAX_COMMAND_TXACC) && 07436 (f.subclass != IAX_COMMAND_TXCNT)))) { 07437 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07438 ast_mutex_unlock(&iaxsl[fr->callno]); 07439 return 1; 07440 } 07441 07442 if (f.datalen) { 07443 if (f.frametype == AST_FRAME_IAX) { 07444 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07445 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07446 ast_mutex_unlock(&iaxsl[fr->callno]); 07447 return 1; 07448 } 07449 f.data = NULL; 07450 f.datalen = 0; 07451 } else 07452 f.data = thread->buf + sizeof(*fh); 07453 } else { 07454 if (f.frametype == AST_FRAME_IAX) 07455 f.data = NULL; 07456 else 07457 f.data = empty; 07458 memset(&ies, 0, sizeof(ies)); 07459 } 07460 07461 /* when we receive the first full frame for a new incoming channel, 07462 it is safe to start the PBX on the channel because we have now 07463 completed a 3-way handshake with the peer */ 07464 if ((f.frametype == AST_FRAME_VOICE) || 07465 (f.frametype == AST_FRAME_VIDEO) || 07466 (f.frametype == AST_FRAME_IAX)) { 07467 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07468 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07469 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07470 ast_mutex_unlock(&iaxsl[fr->callno]); 07471 return 1; 07472 } 07473 } 07474 } 07475 07476 if (f.frametype == AST_FRAME_VOICE) { 07477 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07478 iaxs[fr->callno]->voiceformat = f.subclass; 07479 if (option_debug) 07480 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07481 if (iaxs[fr->callno]->owner) { 07482 int orignative; 07483 retryowner: 07484 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07485 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07486 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07487 } 07488 if (iaxs[fr->callno]) { 07489 if (iaxs[fr->callno]->owner) { 07490 orignative = iaxs[fr->callno]->owner->nativeformats; 07491 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07492 if (iaxs[fr->callno]->owner->readformat) 07493 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07494 iaxs[fr->callno]->owner->nativeformats = orignative; 07495 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07496 } 07497 } else { 07498 if (option_debug) 07499 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07500 ast_mutex_unlock(&iaxsl[fr->callno]); 07501 return 1; 07502 } 07503 } 07504 } 07505 } 07506 if (f.frametype == AST_FRAME_VIDEO) { 07507 if (f.subclass != iaxs[fr->callno]->videoformat) { 07508 if (option_debug) 07509 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07510 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07511 } 07512 } 07513 if (f.frametype == AST_FRAME_IAX) { 07514 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07515 /* Handle the IAX pseudo frame itself */ 07516 if (option_debug && iaxdebug) 07517 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07518 07519 /* Update last ts unless the frame's timestamp originated with us. */ 07520 if (iaxs[fr->callno]->last < fr->ts && 07521 f.subclass != IAX_COMMAND_ACK && 07522 f.subclass != IAX_COMMAND_PONG && 07523 f.subclass != IAX_COMMAND_LAGRP) { 07524 iaxs[fr->callno]->last = fr->ts; 07525 if (option_debug && iaxdebug) 07526 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07527 } 07528 07529 switch(f.subclass) { 07530 case IAX_COMMAND_ACK: 07531 /* Do nothing */ 07532 break; 07533 case IAX_COMMAND_QUELCH: 07534 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07535 /* Generate Manager Hold event, if necessary*/ 07536 if (iaxs[fr->callno]->owner) { 07537 manager_event(EVENT_FLAG_CALL, "Hold", 07538 "Channel: %s\r\n" 07539 "Uniqueid: %s\r\n", 07540 iaxs[fr->callno]->owner->name, 07541 iaxs[fr->callno]->owner->uniqueid); 07542 } 07543 07544 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07545 if (ies.musiconhold) { 07546 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07547 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07548 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07549 S_OR(mohsuggest, NULL), 07550 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07551 if (!iaxs[fr->callno]) { 07552 ast_mutex_unlock(&iaxsl[fr->callno]); 07553 return 1; 07554 } 07555 } 07556 } 07557 } 07558 break; 07559 case IAX_COMMAND_UNQUELCH: 07560 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07561 /* Generate Manager Unhold event, if necessary*/ 07562 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07563 manager_event(EVENT_FLAG_CALL, "Unhold", 07564 "Channel: %s\r\n" 07565 "Uniqueid: %s\r\n", 07566 iaxs[fr->callno]->owner->name, 07567 iaxs[fr->callno]->owner->uniqueid); 07568 } 07569 07570 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07571 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07572 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07573 if (!iaxs[fr->callno]) { 07574 ast_mutex_unlock(&iaxsl[fr->callno]); 07575 return 1; 07576 } 07577 } 07578 } 07579 break; 07580 case IAX_COMMAND_TXACC: 07581 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07582 /* Ack the packet with the given timestamp */ 07583 AST_LIST_LOCK(&iaxq.queue); 07584 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07585 /* Cancel any outstanding txcnt's */ 07586 if ((fr->callno == cur->callno) && (cur->transfer)) 07587 cur->retries = -1; 07588 } 07589 AST_LIST_UNLOCK(&iaxq.queue); 07590 memset(&ied1, 0, sizeof(ied1)); 07591 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07592 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07593 iaxs[fr->callno]->transferring = TRANSFER_READY; 07594 } 07595 break; 07596 case IAX_COMMAND_NEW: 07597 /* Ignore if it's already up */ 07598 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07599 break; 07600 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07601 ast_mutex_unlock(&iaxsl[fr->callno]); 07602 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07603 ast_mutex_lock(&iaxsl[fr->callno]); 07604 if (!iaxs[fr->callno]) { 07605 ast_mutex_unlock(&iaxsl[fr->callno]); 07606 return 1; 07607 } 07608 } 07609 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07610 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07611 int new_callno; 07612 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07613 fr->callno = new_callno; 07614 } 07615 /* For security, always ack immediately */ 07616 if (delayreject) 07617 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07618 if (check_access(fr->callno, &sin, &ies)) { 07619 /* They're not allowed on */ 07620 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07621 if (authdebug) 07622 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); 07623 break; 07624 } 07625 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07626 const char *context, *exten, *cid_num; 07627 07628 context = ast_strdupa(iaxs[fr->callno]->context); 07629 exten = ast_strdupa(iaxs[fr->callno]->exten); 07630 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07631 07632 /* This might re-enter the IAX code and need the lock */ 07633 ast_mutex_unlock(&iaxsl[fr->callno]); 07634 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07635 ast_mutex_lock(&iaxsl[fr->callno]); 07636 07637 if (!iaxs[fr->callno]) { 07638 ast_mutex_unlock(&iaxsl[fr->callno]); 07639 return 1; 07640 } 07641 } else 07642 exists = 0; 07643 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07644 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07645 memset(&ied0, 0, sizeof(ied0)); 07646 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07647 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07648 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07649 if (!iaxs[fr->callno]) { 07650 ast_mutex_unlock(&iaxsl[fr->callno]); 07651 return 1; 07652 } 07653 if (authdebug) 07654 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); 07655 } else { 07656 /* Select an appropriate format */ 07657 07658 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07659 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07660 using_prefs = "reqonly"; 07661 } else { 07662 using_prefs = "disabled"; 07663 } 07664 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07665 memset(&pref, 0, sizeof(pref)); 07666 strcpy(caller_pref_buf, "disabled"); 07667 strcpy(host_pref_buf, "disabled"); 07668 } else { 07669 using_prefs = "mine"; 07670 /* If the information elements are in here... use them */ 07671 if (ies.codec_prefs) 07672 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07673 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07674 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07675 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07676 pref = iaxs[fr->callno]->rprefs; 07677 using_prefs = "caller"; 07678 } else { 07679 pref = iaxs[fr->callno]->prefs; 07680 } 07681 } else 07682 pref = iaxs[fr->callno]->prefs; 07683 07684 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07685 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07686 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07687 } 07688 if (!format) { 07689 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07690 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07691 if (!format) { 07692 memset(&ied0, 0, sizeof(ied0)); 07693 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07694 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07695 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07696 if (!iaxs[fr->callno]) { 07697 ast_mutex_unlock(&iaxsl[fr->callno]); 07698 return 1; 07699 } 07700 if (authdebug) { 07701 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07702 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); 07703 else 07704 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); 07705 } 07706 } else { 07707 /* Pick one... */ 07708 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07709 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07710 format = 0; 07711 } else { 07712 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07713 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07714 memset(&pref, 0, sizeof(pref)); 07715 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07716 strcpy(caller_pref_buf,"disabled"); 07717 strcpy(host_pref_buf,"disabled"); 07718 } else { 07719 using_prefs = "mine"; 07720 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07721 /* Do the opposite of what we tried above. */ 07722 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07723 pref = iaxs[fr->callno]->prefs; 07724 } else { 07725 pref = iaxs[fr->callno]->rprefs; 07726 using_prefs = "caller"; 07727 } 07728 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07729 07730 } else /* if no codec_prefs IE do it the old way */ 07731 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07732 } 07733 } 07734 07735 if (!format) { 07736 memset(&ied0, 0, sizeof(ied0)); 07737 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07738 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07739 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07740 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07741 if (!iaxs[fr->callno]) { 07742 ast_mutex_unlock(&iaxsl[fr->callno]); 07743 return 1; 07744 } 07745 if (authdebug) 07746 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); 07747 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07748 break; 07749 } 07750 } 07751 } 07752 if (format) { 07753 /* No authentication required, let them in */ 07754 memset(&ied1, 0, sizeof(ied1)); 07755 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07756 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07757 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07758 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07759 if (option_verbose > 2) 07760 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07761 "%srequested format = %s,\n" 07762 "%srequested prefs = %s,\n" 07763 "%sactual format = %s,\n" 07764 "%shost prefs = %s,\n" 07765 "%spriority = %s\n", 07766 ast_inet_ntoa(sin.sin_addr), 07767 VERBOSE_PREFIX_4, 07768 ast_getformatname(iaxs[fr->callno]->peerformat), 07769 VERBOSE_PREFIX_4, 07770 caller_pref_buf, 07771 VERBOSE_PREFIX_4, 07772 ast_getformatname(format), 07773 VERBOSE_PREFIX_4, 07774 host_pref_buf, 07775 VERBOSE_PREFIX_4, 07776 using_prefs); 07777 07778 iaxs[fr->callno]->chosenformat = format; 07779 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07780 } else { 07781 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07782 /* If this is a TBD call, we're ready but now what... */ 07783 if (option_verbose > 2) 07784 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07785 } 07786 } 07787 } 07788 break; 07789 } 07790 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07791 merge_encryption(iaxs[fr->callno],ies.encmethods); 07792 else 07793 iaxs[fr->callno]->encmethods = 0; 07794 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07795 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07796 if (!iaxs[fr->callno]) { 07797 ast_mutex_unlock(&iaxsl[fr->callno]); 07798 return 1; 07799 } 07800 break; 07801 case IAX_COMMAND_DPREQ: 07802 /* Request status in the dialplan */ 07803 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07804 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07805 if (iaxcompat) { 07806 /* Spawn a thread for the lookup */ 07807 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07808 } else { 07809 /* Just look it up */ 07810 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07811 } 07812 } 07813 break; 07814 case IAX_COMMAND_HANGUP: 07815 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07816 if (option_debug) 07817 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07818 /* Set hangup cause according to remote */ 07819 if (ies.causecode && iaxs[fr->callno]->owner) 07820 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07821 /* Send ack immediately, before we destroy */ 07822 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07823 iax2_destroy(fr->callno); 07824 break; 07825 case IAX_COMMAND_REJECT: 07826 /* Set hangup cause according to remote */ 07827 if (ies.causecode && iaxs[fr->callno]->owner) 07828 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07829 07830 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07831 if (iaxs[fr->callno]->owner && authdebug) 07832 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07833 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07834 ies.cause ? ies.cause : "<Unknown>"); 07835 if (option_debug) 07836 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07837 fr->callno); 07838 } 07839 /* Send ack immediately, before we destroy */ 07840 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07841 fr->ts, NULL, 0, fr->iseqno); 07842 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07843 iaxs[fr->callno]->error = EPERM; 07844 iax2_destroy(fr->callno); 07845 break; 07846 case IAX_COMMAND_TRANSFER: 07847 { 07848 struct ast_channel *bridged_chan; 07849 07850 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07851 /* Set BLINDTRANSFER channel variables */ 07852 07853 ast_mutex_unlock(&iaxsl[fr->callno]); 07854 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07855 ast_mutex_lock(&iaxsl[fr->callno]); 07856 if (!iaxs[fr->callno]) { 07857 ast_mutex_unlock(&iaxsl[fr->callno]); 07858 return 1; 07859 } 07860 07861 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07862 if (!strcmp(ies.called_number, ast_parking_ext())) { 07863 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07864 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07865 } else { 07866 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07867 } 07868 } else { 07869 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07870 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07871 ies.called_number, iaxs[fr->callno]->context); 07872 else 07873 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07874 ies.called_number, iaxs[fr->callno]->context); 07875 } 07876 } else 07877 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07878 07879 break; 07880 } 07881 case IAX_COMMAND_ACCEPT: 07882 /* Ignore if call is already up or needs authentication or is a TBD */ 07883 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07884 break; 07885 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07886 /* Send ack immediately, before we destroy */ 07887 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07888 iax2_destroy(fr->callno); 07889 break; 07890 } 07891 if (ies.format) { 07892 iaxs[fr->callno]->peerformat = ies.format; 07893 } else { 07894 if (iaxs[fr->callno]->owner) 07895 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07896 else 07897 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07898 } 07899 if (option_verbose > 2) 07900 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)); 07901 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07902 memset(&ied0, 0, sizeof(ied0)); 07903 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07904 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07905 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07906 if (!iaxs[fr->callno]) { 07907 ast_mutex_unlock(&iaxsl[fr->callno]); 07908 return 1; 07909 } 07910 if (authdebug) 07911 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); 07912 } else { 07913 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07914 if (iaxs[fr->callno]->owner) { 07915 /* Switch us to use a compatible format */ 07916 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07917 if (option_verbose > 2) 07918 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07919 retryowner2: 07920 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07921 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07922 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07923 } 07924 07925 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07926 /* Setup read/write formats properly. */ 07927 if (iaxs[fr->callno]->owner->writeformat) 07928 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07929 if (iaxs[fr->callno]->owner->readformat) 07930 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07931 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07932 } 07933 } 07934 } 07935 if (iaxs[fr->callno]) { 07936 ast_mutex_lock(&dpcache_lock); 07937 dp = iaxs[fr->callno]->dpentries; 07938 while(dp) { 07939 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07940 iax2_dprequest(dp, fr->callno); 07941 } 07942 dp = dp->peer; 07943 } 07944 ast_mutex_unlock(&dpcache_lock); 07945 } 07946 break; 07947 case IAX_COMMAND_POKE: 07948 /* Send back a pong packet with the original timestamp */ 07949 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07950 if (!iaxs[fr->callno]) { 07951 ast_mutex_unlock(&iaxsl[fr->callno]); 07952 return 1; 07953 } 07954 break; 07955 case IAX_COMMAND_PING: 07956 { 07957 struct iax_ie_data pingied; 07958 construct_rr(iaxs[fr->callno], &pingied); 07959 /* Send back a pong packet with the original timestamp */ 07960 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07961 } 07962 break; 07963 case IAX_COMMAND_PONG: 07964 /* Calculate ping time */ 07965 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07966 /* save RR info */ 07967 save_rr(fr, &ies); 07968 07969 if (iaxs[fr->callno]->peerpoke) { 07970 peer = iaxs[fr->callno]->peerpoke; 07971 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07972 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07973 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07974 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07975 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07976 } 07977 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07978 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07979 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07980 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07981 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07982 } 07983 } 07984 peer->lastms = iaxs[fr->callno]->pingtime; 07985 if (peer->smoothing && (peer->lastms > -1)) 07986 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07987 else if (peer->smoothing && peer->lastms < 0) 07988 peer->historicms = (0 + peer->historicms) / 2; 07989 else 07990 peer->historicms = iaxs[fr->callno]->pingtime; 07991 07992 /* Remove scheduled iax2_poke_noanswer */ 07993 if (peer->pokeexpire > -1) { 07994 if (!ast_sched_del(sched, peer->pokeexpire)) { 07995 peer_unref(peer); 07996 peer->pokeexpire = -1; 07997 } 07998 } 07999 /* Schedule the next cycle */ 08000 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 08001 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08002 else 08003 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 08004 if (peer->pokeexpire == -1) 08005 peer_unref(peer); 08006 /* and finally send the ack */ 08007 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08008 /* And wrap up the qualify call */ 08009 iax2_destroy(fr->callno); 08010 peer->callno = 0; 08011 if (option_debug) 08012 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08013 } 08014 break; 08015 case IAX_COMMAND_LAGRQ: 08016 case IAX_COMMAND_LAGRP: 08017 f.src = "LAGRQ"; 08018 f.mallocd = 0; 08019 f.offset = 0; 08020 f.samples = 0; 08021 iax_frame_wrap(fr, &f); 08022 if(f.subclass == IAX_COMMAND_LAGRQ) { 08023 /* Received a LAGRQ - echo back a LAGRP */ 08024 fr->af.subclass = IAX_COMMAND_LAGRP; 08025 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08026 } else { 08027 /* Received LAGRP in response to our LAGRQ */ 08028 unsigned int ts; 08029 /* This is a reply we've been given, actually measure the difference */ 08030 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08031 iaxs[fr->callno]->lag = ts - fr->ts; 08032 if (option_debug && iaxdebug) 08033 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08034 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08035 } 08036 break; 08037 case IAX_COMMAND_AUTHREQ: 08038 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08039 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>"); 08040 break; 08041 } 08042 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08043 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08044 .subclass = AST_CONTROL_HANGUP, 08045 }; 08046 ast_log(LOG_WARNING, 08047 "I don't know how to authenticate %s to %s\n", 08048 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08049 iax2_queue_frame(fr->callno, &hangup_fr); 08050 } 08051 if (!iaxs[fr->callno]) { 08052 ast_mutex_unlock(&iaxsl[fr->callno]); 08053 return 1; 08054 } 08055 break; 08056 case IAX_COMMAND_AUTHREP: 08057 /* For security, always ack immediately */ 08058 if (delayreject) 08059 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08060 /* Ignore once we've started */ 08061 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08062 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>"); 08063 break; 08064 } 08065 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08066 if (authdebug) 08067 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); 08068 memset(&ied0, 0, sizeof(ied0)); 08069 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08070 break; 08071 } 08072 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08073 /* This might re-enter the IAX code and need the lock */ 08074 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08075 } else 08076 exists = 0; 08077 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08078 if (authdebug) 08079 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); 08080 memset(&ied0, 0, sizeof(ied0)); 08081 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08082 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08083 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08084 if (!iaxs[fr->callno]) { 08085 ast_mutex_unlock(&iaxsl[fr->callno]); 08086 return 1; 08087 } 08088 } else { 08089 /* Select an appropriate format */ 08090 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08091 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08092 using_prefs = "reqonly"; 08093 } else { 08094 using_prefs = "disabled"; 08095 } 08096 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08097 memset(&pref, 0, sizeof(pref)); 08098 strcpy(caller_pref_buf, "disabled"); 08099 strcpy(host_pref_buf, "disabled"); 08100 } else { 08101 using_prefs = "mine"; 08102 if (ies.codec_prefs) 08103 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08104 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08105 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08106 pref = iaxs[fr->callno]->rprefs; 08107 using_prefs = "caller"; 08108 } else { 08109 pref = iaxs[fr->callno]->prefs; 08110 } 08111 } else /* if no codec_prefs IE do it the old way */ 08112 pref = iaxs[fr->callno]->prefs; 08113 08114 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08115 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08116 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08117 } 08118 if (!format) { 08119 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08120 if (option_debug) 08121 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); 08122 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08123 } 08124 if (!format) { 08125 if (authdebug) { 08126 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08127 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); 08128 else 08129 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); 08130 } 08131 memset(&ied0, 0, sizeof(ied0)); 08132 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08133 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08134 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08135 if (!iaxs[fr->callno]) { 08136 ast_mutex_unlock(&iaxsl[fr->callno]); 08137 return 1; 08138 } 08139 } else { 08140 /* Pick one... */ 08141 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08142 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08143 format = 0; 08144 } else { 08145 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08146 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08147 memset(&pref, 0, sizeof(pref)); 08148 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08149 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08150 strcpy(caller_pref_buf,"disabled"); 08151 strcpy(host_pref_buf,"disabled"); 08152 } else { 08153 using_prefs = "mine"; 08154 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08155 /* Do the opposite of what we tried above. */ 08156 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08157 pref = iaxs[fr->callno]->prefs; 08158 } else { 08159 pref = iaxs[fr->callno]->rprefs; 08160 using_prefs = "caller"; 08161 } 08162 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08163 } else /* if no codec_prefs IE do it the old way */ 08164 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08165 } 08166 } 08167 if (!format) { 08168 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08169 if (authdebug) { 08170 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08171 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); 08172 else 08173 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); 08174 } 08175 memset(&ied0, 0, sizeof(ied0)); 08176 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08177 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08178 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08179 if (!iaxs[fr->callno]) { 08180 ast_mutex_unlock(&iaxsl[fr->callno]); 08181 return 1; 08182 } 08183 } 08184 } 08185 } 08186 if (format) { 08187 /* Authentication received */ 08188 memset(&ied1, 0, sizeof(ied1)); 08189 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08190 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08191 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08192 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08193 if (option_verbose > 2) 08194 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08195 "%srequested format = %s,\n" 08196 "%srequested prefs = %s,\n" 08197 "%sactual format = %s,\n" 08198 "%shost prefs = %s,\n" 08199 "%spriority = %s\n", 08200 ast_inet_ntoa(sin.sin_addr), 08201 VERBOSE_PREFIX_4, 08202 ast_getformatname(iaxs[fr->callno]->peerformat), 08203 VERBOSE_PREFIX_4, 08204 caller_pref_buf, 08205 VERBOSE_PREFIX_4, 08206 ast_getformatname(format), 08207 VERBOSE_PREFIX_4, 08208 host_pref_buf, 08209 VERBOSE_PREFIX_4, 08210 using_prefs); 08211 08212 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08213 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08214 iax2_destroy(fr->callno); 08215 } else { 08216 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08217 /* If this is a TBD call, we're ready but now what... */ 08218 if (option_verbose > 2) 08219 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08220 } 08221 } 08222 } 08223 break; 08224 case IAX_COMMAND_DIAL: 08225 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08226 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08227 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08228 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08229 if (authdebug) 08230 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); 08231 memset(&ied0, 0, sizeof(ied0)); 08232 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08233 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08234 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08235 if (!iaxs[fr->callno]) { 08236 ast_mutex_unlock(&iaxsl[fr->callno]); 08237 return 1; 08238 } 08239 } else { 08240 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08241 if (option_verbose > 2) 08242 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08243 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08244 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08245 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08246 iax2_destroy(fr->callno); 08247 } 08248 } 08249 break; 08250 case IAX_COMMAND_INVAL: 08251 iaxs[fr->callno]->error = ENOTCONN; 08252 if (option_debug) 08253 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08254 iax2_destroy(fr->callno); 08255 if (option_debug) 08256 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08257 break; 08258 case IAX_COMMAND_VNAK: 08259 if (option_debug) 08260 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08261 /* Force retransmission */ 08262 vnak_retransmit(fr->callno, fr->iseqno); 08263 break; 08264 case IAX_COMMAND_REGREQ: 08265 case IAX_COMMAND_REGREL: 08266 /* For security, always ack immediately */ 08267 if (delayreject) 08268 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08269 if (register_verify(fr->callno, &sin, &ies)) { 08270 if (!iaxs[fr->callno]) { 08271 ast_mutex_unlock(&iaxsl[fr->callno]); 08272 return 1; 08273 } 08274 /* Send delayed failure */ 08275 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08276 break; 08277 } 08278 if (!iaxs[fr->callno]) { 08279 ast_mutex_unlock(&iaxsl[fr->callno]); 08280 return 1; 08281 } 08282 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08283 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 08284 08285 if (f.subclass == IAX_COMMAND_REGREL) 08286 memset(&sin, 0, sizeof(sin)); 08287 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08288 ast_log(LOG_WARNING, "Registry error\n"); 08289 if (!iaxs[fr->callno]) { 08290 ast_mutex_unlock(&iaxsl[fr->callno]); 08291 return 1; 08292 } 08293 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08294 ast_mutex_unlock(&iaxsl[fr->callno]); 08295 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08296 ast_mutex_lock(&iaxsl[fr->callno]); 08297 if (!iaxs[fr->callno]) { 08298 ast_mutex_unlock(&iaxsl[fr->callno]); 08299 return 1; 08300 } 08301 } 08302 break; 08303 } 08304 registry_authrequest(fr->callno); 08305 if (!iaxs[fr->callno]) { 08306 ast_mutex_unlock(&iaxsl[fr->callno]); 08307 return 1; 08308 } 08309 break; 08310 case IAX_COMMAND_REGACK: 08311 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08312 ast_log(LOG_WARNING, "Registration failure\n"); 08313 /* Send ack immediately, before we destroy */ 08314 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08315 iax2_destroy(fr->callno); 08316 break; 08317 case IAX_COMMAND_REGREJ: 08318 if (iaxs[fr->callno]->reg) { 08319 if (authdebug) { 08320 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)); 08321 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>"); 08322 } 08323 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08324 } 08325 /* Send ack immediately, before we destroy */ 08326 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08327 iax2_destroy(fr->callno); 08328 break; 08329 case IAX_COMMAND_REGAUTH: 08330 /* Authentication request */ 08331 if (registry_rerequest(&ies, fr->callno, &sin)) { 08332 memset(&ied0, 0, sizeof(ied0)); 08333 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08334 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08335 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08336 if (!iaxs[fr->callno]) { 08337 ast_mutex_unlock(&iaxsl[fr->callno]); 08338 return 1; 08339 } 08340 } 08341 break; 08342 case IAX_COMMAND_TXREJ: 08343 iaxs[fr->callno]->transferring = 0; 08344 if (option_verbose > 2) 08345 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08346 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08347 if (iaxs[fr->callno]->bridgecallno) { 08348 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08349 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08350 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08351 } 08352 } 08353 break; 08354 case IAX_COMMAND_TXREADY: 08355 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08356 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08357 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08358 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08359 else 08360 iaxs[fr->callno]->transferring = TRANSFER_READY; 08361 if (option_verbose > 2) 08362 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08363 if (iaxs[fr->callno]->bridgecallno) { 08364 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08365 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08366 /* They're both ready, now release them. */ 08367 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08368 if (option_verbose > 2) 08369 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08370 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08371 08372 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08373 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08374 08375 memset(&ied0, 0, sizeof(ied0)); 08376 memset(&ied1, 0, sizeof(ied1)); 08377 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08378 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08379 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08380 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08381 } else { 08382 if (option_verbose > 2) 08383 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08384 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08385 08386 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08387 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08388 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08389 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08390 08391 /* Stop doing lag & ping requests */ 08392 stop_stuff(fr->callno); 08393 stop_stuff(iaxs[fr->callno]->bridgecallno); 08394 08395 memset(&ied0, 0, sizeof(ied0)); 08396 memset(&ied1, 0, sizeof(ied1)); 08397 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08398 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08399 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08400 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08401 } 08402 08403 } 08404 } 08405 } 08406 break; 08407 case IAX_COMMAND_TXREQ: 08408 try_transfer(iaxs[fr->callno], &ies); 08409 break; 08410 case IAX_COMMAND_TXCNT: 08411 if (iaxs[fr->callno]->transferring) 08412 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08413 break; 08414 case IAX_COMMAND_TXREL: 08415 /* Send ack immediately, rather than waiting until we've changed addresses */ 08416 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08417 complete_transfer(fr->callno, &ies); 08418 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08419 break; 08420 case IAX_COMMAND_TXMEDIA: 08421 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08422 AST_LIST_LOCK(&iaxq.queue); 08423 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08424 /* Cancel any outstanding frames and start anew */ 08425 if ((fr->callno == cur->callno) && (cur->transfer)) { 08426 cur->retries = -1; 08427 } 08428 } 08429 AST_LIST_UNLOCK(&iaxq.queue); 08430 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08431 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08432 } 08433 break; 08434 case IAX_COMMAND_DPREP: 08435 complete_dpreply(iaxs[fr->callno], &ies); 08436 break; 08437 case IAX_COMMAND_UNSUPPORT: 08438 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08439 break; 08440 case IAX_COMMAND_FWDOWNL: 08441 /* Firmware download */ 08442 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08443 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08444 break; 08445 } 08446 memset(&ied0, 0, sizeof(ied0)); 08447 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08448 if (res < 0) 08449 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08450 else if (res > 0) 08451 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08452 else 08453 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08454 if (!iaxs[fr->callno]) { 08455 ast_mutex_unlock(&iaxsl[fr->callno]); 08456 return 1; 08457 } 08458 break; 08459 default: 08460 if (option_debug) 08461 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08462 memset(&ied0, 0, sizeof(ied0)); 08463 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08465 } 08466 /* Don't actually pass these frames along */ 08467 if ((f.subclass != IAX_COMMAND_ACK) && 08468 (f.subclass != IAX_COMMAND_TXCNT) && 08469 (f.subclass != IAX_COMMAND_TXACC) && 08470 (f.subclass != IAX_COMMAND_INVAL) && 08471 (f.subclass != IAX_COMMAND_VNAK)) { 08472 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08473 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08474 } 08475 ast_mutex_unlock(&iaxsl[fr->callno]); 08476 return 1; 08477 } 08478 /* Unless this is an ACK or INVAL frame, ack it */ 08479 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08480 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08481 } else if (minivid) { 08482 f.frametype = AST_FRAME_VIDEO; 08483 if (iaxs[fr->callno]->videoformat > 0) 08484 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08485 else { 08486 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08487 iax2_vnak(fr->callno); 08488 ast_mutex_unlock(&iaxsl[fr->callno]); 08489 return 1; 08490 } 08491 f.datalen = res - sizeof(*vh); 08492 if (f.datalen) 08493 f.data = thread->buf + sizeof(*vh); 08494 else 08495 f.data = NULL; 08496 #ifdef IAXTESTS 08497 if (test_resync) { 08498 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08499 } else 08500 #endif /* IAXTESTS */ 08501 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08502 } else { 08503 /* A mini frame */ 08504 f.frametype = AST_FRAME_VOICE; 08505 if (iaxs[fr->callno]->voiceformat > 0) 08506 f.subclass = iaxs[fr->callno]->voiceformat; 08507 else { 08508 if (option_debug) 08509 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08510 iax2_vnak(fr->callno); 08511 ast_mutex_unlock(&iaxsl[fr->callno]); 08512 return 1; 08513 } 08514 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08515 if (f.datalen < 0) { 08516 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08517 ast_mutex_unlock(&iaxsl[fr->callno]); 08518 return 1; 08519 } 08520 if (f.datalen) 08521 f.data = thread->buf + sizeof(*mh); 08522 else 08523 f.data = NULL; 08524 #ifdef IAXTESTS 08525 if (test_resync) { 08526 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08527 } else 08528 #endif /* IAXTESTS */ 08529 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08530 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08531 } 08532 /* Don't pass any packets until we're started */ 08533 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08534 ast_mutex_unlock(&iaxsl[fr->callno]); 08535 return 1; 08536 } 08537 /* Common things */ 08538 f.src = "IAX2"; 08539 f.mallocd = 0; 08540 f.offset = 0; 08541 f.len = 0; 08542 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08543 f.samples = ast_codec_get_samples(&f); 08544 /* We need to byteswap incoming slinear samples from network byte order */ 08545 if (f.subclass == AST_FORMAT_SLINEAR) 08546 ast_frame_byteswap_be(&f); 08547 } else 08548 f.samples = 0; 08549 iax_frame_wrap(fr, &f); 08550 08551 /* If this is our most recent packet, use it as our basis for timestamping */ 08552 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08553 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08554 fr->outoforder = 0; 08555 } else { 08556 if (option_debug && iaxdebug && iaxs[fr->callno]) 08557 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); 08558 fr->outoforder = -1; 08559 } 08560 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08561 duped_fr = iaxfrdup2(fr); 08562 if (duped_fr) { 08563 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08564 } 08565 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08566 iaxs[fr->callno]->last = fr->ts; 08567 #if 1 08568 if (option_debug && iaxdebug) 08569 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08570 #endif 08571 } 08572 08573 /* Always run again */ 08574 ast_mutex_unlock(&iaxsl[fr->callno]); 08575 return 1; 08576 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6931 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_registry::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len, LOG_DEBUG, 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().
06932 { 06933 struct iax2_thread *thread; 06934 socklen_t len; 06935 time_t t; 06936 static time_t last_errtime = 0; 06937 struct ast_iax2_full_hdr *fh; 06938 06939 if (!(thread = find_idle_thread())) { 06940 time(&t); 06941 if (t != last_errtime && option_debug) 06942 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06943 last_errtime = t; 06944 usleep(1); 06945 return 1; 06946 } 06947 06948 len = sizeof(thread->iosin); 06949 thread->iofd = fd; 06950 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06951 thread->buf_size = sizeof(thread->readbuf); 06952 thread->buf = thread->readbuf; 06953 if (thread->buf_len < 0) { 06954 if (errno != ECONNREFUSED && errno != EAGAIN) 06955 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06956 handle_error(); 06957 thread->iostate = IAX_IOSTATE_IDLE; 06958 signal_condition(&thread->lock, &thread->cond); 06959 return 1; 06960 } 06961 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06962 thread->iostate = IAX_IOSTATE_IDLE; 06963 signal_condition(&thread->lock, &thread->cond); 06964 return 1; 06965 } 06966 06967 /* Determine if this frame is a full frame; if so, and any thread is currently 06968 processing a full frame for the same callno from this peer, then drop this 06969 frame (and the peer will retransmit it) */ 06970 fh = (struct ast_iax2_full_hdr *) thread->buf; 06971 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06972 struct iax2_thread *cur = NULL; 06973 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06974 06975 AST_LIST_LOCK(&active_list); 06976 AST_LIST_TRAVERSE(&active_list, cur, list) { 06977 if ((cur->ffinfo.callno == callno) && 06978 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06979 break; 06980 } 06981 if (cur) { 06982 /* we found another thread processing a full frame for this call, 06983 so queue it up for processing later. */ 06984 defer_full_frame(thread, cur); 06985 AST_LIST_UNLOCK(&active_list); 06986 thread->iostate = IAX_IOSTATE_IDLE; 06987 signal_condition(&thread->lock, &thread->cond); 06988 return 1; 06989 } else { 06990 /* this thread is going to process this frame, so mark it */ 06991 thread->ffinfo.callno = callno; 06992 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06993 thread->ffinfo.type = fh->type; 06994 thread->ffinfo.csub = fh->csub; 06995 } 06996 AST_LIST_UNLOCK(&active_list); 06997 } 06998 06999 /* Mark as ready and send on its way */ 07000 thread->iostate = IAX_IOSTATE_READY; 07001 #ifdef DEBUG_SCHED_MULTITHREAD 07002 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 07003 #endif 07004 signal_condition(&thread->lock, &thread->cond); 07005 07006 return 1; 07007 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6718 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06719 { 06720 pthread_t newthread; 06721 struct dpreq_data *dpr; 06722 pthread_attr_t attr; 06723 06724 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06725 return; 06726 06727 pthread_attr_init(&attr); 06728 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06729 06730 dpr->callno = callno; 06731 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06732 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06733 if (callerid) 06734 dpr->callerid = ast_strdup(callerid); 06735 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06736 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06737 } 06738 06739 pthread_attr_destroy(&attr); 06740 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9178 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().
09179 { 09180 pthread_attr_t attr; 09181 int threadcount = 0; 09182 int x; 09183 for (x = 0; x < iaxthreadcount; x++) { 09184 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09185 if (thread) { 09186 thread->type = IAX_TYPE_POOL; 09187 thread->threadnum = ++threadcount; 09188 ast_mutex_init(&thread->lock); 09189 ast_cond_init(&thread->cond, NULL); 09190 pthread_attr_init(&attr); 09191 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09192 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09193 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09194 free(thread); 09195 thread = NULL; 09196 } 09197 AST_LIST_LOCK(&idle_list); 09198 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09199 AST_LIST_UNLOCK(&idle_list); 09200 } 09201 } 09202 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09203 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09204 if (option_verbose > 1) 09205 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 09206 return 0; 09207 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6400 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06401 { 06402 iax2_destroy_helper(iaxs[callno]); 06403 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1240 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().
01241 { 01242 if (!pvt->peercallno) { 01243 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01244 return; 01245 } 01246 01247 ao2_link(iax_peercallno_pvts, pvt); 01248 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6587 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_DEBUG, 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().
06588 { 06589 char buf[1024]; 06590 int res; 06591 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06592 int processed = 0; 06593 int totalcalls = 0; 06594 #ifdef ZT_TIMERACK 06595 int x = 1; 06596 #endif 06597 struct timeval now; 06598 if (iaxtrunkdebug) 06599 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06600 gettimeofday(&now, NULL); 06601 if (events & AST_IO_PRI) { 06602 #ifdef ZT_TIMERACK 06603 /* Great, this is a timing interface, just call the ioctl */ 06604 if (ioctl(fd, ZT_TIMERACK, &x)) { 06605 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06606 usleep(1); 06607 return -1; 06608 } 06609 #endif 06610 } else { 06611 /* Read and ignore from the pseudo channel for timing */ 06612 res = read(fd, buf, sizeof(buf)); 06613 if (res < 1) { 06614 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06615 return 1; 06616 } 06617 } 06618 /* For each peer that supports trunking... */ 06619 ast_mutex_lock(&tpeerlock); 06620 tpeer = tpeers; 06621 while(tpeer) { 06622 processed++; 06623 res = 0; 06624 ast_mutex_lock(&tpeer->lock); 06625 /* We can drop a single tpeer per pass. That makes all this logic 06626 substantially easier */ 06627 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06628 /* Take it out of the list, but don't free it yet, because it 06629 could be in use */ 06630 if (prev) 06631 prev->next = tpeer->next; 06632 else 06633 tpeers = tpeer->next; 06634 drop = tpeer; 06635 } else { 06636 res = send_trunk(tpeer, &now); 06637 if (iaxtrunkdebug) 06638 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); 06639 } 06640 totalcalls += res; 06641 res = 0; 06642 ast_mutex_unlock(&tpeer->lock); 06643 prev = tpeer; 06644 tpeer = tpeer->next; 06645 } 06646 ast_mutex_unlock(&tpeerlock); 06647 if (drop) { 06648 ast_mutex_lock(&drop->lock); 06649 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06650 because by the time they could get tpeerlock, we've already grabbed it */ 06651 if (option_debug) 06652 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06653 if (drop->trunkdata) { 06654 free(drop->trunkdata); 06655 drop->trunkdata = NULL; 06656 } 06657 ast_mutex_unlock(&drop->lock); 06658 ast_mutex_destroy(&drop->lock); 06659 free(drop); 06660 06661 } 06662 if (iaxtrunkdebug) 06663 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06664 iaxtrunkdebug =0; 06665 return 1; 06666 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2066 of file chan_iax2.c.
References ast_log(), iax_frame::data, iax_frame::datalen, errno, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02067 { 02068 int res; 02069 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02070 sizeof(*sin)); 02071 if (res < 0) { 02072 if (option_debug) 02073 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02074 handle_error(); 02075 } else 02076 res = 0; 02077 return res; 02078 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1754 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, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01755 { 01756 struct stat stbuf; 01757 struct iax_firmware *cur; 01758 int ifd; 01759 int fd; 01760 int res; 01761 01762 struct ast_iax2_firmware_header *fwh, fwh2; 01763 struct MD5Context md5; 01764 unsigned char sum[16]; 01765 unsigned char buf[1024]; 01766 int len, chunk; 01767 char *s2; 01768 char *last; 01769 s2 = alloca(strlen(s) + 100); 01770 if (!s2) { 01771 ast_log(LOG_WARNING, "Alloca failed!\n"); 01772 return -1; 01773 } 01774 last = strrchr(s, '/'); 01775 if (last) 01776 last++; 01777 else 01778 last = s; 01779 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01780 res = stat(s, &stbuf); 01781 if (res < 0) { 01782 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01783 return -1; 01784 } 01785 /* Make sure it's not a directory */ 01786 if (S_ISDIR(stbuf.st_mode)) 01787 return -1; 01788 ifd = open(s, O_RDONLY); 01789 if (ifd < 0) { 01790 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01791 return -1; 01792 } 01793 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01794 if (fd < 0) { 01795 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01796 close(ifd); 01797 return -1; 01798 } 01799 /* Unlink our newly created file */ 01800 unlink(s2); 01801 01802 /* Now copy the firmware into it */ 01803 len = stbuf.st_size; 01804 while(len) { 01805 chunk = len; 01806 if (chunk > sizeof(buf)) 01807 chunk = sizeof(buf); 01808 res = read(ifd, buf, chunk); 01809 if (res != chunk) { 01810 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01811 close(ifd); 01812 close(fd); 01813 return -1; 01814 } 01815 res = write(fd, buf, chunk); 01816 if (res != chunk) { 01817 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01818 close(ifd); 01819 close(fd); 01820 return -1; 01821 } 01822 len -= chunk; 01823 } 01824 close(ifd); 01825 /* Return to the beginning */ 01826 lseek(fd, 0, SEEK_SET); 01827 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01828 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01829 close(fd); 01830 return -1; 01831 } 01832 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01833 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01834 close(fd); 01835 return -1; 01836 } 01837 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01838 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01839 close(fd); 01840 return -1; 01841 } 01842 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01843 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01844 close(fd); 01845 return -1; 01846 } 01847 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01848 if (fwh == (void *) -1) { 01849 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01850 close(fd); 01851 return -1; 01852 } 01853 MD5Init(&md5); 01854 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01855 MD5Final(sum, &md5); 01856 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01857 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01858 munmap((void*)fwh, stbuf.st_size); 01859 close(fd); 01860 return -1; 01861 } 01862 cur = waresl.wares; 01863 while(cur) { 01864 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01865 /* Found a candidate */ 01866 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01867 /* The version we have on loaded is older, load this one instead */ 01868 break; 01869 /* This version is no newer than what we have. Don't worry about it. 01870 We'll consider it a proper load anyhow though */ 01871 munmap((void*)fwh, stbuf.st_size); 01872 close(fd); 01873 return 0; 01874 } 01875 cur = cur->next; 01876 } 01877 if (!cur) { 01878 /* Allocate a new one and link it */ 01879 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01880 cur->fd = -1; 01881 cur->next = waresl.wares; 01882 waresl.wares = cur; 01883 } 01884 } 01885 if (cur) { 01886 if (cur->fwh) { 01887 munmap((void*)cur->fwh, cur->mmaplen); 01888 } 01889 if (cur->fd > -1) 01890 close(cur->fd); 01891 cur->fwh = fwh; 01892 cur->fd = fd; 01893 cur->mmaplen = stbuf.st_size; 01894 cur->dead = 0; 01895 } 01896 return 0; 01897 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5793 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05794 { 05795 int newcall = 0; 05796 char newip[256]; 05797 struct iax_ie_data ied; 05798 struct sockaddr_in new; 05799 05800 05801 memset(&ied, 0, sizeof(ied)); 05802 if (ies->apparent_addr) 05803 bcopy(ies->apparent_addr, &new, sizeof(new)); 05804 if (ies->callno) 05805 newcall = ies->callno; 05806 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05807 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05808 return -1; 05809 } 05810 pvt->transfercallno = newcall; 05811 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05812 inet_aton(newip, &pvt->transfer.sin_addr); 05813 pvt->transfer.sin_family = AF_INET; 05814 pvt->transferring = TRANSFER_BEGIN; 05815 pvt->transferid = ies->transferid; 05816 if (ies->transferid) 05817 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05818 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05819 return 0; 05820 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1085 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01086 { 01087 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01088 if (csub & IAX_FLAG_SC_LOG) { 01089 /* special case for 'compressed' -1 */ 01090 if (csub == 0xff) 01091 return -1; 01092 else 01093 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01094 } 01095 else 01096 return csub; 01097 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6065 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
06066 { 06067 if (peer->expire > -1) { 06068 if (!ast_sched_del(sched, peer->expire)) { 06069 peer->expire = -1; 06070 peer_unref(peer); 06071 } 06072 } 06073 06074 if (peer->pokeexpire > -1) { 06075 if (!ast_sched_del(sched, peer->pokeexpire)) { 06076 peer->pokeexpire = -1; 06077 peer_unref(peer); 06078 } 06079 } 06080 06081 ao2_unlink(peers, peer); 06082 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11103 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11104 { 11105 ast_custom_function_unregister(&iaxpeer_function); 11106 return __unload_module(); 11107 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3486 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03487 { 03488 ast_mutex_unlock(&iaxsl[callno1]); 03489 ast_mutex_unlock(&iaxsl[callno0]); 03490 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2500 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().
02501 { 02502 int x; 02503 02504 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02505 x = fr->ts - iaxs[fr->callno]->last; 02506 if (x < -50000) { 02507 /* Sudden big jump backwards in timestamp: 02508 What likely happened here is that miniframe timestamp has circled but we haven't 02509 gotten the update from the main packet. We'll just pretend that we did, and 02510 update the timestamp appropriately. */ 02511 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02512 if (option_debug && iaxdebug) 02513 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02514 } 02515 if (x > 50000) { 02516 /* Sudden apparent big jump forwards in timestamp: 02517 What's likely happened is this is an old miniframe belonging to the previous 02518 top-16-bit timestamp that has turned up out of order. 02519 Adjust the timestamp appropriately. */ 02520 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02521 if (option_debug && iaxdebug) 02522 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02523 } 02524 } 02525 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2529 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, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
02530 { 02531 int when; 02532 02533 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02534 02535 when = jb_next(pvt->jb) - when; 02536 02537 AST_SCHED_DEL(sched, pvt->jbid); 02538 02539 if(when <= 0) { 02540 /* XXX should really just empty until when > 0.. */ 02541 when = 1; 02542 } 02543 02544 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02545 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1453 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01454 { 01455 int max = 1; 01456 int x; 01457 /* XXX Prolly don't need locks here XXX */ 01458 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01459 if (iaxs[x]) 01460 max = x + 1; 01461 } 01462 maxnontrunkcall = max; 01463 if (option_debug && iaxdebug) 01464 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01465 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1260 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), iaxs, LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01261 { 01262 int max = TRUNK_CALL_START; 01263 int x; 01264 01265 /* XXX Prolly don't need locks here XXX */ 01266 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01267 if (iaxs[x]) { 01268 max = x + 1; 01269 } 01270 } 01271 01272 maxtrunkcall = max; 01273 if (option_debug && iaxdebug) 01274 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01275 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2137 of file chan_iax2.c.
References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno.
Referenced by __attempt_transmit().
02138 { 02139 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02140 struct ast_iax2_full_hdr *fh = f->data; 02141 /* Mark this as a retransmission */ 02142 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02143 /* Update iseqno */ 02144 f->iseqno = iaxs[f->callno]->iseqno; 02145 fh->iseqno = f->iseqno; 02146 return 0; 02147 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6176 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(), iax_ie_data::buf, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), 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(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
06177 { 06178 /* Called from IAX thread only, with proper iaxsl lock */ 06179 struct iax_ie_data ied; 06180 struct iax2_peer *p; 06181 int msgcount; 06182 char data[80]; 06183 int version; 06184 const char *peer_name; 06185 int res = -1; 06186 06187 memset(&ied, 0, sizeof(ied)); 06188 06189 peer_name = ast_strdupa(iaxs[callno]->peer); 06190 06191 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06192 ast_mutex_unlock(&iaxsl[callno]); 06193 if (!(p = find_peer(peer_name, 1))) { 06194 ast_mutex_lock(&iaxsl[callno]); 06195 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06196 return -1; 06197 } 06198 ast_mutex_lock(&iaxsl[callno]); 06199 if (!iaxs[callno]) 06200 goto return_unref; 06201 06202 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06203 if (sin->sin_addr.s_addr) { 06204 time_t nowtime; 06205 time(&nowtime); 06206 realtime_update_peer(peer_name, sin, nowtime); 06207 } else { 06208 realtime_update_peer(peer_name, sin, 0); 06209 } 06210 } 06211 if (inaddrcmp(&p->addr, sin)) { 06212 if (iax2_regfunk) 06213 iax2_regfunk(p->name, 1); 06214 /* Stash the IP address from which they registered */ 06215 memcpy(&p->addr, sin, sizeof(p->addr)); 06216 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06217 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06218 ast_db_put("IAX/Registry", p->name, data); 06219 if (option_verbose > 2) 06220 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06221 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06222 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06223 register_peer_exten(p, 1); 06224 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06225 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06226 if (option_verbose > 2) 06227 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06228 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06229 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06230 register_peer_exten(p, 0); 06231 ast_db_del("IAX/Registry", p->name); 06232 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06233 } 06234 /* Update the host */ 06235 /* Verify that the host is really there */ 06236 iax2_poke_peer(p, callno); 06237 } 06238 06239 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06240 if (!iaxs[callno]) { 06241 res = 0; 06242 goto return_unref; 06243 } 06244 06245 /* Store socket fd */ 06246 p->sockfd = fd; 06247 /* Setup the expiry */ 06248 if (p->expire > -1) { 06249 if (!ast_sched_del(sched, p->expire)) { 06250 p->expire = -1; 06251 peer_unref(p); 06252 } 06253 } 06254 /* treat an unspecified refresh interval as the minimum */ 06255 if (!refresh) 06256 refresh = min_reg_expire; 06257 if (refresh > max_reg_expire) { 06258 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06259 p->name, max_reg_expire, refresh); 06260 p->expiry = max_reg_expire; 06261 } else if (refresh < min_reg_expire) { 06262 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06263 p->name, min_reg_expire, refresh); 06264 p->expiry = min_reg_expire; 06265 } else { 06266 p->expiry = refresh; 06267 } 06268 if (p->expiry && sin->sin_addr.s_addr) { 06269 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06270 if (p->expire == -1) 06271 peer_unref(p); 06272 } 06273 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06274 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06275 if (sin->sin_addr.s_addr) { 06276 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06277 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06278 if (!ast_strlen_zero(p->mailbox)) { 06279 int new, old; 06280 ast_app_inboxcount(p->mailbox, &new, &old); 06281 if (new > 255) 06282 new = 255; 06283 if (old > 255) 06284 old = 255; 06285 msgcount = (old << 8) | new; 06286 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06287 } 06288 if (ast_test_flag(p, IAX_HASCALLERID)) { 06289 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06290 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06291 } 06292 } 06293 version = iax_check_version(devtype); 06294 if (version) 06295 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06296 06297 res = 0; 06298 06299 return_unref: 06300 peer_unref(p); 06301 06302 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06303 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1132 of file chan_iax2.c.
Referenced by load_module().
01133 { 01134 struct iax2_user *user = obj, *user2 = arg; 01135 01136 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01137 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9818 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09819 { 09820 struct iax2_user *user = obj; 09821 09822 ast_set_flag(user, IAX_DELME); 09823 09824 return 0; 09825 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9582 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().
09583 { 09584 struct iax2_user *user = obj; 09585 09586 ast_free_ha(user->ha); 09587 free_context(user->contexts); 09588 if(user->vars) { 09589 ast_variables_destroy(user->vars); 09590 user->vars = NULL; 09591 } 09592 ast_string_field_free_memory(user); 09593 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1122 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01123 { 01124 const struct iax2_user *user = obj; 01125 01126 return ast_str_hash(user->name); 01127 }
Definition at line 1171 of file chan_iax2.c.
References ao2_ref().
01172 { 01173 ao2_ref(user, +1); 01174 return user; 01175 }
Definition at line 1177 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().
01178 { 01179 ao2_ref(user, -1); 01180 return NULL; 01181 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6501 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::callno, f, iaxq, iaxs, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
06502 { 06503 struct iax_frame *f; 06504 06505 AST_LIST_LOCK(&iaxq.queue); 06506 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06507 /* Send a copy immediately */ 06508 if ((f->callno == callno) && iaxs[f->callno] && 06509 ((unsigned char ) (f->oseqno - last) < 128) && 06510 (f->retries >= 0)) { 06511 send_packet(f); 06512 } 06513 } 06514 AST_LIST_UNLOCK(&iaxq.queue); 06515 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 219 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), ast_channel_alloc(), begin_dial(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), sip_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
Definition at line 223 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 222 of file chan_iax2.c.
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 10899 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 10904 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 10914 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 10909 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 10894 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 10868 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 10860 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 10852 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 176 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 224 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 277 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 227 of file chan_iax2.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), forward_message(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), sendmail(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 205 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 225 of file chan_iax2.c.
enum { ... } iax2_flags |
int(* iax2_regfunk)(const char *username, int onoff) = NULL |
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 10810 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 867 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 10876 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 826 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 453 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 207 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 163 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 452 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 813 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), make_trunk(), 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_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 814 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 450 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 209 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 202 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.
int last_authmethod = 0 [static] |
Definition at line 161 of file chan_iax2.c.
Definition at line 815 of file chan_iax2.c.
Referenced by __find_callno(), iax2_destroy(), and make_trunk().
int max_reg_expire [static] |
Definition at line 170 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 833 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 169 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 221 of file chan_iax2.c.
Referenced by check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 174 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 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 10872 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 10864 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 10856 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 175 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 8827 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peers [static] |
Definition at line 651 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(), realtime_peer(), 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(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10806 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
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 203 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 232 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 230 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 10798 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 10826 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 10844 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 10830 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 10802 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 10838 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10814 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 10848 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 10794 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 10834 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 10821 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 211 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 172 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 167 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 654 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(), realtime_user(), 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().