#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, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static 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 668 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 664 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 678 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 666 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 670 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 672 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 674 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 676 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 702 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 705 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 650 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 1437 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 990 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 832 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 2167 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().
02168 { 02169 /* Attempt to transmit the frame to the remote peer... 02170 Called without iaxsl held. */ 02171 struct iax_frame *f = (struct iax_frame *)data; 02172 int freeme=0; 02173 int callno = f->callno; 02174 /* Make sure this call is still active */ 02175 if (callno) 02176 ast_mutex_lock(&iaxsl[callno]); 02177 if (callno && iaxs[callno]) { 02178 if ((f->retries < 0) /* Already ACK'd */ || 02179 (f->retries >= max_retries) /* Too many attempts */) { 02180 /* Record an error if we've transmitted too many times */ 02181 if (f->retries >= max_retries) { 02182 if (f->transfer) { 02183 /* Transfer timeout */ 02184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02185 } else if (f->final) { 02186 if (f->final) 02187 iax2_destroy(callno); 02188 } else { 02189 if (iaxs[callno]->owner) 02190 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); 02191 iaxs[callno]->error = ETIMEDOUT; 02192 if (iaxs[callno]->owner) { 02193 struct ast_frame fr = { 0, }; 02194 /* Hangup the fd */ 02195 fr.frametype = AST_FRAME_CONTROL; 02196 fr.subclass = AST_CONTROL_HANGUP; 02197 iax2_queue_frame(callno, &fr); // XXX 02198 /* Remember, owner could disappear */ 02199 if (iaxs[callno] && iaxs[callno]->owner) 02200 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02201 } else { 02202 if (iaxs[callno]->reg) { 02203 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02204 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02205 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02206 } 02207 iax2_destroy(callno); 02208 } 02209 } 02210 02211 } 02212 freeme++; 02213 } else { 02214 /* Update it if it needs it */ 02215 update_packet(f); 02216 /* Attempt transmission */ 02217 send_packet(f); 02218 f->retries++; 02219 /* Try again later after 10 times as long */ 02220 f->retrytime *= 10; 02221 if (f->retrytime > MAX_RETRY_TIME) 02222 f->retrytime = MAX_RETRY_TIME; 02223 /* Transfer messages max out at one second */ 02224 if (f->transfer && (f->retrytime > 1000)) 02225 f->retrytime = 1000; 02226 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02227 } 02228 } else { 02229 /* Make sure it gets freed */ 02230 f->retries = -1; 02231 freeme++; 02232 } 02233 if (callno) 02234 ast_mutex_unlock(&iaxsl[callno]); 02235 /* Do not try again */ 02236 if (freeme) { 02237 /* Don't attempt delivery, just remove it from the queue */ 02238 AST_LIST_LOCK(&iaxq.queue); 02239 AST_LIST_REMOVE(&iaxq.queue, f, list); 02240 iaxq.count--; 02241 AST_LIST_UNLOCK(&iaxq.queue); 02242 f->retrans = -1; 02243 /* Free the IAX frame */ 02244 iax2_frame_free(f); 02245 } 02246 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6425 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().
06426 { 06427 /* Called from IAX thread only, without iaxs lock */ 06428 int callno = (int)(long)(nothing); 06429 struct iax_ie_data ied; 06430 ast_mutex_lock(&iaxsl[callno]); 06431 if (iaxs[callno]) { 06432 memset(&ied, 0, sizeof(ied)); 06433 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06434 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06435 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06436 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06437 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06438 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06439 } 06440 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06441 } 06442 ast_mutex_unlock(&iaxsl[callno]); 06443 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3122 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().
03123 { 03124 int callno = PTR_TO_CALLNO(nothing); 03125 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03126 ast_mutex_lock(&iaxsl[callno]); 03127 if (iaxs[callno]) { 03128 iaxs[callno]->initid = -1; 03129 iax2_queue_frame(callno, &f); 03130 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03131 } 03132 ast_mutex_unlock(&iaxsl[callno]); 03133 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6474 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().
06475 { 06476 /* Called from IAX thread only, without iaxs lock */ 06477 int callno = (int)(long)(nothing); 06478 struct iax_ie_data ied; 06479 ast_mutex_lock(&iaxsl[callno]); 06480 if (iaxs[callno]) { 06481 memset(&ied, 0, sizeof(ied)); 06482 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06483 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06484 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06485 } 06486 ast_mutex_unlock(&iaxsl[callno]); 06487 }
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 2023 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().
02024 { 02025 /* Just deliver the packet by using queueing. This is called by 02026 the IAX thread with the iaxsl lock held. */ 02027 struct iax_frame *fr = data; 02028 fr->retrans = -1; 02029 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02030 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02031 iax2_queue_frame(fr->callno, &fr->af); 02032 /* Free our iax frame */ 02033 iax2_frame_free(fr); 02034 /* And don't run again */ 02035 return 0; 02036 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6104 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().
06105 { 06106 struct iax2_peer *peer = (struct iax2_peer *) data; 06107 06108 if (!peer) 06109 return; 06110 06111 peer->expire = -1; 06112 06113 if (option_debug) 06114 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06115 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06116 realtime_update_peer(peer->name, &peer->addr, 0); 06117 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06118 /* Reset the address */ 06119 memset(&peer->addr, 0, sizeof(peer->addr)); 06120 /* Reset expiry value */ 06121 peer->expiry = min_reg_expire; 06122 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06123 ast_db_del("IAX/Registry", peer->name); 06124 register_peer_exten(peer, 0); 06125 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06126 if (iax2_regfunk) 06127 iax2_regfunk(peer->name, 0); 06128 06129 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06130 unlink_peer(peer); 06131 06132 peer_unref(peer); 06133 }
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 1522 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().
01523 { 01524 int res = 0; 01525 int x; 01526 struct timeval now; 01527 char host[80]; 01528 01529 if (new <= NEW_ALLOW) { 01530 if (callno) { 01531 struct chan_iax2_pvt *pvt; 01532 struct chan_iax2_pvt tmp_pvt = { 01533 .callno = dcallno, 01534 .peercallno = callno, 01535 /* hack!! */ 01536 .frames_received = check_dcallno, 01537 }; 01538 01539 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01540 01541 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01542 if (return_locked) { 01543 ast_mutex_lock(&iaxsl[pvt->callno]); 01544 } 01545 res = pvt->callno; 01546 ao2_ref(pvt, -1); 01547 pvt = NULL; 01548 return res; 01549 } 01550 } 01551 01552 /* Look for an existing connection first */ 01553 for (x = 1; !res && x < maxnontrunkcall; x++) { 01554 ast_mutex_lock(&iaxsl[x]); 01555 if (iaxs[x]) { 01556 /* Look for an exact match */ 01557 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01558 res = x; 01559 } 01560 } 01561 if (!res || !return_locked) 01562 ast_mutex_unlock(&iaxsl[x]); 01563 } 01564 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01565 ast_mutex_lock(&iaxsl[x]); 01566 if (iaxs[x]) { 01567 /* Look for an exact match */ 01568 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01569 res = x; 01570 } 01571 } 01572 if (!res || !return_locked) 01573 ast_mutex_unlock(&iaxsl[x]); 01574 } 01575 } 01576 if (!res && (new >= NEW_ALLOW)) { 01577 int start, found = 0; 01578 01579 /* It may seem odd that we look through the peer list for a name for 01580 * this *incoming* call. Well, it is weird. However, users don't 01581 * have an IP address/port number that we can match against. So, 01582 * this is just checking for a peer that has that IP/port and 01583 * assuming that we have a user of the same name. This isn't always 01584 * correct, but it will be changed if needed after authentication. */ 01585 if (!iax2_getpeername(*sin, host, sizeof(host))) 01586 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01587 01588 now = ast_tvnow(); 01589 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01590 for (x = start; 1; x++) { 01591 if (x == TRUNK_CALL_START) { 01592 x = 1; 01593 continue; 01594 } 01595 01596 /* Find first unused call number that hasn't been used in a while */ 01597 ast_mutex_lock(&iaxsl[x]); 01598 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01599 found = 1; 01600 break; 01601 } 01602 ast_mutex_unlock(&iaxsl[x]); 01603 01604 if (x == start - 1) { 01605 break; 01606 } 01607 } 01608 /* We've still got lock held if we found a spot */ 01609 if (x == start - 1 && !found) { 01610 ast_log(LOG_WARNING, "No more space\n"); 01611 return 0; 01612 } 01613 iaxs[x] = new_iax(sin, host); 01614 update_max_nontrunk(); 01615 if (iaxs[x]) { 01616 if (option_debug && iaxdebug) 01617 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01618 iaxs[x]->sockfd = sockfd; 01619 iaxs[x]->addr.sin_port = sin->sin_port; 01620 iaxs[x]->addr.sin_family = sin->sin_family; 01621 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01622 iaxs[x]->peercallno = callno; 01623 iaxs[x]->callno = x; 01624 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01625 iaxs[x]->expiry = min_reg_expire; 01626 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01627 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01628 iaxs[x]->amaflags = amaflags; 01629 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01630 01631 ast_string_field_set(iaxs[x], accountcode, accountcode); 01632 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01633 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01634 01635 if (iaxs[x]->peercallno) { 01636 store_by_peercallno(iaxs[x]); 01637 } 01638 } else { 01639 ast_log(LOG_WARNING, "Out of resources\n"); 01640 ast_mutex_unlock(&iaxsl[x]); 01641 return 0; 01642 } 01643 if (!return_locked) 01644 ast_mutex_unlock(&iaxsl[x]); 01645 res = x; 01646 } 01647 return res; 01648 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2564 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().
02565 { 02566 int callno = PTR_TO_CALLNO(p); 02567 struct chan_iax2_pvt *pvt = NULL; 02568 struct iax_frame *fr; 02569 jb_frame frame; 02570 int ret; 02571 long now; 02572 long next; 02573 struct timeval tv; 02574 02575 /* Make sure we have a valid private structure before going on */ 02576 ast_mutex_lock(&iaxsl[callno]); 02577 pvt = iaxs[callno]; 02578 if (!pvt) { 02579 /* No go! */ 02580 ast_mutex_unlock(&iaxsl[callno]); 02581 return; 02582 } 02583 02584 pvt->jbid = -1; 02585 02586 gettimeofday(&tv,NULL); 02587 /* round up a millisecond since ast_sched_runq does; */ 02588 /* prevents us from spinning while waiting for our now */ 02589 /* to catch up with runq's now */ 02590 tv.tv_usec += 1000; 02591 02592 now = ast_tvdiff_ms(tv, pvt->rxcore); 02593 02594 if(now >= (next = jb_next(pvt->jb))) { 02595 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02596 switch(ret) { 02597 case JB_OK: 02598 fr = frame.data; 02599 __do_deliver(fr); 02600 /* __do_deliver() can cause the call to disappear */ 02601 pvt = iaxs[callno]; 02602 break; 02603 case JB_INTERP: 02604 { 02605 struct ast_frame af = { 0, }; 02606 02607 /* create an interpolation frame */ 02608 af.frametype = AST_FRAME_VOICE; 02609 af.subclass = pvt->voiceformat; 02610 af.samples = frame.ms * 8; 02611 af.src = "IAX2 JB interpolation"; 02612 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02613 af.offset = AST_FRIENDLY_OFFSET; 02614 02615 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02616 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02617 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02618 iax2_queue_frame(callno, &af); 02619 /* iax2_queue_frame() could cause the call to disappear */ 02620 pvt = iaxs[callno]; 02621 } 02622 } 02623 break; 02624 case JB_DROP: 02625 iax2_frame_free(frame.data); 02626 break; 02627 case JB_NOFRAME: 02628 case JB_EMPTY: 02629 /* do nothing */ 02630 break; 02631 default: 02632 /* shouldn't happen */ 02633 break; 02634 } 02635 } 02636 if (pvt) 02637 update_jbsched(pvt); 02638 ast_mutex_unlock(&iaxsl[callno]); 02639 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5797 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05798 { 05799 struct iax2_registry *reg = (struct iax2_registry *)data; 05800 reg->expire = -1; 05801 iax2_do_register(reg); 05802 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8908 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().
08909 { 08910 struct iax2_peer *peer = (struct iax2_peer *)data; 08911 int callno; 08912 08913 if (peer->lastms > -1) { 08914 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08915 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08916 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08917 } 08918 if ((callno = peer->callno) > 0) { 08919 ast_mutex_lock(&iaxsl[callno]); 08920 iax2_destroy(callno); 08921 ast_mutex_unlock(&iaxsl[callno]); 08922 } 08923 peer->callno = 0; 08924 peer->lastms = -1; 08925 /* Try again quickly */ 08926 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08927 if (peer->pokeexpire == -1) 08928 peer_unref(peer); 08929 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6537 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06538 { 06539 struct iax2_peer *peer = (struct iax2_peer *)data; 06540 iax2_poke_peer(peer, 0); 06541 peer_unref(peer); 06542 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4551 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().
04552 { 04553 regex_t regexbuf; 04554 int havepattern = 0; 04555 int total_peers = 0; 04556 int online_peers = 0; 04557 int offline_peers = 0; 04558 int unmonitored_peers = 0; 04559 struct ao2_iterator i; 04560 04561 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04562 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04563 04564 struct iax2_peer *peer = NULL; 04565 char name[256]; 04566 int registeredonly=0; 04567 char *term = manager ? "\r\n" : "\n"; 04568 04569 switch (argc) { 04570 case 6: 04571 if (!strcasecmp(argv[3], "registered")) 04572 registeredonly = 1; 04573 else 04574 return RESULT_SHOWUSAGE; 04575 if (!strcasecmp(argv[4], "like")) { 04576 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04577 return RESULT_SHOWUSAGE; 04578 havepattern = 1; 04579 } else 04580 return RESULT_SHOWUSAGE; 04581 break; 04582 case 5: 04583 if (!strcasecmp(argv[3], "like")) { 04584 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04585 return RESULT_SHOWUSAGE; 04586 havepattern = 1; 04587 } else 04588 return RESULT_SHOWUSAGE; 04589 break; 04590 case 4: 04591 if (!strcasecmp(argv[3], "registered")) 04592 registeredonly = 1; 04593 else 04594 return RESULT_SHOWUSAGE; 04595 break; 04596 case 3: 04597 break; 04598 default: 04599 return RESULT_SHOWUSAGE; 04600 } 04601 04602 04603 if (s) 04604 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04605 else 04606 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04607 04608 i = ao2_iterator_init(peers, 0); 04609 for (peer = ao2_iterator_next(&i); peer; 04610 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04611 char nm[20]; 04612 char status[20]; 04613 char srch[2000]; 04614 int retstatus; 04615 04616 if (registeredonly && !peer->addr.sin_addr.s_addr) 04617 continue; 04618 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04619 continue; 04620 04621 if (!ast_strlen_zero(peer->username)) 04622 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04623 else 04624 ast_copy_string(name, peer->name, sizeof(name)); 04625 04626 retstatus = peer_status(peer, status, sizeof(status)); 04627 if (retstatus > 0) 04628 online_peers++; 04629 else if (!retstatus) 04630 offline_peers++; 04631 else 04632 unmonitored_peers++; 04633 04634 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04635 04636 snprintf(srch, sizeof(srch), FORMAT, name, 04637 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04638 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04639 nm, 04640 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04641 peer->encmethods ? "(E)" : " ", status, term); 04642 04643 if (s) 04644 astman_append(s, FORMAT, name, 04645 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04646 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04647 nm, 04648 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04649 peer->encmethods ? "(E)" : " ", status, term); 04650 else 04651 ast_cli(fd, FORMAT, name, 04652 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04653 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04654 nm, 04655 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04656 peer->encmethods ? "(E)" : " ", status, term); 04657 total_peers++; 04658 } 04659 04660 if (s) 04661 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04662 else 04663 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04664 04665 if (havepattern) 04666 regfree(®exbuf); 04667 04668 return RESULT_SUCCESS; 04669 #undef FORMAT 04670 #undef FORMAT2 04671 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 965 of file chan_iax2.c.
References ast_log(), find_idle_thread(), func, IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00966 { 00967 struct iax2_thread *thread = NULL; 00968 static time_t lasterror; 00969 static time_t t; 00970 00971 thread = find_idle_thread(); 00972 00973 if (thread != NULL) { 00974 thread->schedfunc = func; 00975 thread->scheddata = data; 00976 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00977 #ifdef DEBUG_SCHED_MULTITHREAD 00978 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00979 #endif 00980 signal_condition(&thread->lock, &thread->cond); 00981 return 0; 00982 } 00983 time(&t); 00984 if (t != lasterror && option_debug) 00985 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00986 lasterror = t; 00987 00988 return -1; 00989 }
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 5052 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().
05054 { 05055 struct ast_frame f = { 0, }; 05056 05057 f.frametype = type; 05058 f.subclass = command; 05059 f.datalen = datalen; 05060 f.src = __FUNCTION__; 05061 f.data = (void *) data; 05062 05063 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05064 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1045 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().
01046 { 01047 int callno = (long) data; 01048 01049 ast_mutex_lock(&iaxsl[callno]); 01050 01051 while (iaxs[callno] && iaxs[callno]->lagid > -1) { 01052 if (iaxs[callno]->peercallno) { 01053 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01054 } 01055 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01056 break; 01057 } 01058 01059 ast_mutex_unlock(&iaxsl[callno]); 01060 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1005 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().
01006 { 01007 int callno = (long) data; 01008 01009 ast_mutex_lock(&iaxsl[callno]); 01010 01011 while (iaxs[callno] && iaxs[callno]->pingid != -1) { 01012 if (iaxs[callno]->peercallno) { 01013 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01014 } 01015 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01016 break; 01017 } 01018 01019 ast_mutex_unlock(&iaxsl[callno]); 01020 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11035 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().
11036 { 11037 struct iax2_thread *thread = NULL; 11038 int x; 11039 11040 /* Make sure threads do not hold shared resources when they are canceled */ 11041 11042 /* Grab the sched lock resource to keep it away from threads about to die */ 11043 /* Cancel the network thread, close the net socket */ 11044 if (netthreadid != AST_PTHREADT_NULL) { 11045 AST_LIST_LOCK(&iaxq.queue); 11046 ast_mutex_lock(&sched_lock); 11047 pthread_cancel(netthreadid); 11048 ast_cond_signal(&sched_cond); 11049 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11050 AST_LIST_UNLOCK(&iaxq.queue); 11051 pthread_join(netthreadid, NULL); 11052 } 11053 if (schedthreadid != AST_PTHREADT_NULL) { 11054 ast_mutex_lock(&sched_lock); 11055 pthread_cancel(schedthreadid); 11056 ast_cond_signal(&sched_cond); 11057 ast_mutex_unlock(&sched_lock); 11058 pthread_join(schedthreadid, NULL); 11059 } 11060 11061 /* Call for all threads to halt */ 11062 AST_LIST_LOCK(&idle_list); 11063 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11064 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11065 pthread_cancel(thread->threadid); 11066 } 11067 AST_LIST_TRAVERSE_SAFE_END 11068 AST_LIST_UNLOCK(&idle_list); 11069 11070 AST_LIST_LOCK(&active_list); 11071 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11072 AST_LIST_REMOVE_CURRENT(&active_list, list); 11073 pthread_cancel(thread->threadid); 11074 } 11075 AST_LIST_TRAVERSE_SAFE_END 11076 AST_LIST_UNLOCK(&active_list); 11077 11078 AST_LIST_LOCK(&dynamic_list); 11079 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11080 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11081 pthread_cancel(thread->threadid); 11082 } 11083 AST_LIST_TRAVERSE_SAFE_END 11084 AST_LIST_UNLOCK(&dynamic_list); 11085 11086 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11087 11088 /* Wait for threads to exit */ 11089 while(0 < iaxactivethreadcount) 11090 usleep(10000); 11091 11092 ast_netsock_release(netsock); 11093 ast_netsock_release(outsock); 11094 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11095 if (iaxs[x]) { 11096 iax2_destroy(x); 11097 } 11098 } 11099 ast_manager_unregister( "IAXpeers" ); 11100 ast_manager_unregister( "IAXnetstats" ); 11101 ast_unregister_application(papp); 11102 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11103 ast_unregister_switch(&iax2_switch); 11104 ast_channel_unregister(&iax2_tech); 11105 delete_users(); 11106 iax_provision_unload(); 11107 sched_context_destroy(sched); 11108 reload_firmware(1); 11109 11110 ast_mutex_destroy(&waresl.lock); 11111 11112 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11113 ast_mutex_destroy(&iaxsl[x]); 11114 } 11115 11116 ao2_ref(peers, -1); 11117 ao2_ref(users, -1); 11118 ao2_ref(iax_peercallno_pvts, -1); 11119 11120 return 0; 11121 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5105 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05106 { 05107 while(con) { 05108 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05109 return -1; 05110 con = con->next; 05111 } 05112 return 0; 05113 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4879 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().
04880 { 04881 int x; 04882 int numchans = 0; 04883 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04884 ast_mutex_lock(&iaxsl[x]); 04885 if (iaxs[x]) { 04886 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04887 char *fmt; 04888 jb_info jbinfo; 04889 04890 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04891 jb_getinfo(iaxs[x]->jb, &jbinfo); 04892 localjitter = jbinfo.jitter; 04893 localdelay = jbinfo.current - jbinfo.min; 04894 locallost = jbinfo.frames_lost; 04895 locallosspct = jbinfo.losspct/1000; 04896 localdropped = jbinfo.frames_dropped; 04897 localooo = jbinfo.frames_ooo; 04898 } else { 04899 localjitter = -1; 04900 localdelay = 0; 04901 locallost = -1; 04902 locallosspct = -1; 04903 localdropped = 0; 04904 localooo = -1; 04905 } 04906 if (limit_fmt) 04907 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04908 else 04909 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04910 if (s) 04911 04912 astman_append(s, fmt, 04913 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04914 iaxs[x]->pingtime, 04915 localjitter, 04916 localdelay, 04917 locallost, 04918 locallosspct, 04919 localdropped, 04920 localooo, 04921 iaxs[x]->frames_received/1000, 04922 iaxs[x]->remote_rr.jitter, 04923 iaxs[x]->remote_rr.delay, 04924 iaxs[x]->remote_rr.losscnt, 04925 iaxs[x]->remote_rr.losspct, 04926 iaxs[x]->remote_rr.dropped, 04927 iaxs[x]->remote_rr.ooo, 04928 iaxs[x]->remote_rr.packets/1000); 04929 else 04930 ast_cli(fd, fmt, 04931 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04932 iaxs[x]->pingtime, 04933 localjitter, 04934 localdelay, 04935 locallost, 04936 locallosspct, 04937 localdropped, 04938 localooo, 04939 iaxs[x]->frames_received/1000, 04940 iaxs[x]->remote_rr.jitter, 04941 iaxs[x]->remote_rr.delay, 04942 iaxs[x]->remote_rr.losscnt, 04943 iaxs[x]->remote_rr.losspct, 04944 iaxs[x]->remote_rr.dropped, 04945 iaxs[x]->remote_rr.ooo, 04946 iaxs[x]->remote_rr.packets/1000 04947 ); 04948 numchans++; 04949 } 04950 ast_mutex_unlock(&iaxsl[x]); 04951 } 04952 return numchans; 04953 }
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 3743 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().
03744 { 03745 struct ast_channel *tmp; 03746 struct chan_iax2_pvt *i; 03747 struct ast_variable *v = NULL; 03748 03749 if (!(i = iaxs[callno])) { 03750 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03751 return NULL; 03752 } 03753 03754 /* Don't hold call lock */ 03755 ast_mutex_unlock(&iaxsl[callno]); 03756 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); 03757 ast_mutex_lock(&iaxsl[callno]); 03758 if (!iaxs[callno]) { 03759 if (tmp) { 03760 ast_channel_free(tmp); 03761 } 03762 ast_mutex_unlock(&iaxsl[callno]); 03763 return NULL; 03764 } 03765 03766 if (!tmp) 03767 return NULL; 03768 tmp->tech = &iax2_tech; 03769 /* We can support any format by default, until we get restricted */ 03770 tmp->nativeformats = capability; 03771 tmp->readformat = ast_best_codec(capability); 03772 tmp->writeformat = ast_best_codec(capability); 03773 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03774 03775 /* Don't use ast_set_callerid() here because it will 03776 * generate a NewCallerID event before the NewChannel event */ 03777 if (!ast_strlen_zero(i->ani)) 03778 tmp->cid.cid_ani = ast_strdup(i->ani); 03779 else 03780 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03781 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03782 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03783 tmp->cid.cid_pres = i->calling_pres; 03784 tmp->cid.cid_ton = i->calling_ton; 03785 tmp->cid.cid_tns = i->calling_tns; 03786 if (!ast_strlen_zero(i->language)) 03787 ast_string_field_set(tmp, language, i->language); 03788 if (!ast_strlen_zero(i->accountcode)) 03789 ast_string_field_set(tmp, accountcode, i->accountcode); 03790 if (i->amaflags) 03791 tmp->amaflags = i->amaflags; 03792 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03793 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03794 if (i->adsi) 03795 tmp->adsicpe = i->peeradsicpe; 03796 else 03797 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03798 i->owner = tmp; 03799 i->capability = capability; 03800 03801 for (v = i->vars ; v ; v = v->next) 03802 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03803 03804 if (state != AST_STATE_DOWN) { 03805 if (ast_pbx_start(tmp)) { 03806 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03807 ast_hangup(tmp); 03808 i->owner = NULL; 03809 return NULL; 03810 } 03811 } 03812 03813 ast_module_ref(ast_module_info->self); 03814 03815 return tmp; 03816 }
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 2248 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02249 { 02250 #ifdef SCHED_MULTITHREADED 02251 if (schedule_action(__attempt_transmit, data)) 02252 #endif 02253 __attempt_transmit(data); 02254 return 0; 02255 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6459 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().
06460 { 06461 /* Schedule sending the authentication failure in one second, to prevent 06462 guessing */ 06463 if (iaxs[callno]) { 06464 iaxs[callno]->authfail = failcode; 06465 if (delayreject) { 06466 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06467 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06468 } else 06469 auth_reject((void *)(long)callno); 06470 } 06471 return 0; 06472 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6445 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().
06446 { 06447 int callno = (int)(long)(data); 06448 ast_mutex_lock(&iaxsl[callno]); 06449 if (iaxs[callno]) 06450 iaxs[callno]->authid = -1; 06451 ast_mutex_unlock(&iaxsl[callno]); 06452 #ifdef SCHED_MULTITHREADED 06453 if (schedule_action(__auth_reject, data)) 06454 #endif 06455 __auth_reject(data); 06456 return 0; 06457 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5665 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
05666 { 05667 int res = -1; 05668 int x; 05669 if (!ast_strlen_zero(keyn)) { 05670 if (!(authmethods & IAX_AUTH_RSA)) { 05671 if (ast_strlen_zero(secret)) 05672 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)); 05673 } else if (ast_strlen_zero(challenge)) { 05674 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05675 } else { 05676 char sig[256]; 05677 struct ast_key *key; 05678 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05679 if (!key) { 05680 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05681 } else { 05682 if (ast_sign(key, (char*)challenge, sig)) { 05683 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05684 res = -1; 05685 } else { 05686 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05687 res = 0; 05688 } 05689 } 05690 } 05691 } 05692 /* Fall back */ 05693 if (res && !ast_strlen_zero(secret)) { 05694 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05695 struct MD5Context md5; 05696 unsigned char digest[16]; 05697 char digres[128]; 05698 MD5Init(&md5); 05699 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05700 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05701 MD5Final(digest, &md5); 05702 /* If they support md5, authenticate with it. */ 05703 for (x=0;x<16;x++) 05704 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05705 if (pvt) { 05706 build_encryption_keys(digest, pvt); 05707 } 05708 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05709 res = 0; 05710 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05711 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05712 res = 0; 05713 } else 05714 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05715 } 05716 return res; 05717 }
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 5723 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::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().
05724 { 05725 struct iax2_peer *peer = NULL; 05726 /* Start pessimistic */ 05727 int res = -1; 05728 int authmethods = 0; 05729 struct iax_ie_data ied; 05730 uint16_t callno = p->callno; 05731 05732 memset(&ied, 0, sizeof(ied)); 05733 05734 if (ies->username) 05735 ast_string_field_set(p, username, ies->username); 05736 if (ies->challenge) 05737 ast_string_field_set(p, challenge, ies->challenge); 05738 if (ies->authmethods) 05739 authmethods = ies->authmethods; 05740 if (authmethods & IAX_AUTH_MD5) 05741 merge_encryption(p, ies->encmethods); 05742 else 05743 p->encmethods = 0; 05744 05745 /* Check for override RSA authentication first */ 05746 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05747 /* Normal password authentication */ 05748 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 05749 } else { 05750 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05751 while ((peer = ao2_iterator_next(&i))) { 05752 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05753 /* No peer specified at our end, or this is the peer */ 05754 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05755 /* No username specified in peer rule, or this is the right username */ 05756 && (!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))) 05757 /* No specified host, or this is our host */ 05758 ) { 05759 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 05760 if (!res) { 05761 peer_unref(peer); 05762 break; 05763 } 05764 } 05765 peer_unref(peer); 05766 } 05767 if (!peer) { 05768 /* We checked our list and didn't find one. It's unlikely, but possible, 05769 that we're trying to authenticate *to* a realtime peer */ 05770 const char *peer_name = ast_strdupa(p->peer); 05771 ast_mutex_unlock(&iaxsl[callno]); 05772 if ((peer = realtime_peer(peer_name, NULL))) { 05773 ast_mutex_lock(&iaxsl[callno]); 05774 if (!(p = iaxs[callno])) { 05775 peer_unref(peer); 05776 return -1; 05777 } 05778 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 05779 peer_unref(peer); 05780 } 05781 if (!peer) { 05782 ast_mutex_lock(&iaxsl[callno]); 05783 if (!(p = iaxs[callno])) 05784 return -1; 05785 } 05786 } 05787 } 05788 if (ies->encmethods) 05789 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05790 if (!res) 05791 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05792 return res; 05793 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5377 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().
05378 { 05379 struct iax_ie_data ied; 05380 int res = -1, authreq_restrict = 0; 05381 char challenge[10]; 05382 struct chan_iax2_pvt *p = iaxs[call_num]; 05383 05384 memset(&ied, 0, sizeof(ied)); 05385 05386 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05387 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05388 struct iax2_user *user, tmp_user = { 05389 .name = p->username, 05390 }; 05391 05392 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05393 if (user) { 05394 if (user->curauthreq == user->maxauthreq) 05395 authreq_restrict = 1; 05396 else 05397 user->curauthreq++; 05398 user = user_unref(user); 05399 } 05400 } 05401 05402 /* If the AUTHREQ limit test failed, send back an error */ 05403 if (authreq_restrict) { 05404 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05405 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05406 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05407 return 0; 05408 } 05409 05410 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05411 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05412 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05413 ast_string_field_set(p, challenge, challenge); 05414 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05415 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05416 } 05417 if (p->encmethods) 05418 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05419 05420 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05421 05422 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05423 05424 if (p->encmethods) 05425 ast_set_flag(p, IAX_ENCRYPTED); 05426 05427 return res; 05428 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5430 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().
05431 { 05432 char requeststr[256]; 05433 char md5secret[256] = ""; 05434 char secret[256] = ""; 05435 char rsasecret[256] = ""; 05436 int res = -1; 05437 int x; 05438 struct iax2_user *user, tmp_user = { 05439 .name = p->username, 05440 }; 05441 05442 if (p->authrej) { 05443 return res; 05444 } 05445 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05446 if (user) { 05447 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05448 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05449 ast_clear_flag(p, IAX_MAXAUTHREQ); 05450 } 05451 ast_string_field_set(p, host, user->name); 05452 user = user_unref(user); 05453 } 05454 05455 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05456 return res; 05457 if (ies->password) 05458 ast_copy_string(secret, ies->password, sizeof(secret)); 05459 if (ies->md5_result) 05460 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05461 if (ies->rsa_result) 05462 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05463 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05464 struct ast_key *key; 05465 char *keyn; 05466 char tmpkey[256]; 05467 char *stringp=NULL; 05468 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05469 stringp=tmpkey; 05470 keyn = strsep(&stringp, ":"); 05471 while(keyn) { 05472 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05473 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05474 res = 0; 05475 break; 05476 } else if (!key) 05477 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05478 keyn = strsep(&stringp, ":"); 05479 } 05480 } else if (p->authmethods & IAX_AUTH_MD5) { 05481 struct MD5Context md5; 05482 unsigned char digest[16]; 05483 char *tmppw, *stringp; 05484 05485 tmppw = ast_strdupa(p->secret); 05486 stringp = tmppw; 05487 while((tmppw = strsep(&stringp, ";"))) { 05488 MD5Init(&md5); 05489 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05490 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05491 MD5Final(digest, &md5); 05492 /* If they support md5, authenticate with it. */ 05493 for (x=0;x<16;x++) 05494 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05495 if (!strcasecmp(requeststr, md5secret)) { 05496 res = 0; 05497 break; 05498 } 05499 } 05500 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05501 if (!strcmp(secret, p->secret)) 05502 res = 0; 05503 } 05504 return res; 05505 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3135 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03136 { 03137 #ifdef SCHED_MULTITHREADED 03138 if (schedule_action(__auto_congest, data)) 03139 #endif 03140 __auto_congest(data); 03141 return 0; 03142 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6489 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().
06490 { 06491 int callno = (int)(long)(data); 06492 ast_mutex_lock(&iaxsl[callno]); 06493 if (iaxs[callno]) { 06494 iaxs[callno]->autoid = -1; 06495 } 06496 ast_mutex_unlock(&iaxsl[callno]); 06497 #ifdef SCHED_MULTITHREADED 06498 if (schedule_action(__auto_hangup, data)) 06499 #endif 06500 __auto_hangup(data); 06501 return 0; 06502 }
static struct iax2_context* build_context | ( | char * | context | ) | [static, read] |
Definition at line 9229 of file chan_iax2.c.
References ast_calloc, and iax2_context::context.
Referenced by build_user().
09230 { 09231 struct iax2_context *con; 09232 09233 if ((con = ast_calloc(1, sizeof(*con)))) 09234 ast_copy_string(con->context, context, sizeof(con->context)); 09235 09236 return con; 09237 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 4129 of file chan_iax2.c.
References aes_decrypt_key128(), aes_encrypt_key128(), chan_iax2_pvt::ecx, and chan_iax2_pvt::mydcx.
Referenced by build_encryption_keys().
04130 { 04131 /* it is required to hold the corresponding decrypt key to our encrypt key 04132 * in the pvt struct because queued frames occasionally need to be decrypted and 04133 * re-encrypted when updated for a retransmission */ 04134 aes_encrypt_key128(digest, &pvt->ecx); 04135 aes_decrypt_key128(digest, &pvt->mydcx); 04136 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 4123 of file chan_iax2.c.
References aes_decrypt_key128(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
04124 { 04125 build_ecx_key(digest, pvt); 04126 aes_decrypt_key128(digest, &pvt->dcx); 04127 }
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 9375 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.
09376 { 09377 struct iax2_peer *peer = NULL; 09378 struct ast_ha *oldha = NULL; 09379 int maskfound=0; 09380 int found=0; 09381 int firstpass=1; 09382 struct iax2_peer tmp_peer = { 09383 .name = name, 09384 }; 09385 09386 if (!temponly) { 09387 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09388 if (peer && !ast_test_flag(peer, IAX_DELME)) 09389 firstpass = 0; 09390 } 09391 09392 if (peer) { 09393 found++; 09394 if (firstpass) { 09395 oldha = peer->ha; 09396 peer->ha = NULL; 09397 } 09398 unlink_peer(peer); 09399 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09400 peer->expire = -1; 09401 peer->pokeexpire = -1; 09402 peer->sockfd = defaultsockfd; 09403 if (ast_string_field_init(peer, 32)) 09404 peer = peer_unref(peer); 09405 } 09406 09407 if (peer) { 09408 if (firstpass) { 09409 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09410 peer->encmethods = iax2_encryption; 09411 peer->adsi = adsi; 09412 ast_string_field_set(peer,secret,""); 09413 if (!found) { 09414 ast_string_field_set(peer, name, name); 09415 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09416 peer->expiry = min_reg_expire; 09417 } 09418 peer->prefs = prefs; 09419 peer->capability = iax2_capability; 09420 peer->smoothing = 0; 09421 peer->pokefreqok = DEFAULT_FREQ_OK; 09422 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09423 ast_string_field_set(peer,context,""); 09424 ast_string_field_set(peer,peercontext,""); 09425 ast_clear_flag(peer, IAX_HASCALLERID); 09426 ast_string_field_set(peer, cid_name, ""); 09427 ast_string_field_set(peer, cid_num, ""); 09428 } 09429 09430 if (!v) { 09431 v = alt; 09432 alt = NULL; 09433 } 09434 while(v) { 09435 if (!strcasecmp(v->name, "secret")) { 09436 ast_string_field_set(peer, secret, v->value); 09437 } else if (!strcasecmp(v->name, "mailbox")) { 09438 ast_string_field_set(peer, mailbox, v->value); 09439 } else if (!strcasecmp(v->name, "mohinterpret")) { 09440 ast_string_field_set(peer, mohinterpret, v->value); 09441 } else if (!strcasecmp(v->name, "mohsuggest")) { 09442 ast_string_field_set(peer, mohsuggest, v->value); 09443 } else if (!strcasecmp(v->name, "dbsecret")) { 09444 ast_string_field_set(peer, dbsecret, v->value); 09445 } else if (!strcasecmp(v->name, "trunk")) { 09446 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09447 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09448 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09449 ast_clear_flag(peer, IAX_TRUNK); 09450 } 09451 } else if (!strcasecmp(v->name, "auth")) { 09452 peer->authmethods = get_auth_methods(v->value); 09453 } else if (!strcasecmp(v->name, "encryption")) { 09454 peer->encmethods = get_encrypt_methods(v->value); 09455 } else if (!strcasecmp(v->name, "notransfer")) { 09456 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09457 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09458 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09459 } else if (!strcasecmp(v->name, "transfer")) { 09460 if (!strcasecmp(v->value, "mediaonly")) { 09461 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09462 } else if (ast_true(v->value)) { 09463 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09464 } else 09465 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09466 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09467 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09468 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09469 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09470 } else if (!strcasecmp(v->name, "host")) { 09471 if (!strcasecmp(v->value, "dynamic")) { 09472 /* They'll register with us */ 09473 ast_set_flag(peer, IAX_DYNAMIC); 09474 if (!found) { 09475 /* Initialize stuff iff we're not found, otherwise 09476 we keep going with what we had */ 09477 memset(&peer->addr.sin_addr, 0, 4); 09478 if (peer->addr.sin_port) { 09479 /* If we've already got a port, make it the default rather than absolute */ 09480 peer->defaddr.sin_port = peer->addr.sin_port; 09481 peer->addr.sin_port = 0; 09482 } 09483 } 09484 } else { 09485 /* Non-dynamic. Make sure we become that way if we're not */ 09486 AST_SCHED_DEL(sched, peer->expire); 09487 ast_clear_flag(peer, IAX_DYNAMIC); 09488 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09489 return peer_unref(peer); 09490 if (!peer->addr.sin_port) 09491 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09492 } 09493 if (!maskfound) 09494 inet_aton("255.255.255.255", &peer->mask); 09495 } else if (!strcasecmp(v->name, "defaultip")) { 09496 if (ast_get_ip(&peer->defaddr, v->value)) 09497 return peer_unref(peer); 09498 } else if (!strcasecmp(v->name, "sourceaddress")) { 09499 peer_set_srcaddr(peer, v->value); 09500 } else if (!strcasecmp(v->name, "permit") || 09501 !strcasecmp(v->name, "deny")) { 09502 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09503 } else if (!strcasecmp(v->name, "mask")) { 09504 maskfound++; 09505 inet_aton(v->value, &peer->mask); 09506 } else if (!strcasecmp(v->name, "context")) { 09507 ast_string_field_set(peer, context, v->value); 09508 } else if (!strcasecmp(v->name, "regexten")) { 09509 ast_string_field_set(peer, regexten, v->value); 09510 } else if (!strcasecmp(v->name, "peercontext")) { 09511 ast_string_field_set(peer, peercontext, v->value); 09512 } else if (!strcasecmp(v->name, "port")) { 09513 if (ast_test_flag(peer, IAX_DYNAMIC)) 09514 peer->defaddr.sin_port = htons(atoi(v->value)); 09515 else 09516 peer->addr.sin_port = htons(atoi(v->value)); 09517 } else if (!strcasecmp(v->name, "username")) { 09518 ast_string_field_set(peer, username, v->value); 09519 } else if (!strcasecmp(v->name, "allow")) { 09520 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09521 } else if (!strcasecmp(v->name, "disallow")) { 09522 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09523 } else if (!strcasecmp(v->name, "callerid")) { 09524 if (!ast_strlen_zero(v->value)) { 09525 char name2[80]; 09526 char num2[80]; 09527 ast_callerid_split(v->value, name2, 80, num2, 80); 09528 ast_string_field_set(peer, cid_name, name2); 09529 ast_string_field_set(peer, cid_num, num2); 09530 ast_set_flag(peer, IAX_HASCALLERID); 09531 } else { 09532 ast_clear_flag(peer, IAX_HASCALLERID); 09533 ast_string_field_set(peer, cid_name, ""); 09534 ast_string_field_set(peer, cid_num, ""); 09535 } 09536 } else if (!strcasecmp(v->name, "fullname")) { 09537 if (!ast_strlen_zero(v->value)) { 09538 ast_string_field_set(peer, cid_name, v->value); 09539 ast_set_flag(peer, IAX_HASCALLERID); 09540 } else { 09541 ast_string_field_set(peer, cid_name, ""); 09542 if (ast_strlen_zero(peer->cid_num)) 09543 ast_clear_flag(peer, IAX_HASCALLERID); 09544 } 09545 } else if (!strcasecmp(v->name, "cid_number")) { 09546 if (!ast_strlen_zero(v->value)) { 09547 ast_string_field_set(peer, cid_num, v->value); 09548 ast_set_flag(peer, IAX_HASCALLERID); 09549 } else { 09550 ast_string_field_set(peer, cid_num, ""); 09551 if (ast_strlen_zero(peer->cid_name)) 09552 ast_clear_flag(peer, IAX_HASCALLERID); 09553 } 09554 } else if (!strcasecmp(v->name, "sendani")) { 09555 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09556 } else if (!strcasecmp(v->name, "inkeys")) { 09557 ast_string_field_set(peer, inkeys, v->value); 09558 } else if (!strcasecmp(v->name, "outkey")) { 09559 ast_string_field_set(peer, outkey, v->value); 09560 } else if (!strcasecmp(v->name, "qualify")) { 09561 if (!strcasecmp(v->value, "no")) { 09562 peer->maxms = 0; 09563 } else if (!strcasecmp(v->value, "yes")) { 09564 peer->maxms = DEFAULT_MAXMS; 09565 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09566 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); 09567 peer->maxms = 0; 09568 } 09569 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09570 peer->smoothing = ast_true(v->value); 09571 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09572 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09573 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); 09574 } 09575 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09576 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09577 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); 09578 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09579 } else if (!strcasecmp(v->name, "timezone")) { 09580 ast_string_field_set(peer, zonetag, v->value); 09581 } else if (!strcasecmp(v->name, "adsi")) { 09582 peer->adsi = ast_true(v->value); 09583 }/* else if (strcasecmp(v->name,"type")) */ 09584 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09585 v = v->next; 09586 if (!v) { 09587 v = alt; 09588 alt = NULL; 09589 } 09590 } 09591 if (!peer->authmethods) 09592 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09593 ast_clear_flag(peer, IAX_DELME); 09594 /* Make sure these are IPv4 addresses */ 09595 peer->addr.sin_family = AF_INET; 09596 } 09597 if (oldha) 09598 ast_free_ha(oldha); 09599 return peer; 09600 }
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 9616 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.
09617 { 09618 struct iax2_user *user = NULL; 09619 struct iax2_context *con, *conl = NULL; 09620 struct ast_ha *oldha = NULL; 09621 struct iax2_context *oldcon = NULL; 09622 int format; 09623 int firstpass=1; 09624 int oldcurauthreq = 0; 09625 char *varname = NULL, *varval = NULL; 09626 struct ast_variable *tmpvar = NULL; 09627 struct iax2_user tmp_user = { 09628 .name = name, 09629 }; 09630 09631 if (!temponly) { 09632 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09633 if (user && !ast_test_flag(user, IAX_DELME)) 09634 firstpass = 0; 09635 } 09636 09637 if (user) { 09638 if (firstpass) { 09639 oldcurauthreq = user->curauthreq; 09640 oldha = user->ha; 09641 oldcon = user->contexts; 09642 user->ha = NULL; 09643 user->contexts = NULL; 09644 } 09645 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09646 ao2_unlink(users, user); 09647 } else { 09648 user = ao2_alloc(sizeof(*user), user_destructor); 09649 } 09650 09651 if (user) { 09652 if (firstpass) { 09653 ast_string_field_free_memory(user); 09654 memset(user, 0, sizeof(struct iax2_user)); 09655 if (ast_string_field_init(user, 32)) { 09656 user = user_unref(user); 09657 goto cleanup; 09658 } 09659 user->maxauthreq = maxauthreq; 09660 user->curauthreq = oldcurauthreq; 09661 user->prefs = prefs; 09662 user->capability = iax2_capability; 09663 user->encmethods = iax2_encryption; 09664 user->adsi = adsi; 09665 ast_string_field_set(user, name, name); 09666 ast_string_field_set(user, language, language); 09667 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09668 ast_clear_flag(user, IAX_HASCALLERID); 09669 ast_string_field_set(user, cid_name, ""); 09670 ast_string_field_set(user, cid_num, ""); 09671 } 09672 if (!v) { 09673 v = alt; 09674 alt = NULL; 09675 } 09676 while(v) { 09677 if (!strcasecmp(v->name, "context")) { 09678 con = build_context(v->value); 09679 if (con) { 09680 if (conl) 09681 conl->next = con; 09682 else 09683 user->contexts = con; 09684 conl = con; 09685 } 09686 } else if (!strcasecmp(v->name, "permit") || 09687 !strcasecmp(v->name, "deny")) { 09688 user->ha = ast_append_ha(v->name, v->value, user->ha); 09689 } else if (!strcasecmp(v->name, "setvar")) { 09690 varname = ast_strdupa(v->value); 09691 if (varname && (varval = strchr(varname,'='))) { 09692 *varval = '\0'; 09693 varval++; 09694 if((tmpvar = ast_variable_new(varname, varval))) { 09695 tmpvar->next = user->vars; 09696 user->vars = tmpvar; 09697 } 09698 } 09699 } else if (!strcasecmp(v->name, "allow")) { 09700 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09701 } else if (!strcasecmp(v->name, "disallow")) { 09702 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09703 } else if (!strcasecmp(v->name, "trunk")) { 09704 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09705 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09706 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09707 ast_clear_flag(user, IAX_TRUNK); 09708 } 09709 } else if (!strcasecmp(v->name, "auth")) { 09710 user->authmethods = get_auth_methods(v->value); 09711 } else if (!strcasecmp(v->name, "encryption")) { 09712 user->encmethods = get_encrypt_methods(v->value); 09713 } else if (!strcasecmp(v->name, "notransfer")) { 09714 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09715 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09716 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09717 } else if (!strcasecmp(v->name, "transfer")) { 09718 if (!strcasecmp(v->value, "mediaonly")) { 09719 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09720 } else if (ast_true(v->value)) { 09721 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09722 } else 09723 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09724 } else if (!strcasecmp(v->name, "codecpriority")) { 09725 if(!strcasecmp(v->value, "caller")) 09726 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09727 else if(!strcasecmp(v->value, "disabled")) 09728 ast_set_flag(user, IAX_CODEC_NOPREFS); 09729 else if(!strcasecmp(v->value, "reqonly")) { 09730 ast_set_flag(user, IAX_CODEC_NOCAP); 09731 ast_set_flag(user, IAX_CODEC_NOPREFS); 09732 } 09733 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09734 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09735 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09736 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09737 } else if (!strcasecmp(v->name, "dbsecret")) { 09738 ast_string_field_set(user, dbsecret, v->value); 09739 } else if (!strcasecmp(v->name, "secret")) { 09740 if (!ast_strlen_zero(user->secret)) { 09741 char *old = ast_strdupa(user->secret); 09742 09743 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09744 } else 09745 ast_string_field_set(user, secret, v->value); 09746 } else if (!strcasecmp(v->name, "callerid")) { 09747 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09748 char name2[80]; 09749 char num2[80]; 09750 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09751 ast_string_field_set(user, cid_name, name2); 09752 ast_string_field_set(user, cid_num, num2); 09753 ast_set_flag(user, IAX_HASCALLERID); 09754 } else { 09755 ast_clear_flag(user, IAX_HASCALLERID); 09756 ast_string_field_set(user, cid_name, ""); 09757 ast_string_field_set(user, cid_num, ""); 09758 } 09759 } else if (!strcasecmp(v->name, "fullname")) { 09760 if (!ast_strlen_zero(v->value)) { 09761 ast_string_field_set(user, cid_name, v->value); 09762 ast_set_flag(user, IAX_HASCALLERID); 09763 } else { 09764 ast_string_field_set(user, cid_name, ""); 09765 if (ast_strlen_zero(user->cid_num)) 09766 ast_clear_flag(user, IAX_HASCALLERID); 09767 } 09768 } else if (!strcasecmp(v->name, "cid_number")) { 09769 if (!ast_strlen_zero(v->value)) { 09770 ast_string_field_set(user, cid_num, v->value); 09771 ast_set_flag(user, IAX_HASCALLERID); 09772 } else { 09773 ast_string_field_set(user, cid_num, ""); 09774 if (ast_strlen_zero(user->cid_name)) 09775 ast_clear_flag(user, IAX_HASCALLERID); 09776 } 09777 } else if (!strcasecmp(v->name, "accountcode")) { 09778 ast_string_field_set(user, accountcode, v->value); 09779 } else if (!strcasecmp(v->name, "mohinterpret")) { 09780 ast_string_field_set(user, mohinterpret, v->value); 09781 } else if (!strcasecmp(v->name, "mohsuggest")) { 09782 ast_string_field_set(user, mohsuggest, v->value); 09783 } else if (!strcasecmp(v->name, "language")) { 09784 ast_string_field_set(user, language, v->value); 09785 } else if (!strcasecmp(v->name, "amaflags")) { 09786 format = ast_cdr_amaflags2int(v->value); 09787 if (format < 0) { 09788 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09789 } else { 09790 user->amaflags = format; 09791 } 09792 } else if (!strcasecmp(v->name, "inkeys")) { 09793 ast_string_field_set(user, inkeys, v->value); 09794 } else if (!strcasecmp(v->name, "maxauthreq")) { 09795 user->maxauthreq = atoi(v->value); 09796 if (user->maxauthreq < 0) 09797 user->maxauthreq = 0; 09798 } else if (!strcasecmp(v->name, "adsi")) { 09799 user->adsi = ast_true(v->value); 09800 }/* else if (strcasecmp(v->name,"type")) */ 09801 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09802 v = v->next; 09803 if (!v) { 09804 v = alt; 09805 alt = NULL; 09806 } 09807 } 09808 if (!user->authmethods) { 09809 if (!ast_strlen_zero(user->secret)) { 09810 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09811 if (!ast_strlen_zero(user->inkeys)) 09812 user->authmethods |= IAX_AUTH_RSA; 09813 } else if (!ast_strlen_zero(user->inkeys)) { 09814 user->authmethods = IAX_AUTH_RSA; 09815 } else { 09816 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09817 } 09818 } 09819 ast_clear_flag(user, IAX_DELME); 09820 } 09821 cleanup: 09822 if (oldha) 09823 ast_free_ha(oldha); 09824 if (oldcon) 09825 free_context(oldcon); 09826 return user; 09827 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10332 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().
10333 { 10334 struct sockaddr_in sin; 10335 int x; 10336 int callno; 10337 struct iax_ie_data ied; 10338 struct create_addr_info cai; 10339 struct parsed_dial_string pds; 10340 char *tmpstr; 10341 10342 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10343 /* Look for an *exact match* call. Once a call is negotiated, it can only 10344 look up entries for a single context */ 10345 if (!ast_mutex_trylock(&iaxsl[x])) { 10346 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10347 return x; 10348 ast_mutex_unlock(&iaxsl[x]); 10349 } 10350 } 10351 10352 /* No match found, we need to create a new one */ 10353 10354 memset(&cai, 0, sizeof(cai)); 10355 memset(&ied, 0, sizeof(ied)); 10356 memset(&pds, 0, sizeof(pds)); 10357 10358 tmpstr = ast_strdupa(data); 10359 parse_dial_string(tmpstr, &pds); 10360 10361 if (ast_strlen_zero(pds.peer)) { 10362 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10363 return -1; 10364 } 10365 10366 /* Populate our address from the given */ 10367 if (create_addr(pds.peer, NULL, &sin, &cai)) 10368 return -1; 10369 10370 if (option_debug) 10371 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10372 pds.peer, pds.username, pds.password, pds.context); 10373 10374 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10375 if (callno < 1) { 10376 ast_log(LOG_WARNING, "Unable to create call\n"); 10377 return -1; 10378 } 10379 10380 ast_string_field_set(iaxs[callno], dproot, data); 10381 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10382 10383 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10384 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10385 /* the string format is slightly different from a standard dial string, 10386 because the context appears in the 'exten' position 10387 */ 10388 if (pds.exten) 10389 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10390 if (pds.username) 10391 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10392 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10393 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10394 /* Keep password handy */ 10395 if (pds.password) 10396 ast_string_field_set(iaxs[callno], secret, pds.password); 10397 if (pds.key) 10398 ast_string_field_set(iaxs[callno], outkey, pds.key); 10399 /* Start the call going */ 10400 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10401 10402 return callno; 10403 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3991 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.
03992 { 03993 /* Returns where in "receive time" we are. That is, how many ms 03994 since we received (or would have received) the frame with timestamp 0 */ 03995 int ms; 03996 #ifdef IAXTESTS 03997 int jit; 03998 #endif /* IAXTESTS */ 03999 /* Setup rxcore if necessary */ 04000 if (ast_tvzero(p->rxcore)) { 04001 p->rxcore = ast_tvnow(); 04002 if (option_debug && iaxdebug) 04003 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 04004 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 04005 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 04006 #if 1 04007 if (option_debug && iaxdebug) 04008 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 04009 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 04010 #endif 04011 } 04012 04013 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 04014 #ifdef IAXTESTS 04015 if (test_jit) { 04016 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04017 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04018 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04019 jit = -jit; 04020 ms += jit; 04021 } 04022 } 04023 if (test_late) { 04024 ms += test_late; 04025 test_late = 0; 04026 } 04027 #endif /* IAXTESTS */ 04028 return ms; 04029 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3862 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().
03863 { 03864 int ms; 03865 int voice = 0; 03866 int genuine = 0; 03867 int adjust; 03868 struct timeval *delivery = NULL; 03869 03870 03871 /* What sort of frame do we have?: voice is self-explanatory 03872 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03873 non-genuine frames are CONTROL frames [ringing etc], DTMF 03874 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03875 the others need a timestamp slaved to the voice frames so that they go in sequence 03876 */ 03877 if (f) { 03878 if (f->frametype == AST_FRAME_VOICE) { 03879 voice = 1; 03880 delivery = &f->delivery; 03881 } else if (f->frametype == AST_FRAME_IAX) { 03882 genuine = 1; 03883 } else if (f->frametype == AST_FRAME_CNG) { 03884 p->notsilenttx = 0; 03885 } 03886 } 03887 if (ast_tvzero(p->offset)) { 03888 gettimeofday(&p->offset, NULL); 03889 /* Round to nearest 20ms for nice looking traces */ 03890 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03891 } 03892 /* If the timestamp is specified, just send it as is */ 03893 if (ts) 03894 return ts; 03895 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03896 if (delivery && !ast_tvzero(*delivery)) { 03897 ms = ast_tvdiff_ms(*delivery, p->offset); 03898 if (option_debug > 2 && iaxdebug) 03899 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03900 } else { 03901 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03902 if (ms < 0) 03903 ms = 0; 03904 if (voice) { 03905 /* On a voice frame, use predicted values if appropriate */ 03906 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03907 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03908 /* AN EXPLANATION: 03909 When we send voice, we usually send "calculated" timestamps worked out 03910 on the basis of the number of samples sent. When we send other frames, 03911 we usually send timestamps worked out from the real clock. 03912 The problem is that they can tend to drift out of step because the 03913 source channel's clock and our clock may not be exactly at the same rate. 03914 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03915 for this call. Moving it adjusts timestamps for non-voice frames. 03916 We make the adjustment in the style of a moving average. Each time we 03917 adjust p->offset by 10% of the difference between our clock-derived 03918 timestamp and the predicted timestamp. That's why you see "10000" 03919 below even though IAX2 timestamps are in milliseconds. 03920 The use of a moving average avoids offset moving too radically. 03921 Generally, "adjust" roams back and forth around 0, with offset hardly 03922 changing at all. But if a consistent different starts to develop it 03923 will be eliminated over the course of 10 frames (200-300msecs) 03924 */ 03925 adjust = (ms - p->nextpred); 03926 if (adjust < 0) 03927 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03928 else if (adjust > 0) 03929 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03930 03931 if (!p->nextpred) { 03932 p->nextpred = ms; /*f->samples / 8;*/ 03933 if (p->nextpred <= p->lastsent) 03934 p->nextpred = p->lastsent + 3; 03935 } 03936 ms = p->nextpred; 03937 } else { 03938 /* in this case, just use the actual 03939 * time, since we're either way off 03940 * (shouldn't happen), or we're ending a 03941 * silent period -- and seed the next 03942 * predicted time. Also, round ms to the 03943 * next multiple of frame size (so our 03944 * silent periods are multiples of 03945 * frame size too) */ 03946 03947 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03948 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03949 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03950 03951 if (f->samples >= 8) /* check to make sure we dont core dump */ 03952 { 03953 int diff = ms % (f->samples / 8); 03954 if (diff) 03955 ms += f->samples/8 - diff; 03956 } 03957 03958 p->nextpred = ms; 03959 p->notsilenttx = 1; 03960 } 03961 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03962 /* 03963 * IAX2 draft 03 says that timestamps MUST be in order. 03964 * It does not say anything about several frames having the same timestamp 03965 * When transporting video, we can have a frame that spans multiple iax packets 03966 * (so called slices), so it would make sense to use the same timestamp for all of 03967 * them 03968 * We do want to make sure that frames don't go backwards though 03969 */ 03970 if ( (unsigned int)ms < p->lastsent ) 03971 ms = p->lastsent; 03972 } else { 03973 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03974 it's a genuine frame */ 03975 if (genuine) { 03976 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03977 if (ms <= p->lastsent) 03978 ms = p->lastsent + 3; 03979 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03980 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03981 ms = p->lastsent + 3; 03982 } 03983 } 03984 } 03985 p->lastsent = ms; 03986 if (voice) 03987 p->nextpred = p->nextpred + f->samples / 8; 03988 return ms; 03989 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3818 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().
03819 { 03820 unsigned long int mssincetx; /* unsigned to handle overflows */ 03821 long int ms, pred; 03822 03823 tpeer->trunkact = *tv; 03824 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03825 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03826 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03827 tpeer->txtrunktime = *tv; 03828 tpeer->lastsent = 999999; 03829 } 03830 /* Update last transmit time now */ 03831 tpeer->lasttxtime = *tv; 03832 03833 /* Calculate ms offset */ 03834 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03835 /* Predict from last value */ 03836 pred = tpeer->lastsent + sampms; 03837 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03838 ms = pred; 03839 03840 /* We never send the same timestamp twice, so fudge a little if we must */ 03841 if (ms == tpeer->lastsent) 03842 ms = tpeer->lastsent + 1; 03843 tpeer->lastsent = ms; 03844 return ms; 03845 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5116 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().
05117 { 05118 /* Start pessimistic */ 05119 int res = -1; 05120 int version = 2; 05121 struct iax2_user *user = NULL, *best = NULL; 05122 int bestscore = 0; 05123 int gotcapability = 0; 05124 struct ast_variable *v = NULL, *tmpvar = NULL; 05125 struct ao2_iterator i; 05126 05127 if (!iaxs[callno]) 05128 return res; 05129 if (ies->called_number) 05130 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05131 if (ies->calling_number) { 05132 ast_shrink_phone_number(ies->calling_number); 05133 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05134 } 05135 if (ies->calling_name) 05136 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05137 if (ies->calling_ani) 05138 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05139 if (ies->dnid) 05140 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05141 if (ies->rdnis) 05142 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05143 if (ies->called_context) 05144 ast_string_field_set(iaxs[callno], context, ies->called_context); 05145 if (ies->language) 05146 ast_string_field_set(iaxs[callno], language, ies->language); 05147 if (ies->username) 05148 ast_string_field_set(iaxs[callno], username, ies->username); 05149 if (ies->calling_ton > -1) 05150 iaxs[callno]->calling_ton = ies->calling_ton; 05151 if (ies->calling_tns > -1) 05152 iaxs[callno]->calling_tns = ies->calling_tns; 05153 if (ies->calling_pres > -1) 05154 iaxs[callno]->calling_pres = ies->calling_pres; 05155 if (ies->format) 05156 iaxs[callno]->peerformat = ies->format; 05157 if (ies->adsicpe) 05158 iaxs[callno]->peeradsicpe = ies->adsicpe; 05159 if (ies->capability) { 05160 gotcapability = 1; 05161 iaxs[callno]->peercapability = ies->capability; 05162 } 05163 if (ies->version) 05164 version = ies->version; 05165 05166 /* Use provided preferences until told otherwise for actual preferences */ 05167 if(ies->codec_prefs) { 05168 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05169 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05170 } 05171 05172 if (!gotcapability) 05173 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05174 if (version > IAX_PROTO_VERSION) { 05175 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05176 ast_inet_ntoa(sin->sin_addr), version); 05177 return res; 05178 } 05179 /* Search the userlist for a compatible entry, and fill in the rest */ 05180 i = ao2_iterator_init(users, 0); 05181 while ((user = ao2_iterator_next(&i))) { 05182 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05183 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05184 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05185 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05186 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05187 if (!ast_strlen_zero(iaxs[callno]->username)) { 05188 /* Exact match, stop right now. */ 05189 if (best) 05190 user_unref(best); 05191 best = user; 05192 break; 05193 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05194 /* No required authentication */ 05195 if (user->ha) { 05196 /* There was host authentication and we passed, bonus! */ 05197 if (bestscore < 4) { 05198 bestscore = 4; 05199 if (best) 05200 user_unref(best); 05201 best = user; 05202 continue; 05203 } 05204 } else { 05205 /* No host access, but no secret, either, not bad */ 05206 if (bestscore < 3) { 05207 bestscore = 3; 05208 if (best) 05209 user_unref(best); 05210 best = user; 05211 continue; 05212 } 05213 } 05214 } else { 05215 if (user->ha) { 05216 /* Authentication, but host access too, eh, it's something.. */ 05217 if (bestscore < 2) { 05218 bestscore = 2; 05219 if (best) 05220 user_unref(best); 05221 best = user; 05222 continue; 05223 } 05224 } else { 05225 /* Authentication and no host access... This is our baseline */ 05226 if (bestscore < 1) { 05227 bestscore = 1; 05228 if (best) 05229 user_unref(best); 05230 best = user; 05231 continue; 05232 } 05233 } 05234 } 05235 } 05236 user_unref(user); 05237 } 05238 user = best; 05239 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05240 user = realtime_user(iaxs[callno]->username, sin); 05241 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05242 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05243 user = user_unref(user); 05244 } 05245 } 05246 if (user) { 05247 /* We found our match (use the first) */ 05248 /* copy vars */ 05249 for (v = user->vars ; v ; v = v->next) { 05250 if((tmpvar = ast_variable_new(v->name, v->value))) { 05251 tmpvar->next = iaxs[callno]->vars; 05252 iaxs[callno]->vars = tmpvar; 05253 } 05254 } 05255 /* If a max AUTHREQ restriction is in place, activate it */ 05256 if (user->maxauthreq > 0) 05257 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05258 iaxs[callno]->prefs = user->prefs; 05259 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05260 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05261 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05262 iaxs[callno]->encmethods = user->encmethods; 05263 /* Store the requested username if not specified */ 05264 if (ast_strlen_zero(iaxs[callno]->username)) 05265 ast_string_field_set(iaxs[callno], username, user->name); 05266 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05267 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05268 iaxs[callno]->capability = user->capability; 05269 /* And use the default context */ 05270 if (ast_strlen_zero(iaxs[callno]->context)) { 05271 if (user->contexts) 05272 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05273 else 05274 ast_string_field_set(iaxs[callno], context, context); 05275 } 05276 /* And any input keys */ 05277 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05278 /* And the permitted authentication methods */ 05279 iaxs[callno]->authmethods = user->authmethods; 05280 iaxs[callno]->adsi = user->adsi; 05281 /* If they have callerid, override the given caller id. Always store the ANI */ 05282 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05283 if (ast_test_flag(user, IAX_HASCALLERID)) { 05284 iaxs[callno]->calling_tns = 0; 05285 iaxs[callno]->calling_ton = 0; 05286 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05287 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05288 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05289 } 05290 if (ast_strlen_zero(iaxs[callno]->ani)) 05291 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05292 } else { 05293 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05294 } 05295 if (!ast_strlen_zero(user->accountcode)) 05296 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05297 if (!ast_strlen_zero(user->mohinterpret)) 05298 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05299 if (!ast_strlen_zero(user->mohsuggest)) 05300 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05301 if (user->amaflags) 05302 iaxs[callno]->amaflags = user->amaflags; 05303 if (!ast_strlen_zero(user->language)) 05304 ast_string_field_set(iaxs[callno], language, user->language); 05305 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05306 /* Keep this check last */ 05307 if (!ast_strlen_zero(user->dbsecret)) { 05308 char *family, *key=NULL; 05309 char buf[80]; 05310 family = ast_strdupa(user->dbsecret); 05311 key = strchr(family, '/'); 05312 if (key) { 05313 *key = '\0'; 05314 key++; 05315 } 05316 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05317 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05318 else 05319 ast_string_field_set(iaxs[callno], secret, buf); 05320 } else 05321 ast_string_field_set(iaxs[callno], secret, user->secret); 05322 res = 0; 05323 user = user_unref(user); 05324 } else { 05325 /* user was not found, but we should still fake an AUTHREQ. 05326 * Set authmethods to the last known authmethod used by the system 05327 * Set a fake secret, it's not looked at, just required to attempt authentication. 05328 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 05329 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 05330 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05331 iaxs[callno]->authrej = 1; 05332 if (!ast_strlen_zero(iaxs[callno]->username)) { 05333 /* only send the AUTHREQ if a username was specified. */ 05334 res = 0; 05335 } 05336 } 05337 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05338 return res; 05339 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6847 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.
Referenced by socket_process().
06848 { 06849 unsigned int ourver; 06850 char rsi[80]; 06851 snprintf(rsi, sizeof(rsi), "si-%s", si); 06852 if (iax_provision_version(&ourver, rsi, 1)) 06853 return 0; 06854 if (option_debug) 06855 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06856 if (ourver != ver) 06857 iax2_provision(sin, sockfd, NULL, rsi, 1); 06858 return 0; 06859 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9255 of file chan_iax2.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09256 { 09257 int sd; 09258 int res; 09259 09260 sd = socket(AF_INET, SOCK_DGRAM, 0); 09261 if (sd < 0) { 09262 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09263 return -1; 09264 } 09265 09266 res = bind(sd, sa, salen); 09267 if (res < 0) { 09268 if (option_debug) 09269 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09270 close(sd); 09271 return 1; 09272 } 09273 09274 close(sd); 09275 return 0; 09276 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5842 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().
05843 { 05844 char exten[256] = ""; 05845 int status = CACHE_FLAG_UNKNOWN; 05846 int expiry = iaxdefaultdpcache; 05847 int x; 05848 int matchmore = 0; 05849 struct iax2_dpcache *dp, *prev; 05850 05851 if (ies->called_number) 05852 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05853 05854 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05855 status = CACHE_FLAG_EXISTS; 05856 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05857 status = CACHE_FLAG_CANEXIST; 05858 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05859 status = CACHE_FLAG_NONEXISTENT; 05860 05861 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05862 /* Don't really do anything with this */ 05863 } 05864 if (ies->refresh) 05865 expiry = ies->refresh; 05866 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05867 matchmore = CACHE_FLAG_MATCHMORE; 05868 ast_mutex_lock(&dpcache_lock); 05869 prev = NULL; 05870 dp = pvt->dpentries; 05871 while(dp) { 05872 if (!strcmp(dp->exten, exten)) { 05873 /* Let them go */ 05874 if (prev) 05875 prev->peer = dp->peer; 05876 else 05877 pvt->dpentries = dp->peer; 05878 dp->peer = NULL; 05879 dp->callno = 0; 05880 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05881 if (dp->flags & CACHE_FLAG_PENDING) { 05882 dp->flags &= ~CACHE_FLAG_PENDING; 05883 dp->flags |= status; 05884 dp->flags |= matchmore; 05885 } 05886 /* Wake up waiters */ 05887 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05888 if (dp->waiters[x] > -1) 05889 write(dp->waiters[x], "asdf", 4); 05890 } 05891 prev = dp; 05892 dp = dp->peer; 05893 } 05894 ast_mutex_unlock(&dpcache_lock); 05895 return 0; 05896 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2410 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02411 { 02412 int which = 0; 02413 struct iax2_peer *peer; 02414 char *res = NULL; 02415 int wordlen = strlen(word); 02416 struct ao2_iterator i; 02417 02418 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02419 if (pos != 3) 02420 return NULL; 02421 02422 i = ao2_iterator_init(peers, 0); 02423 while ((peer = ao2_iterator_next(&i))) { 02424 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02425 res = ast_strdup(peer->name); 02426 peer_unref(peer); 02427 break; 02428 } 02429 peer_unref(peer); 02430 } 02431 02432 return res; 02433 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5898 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().
05899 { 05900 int peercallno = 0; 05901 struct chan_iax2_pvt *pvt = iaxs[callno]; 05902 struct iax_frame *cur; 05903 jb_frame frame; 05904 05905 if (ies->callno) 05906 peercallno = ies->callno; 05907 05908 if (peercallno < 1) { 05909 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05910 return -1; 05911 } 05912 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05913 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05914 /* Reset sequence numbers */ 05915 pvt->oseqno = 0; 05916 pvt->rseqno = 0; 05917 pvt->iseqno = 0; 05918 pvt->aseqno = 0; 05919 05920 if (pvt->peercallno) { 05921 remove_by_peercallno(pvt); 05922 } 05923 pvt->peercallno = peercallno; 05924 store_by_peercallno(pvt); 05925 05926 pvt->transferring = TRANSFER_NONE; 05927 pvt->svoiceformat = -1; 05928 pvt->voiceformat = 0; 05929 pvt->svideoformat = -1; 05930 pvt->videoformat = 0; 05931 pvt->transfercallno = -1; 05932 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05933 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05934 /* reset jitterbuffer */ 05935 while(jb_getall(pvt->jb,&frame) == JB_OK) 05936 iax2_frame_free(frame.data); 05937 jb_reset(pvt->jb); 05938 pvt->lag = 0; 05939 pvt->last = 0; 05940 pvt->lastsent = 0; 05941 pvt->nextpred = 0; 05942 pvt->pingtime = DEFAULT_RETRY_TIME; 05943 AST_LIST_LOCK(&iaxq.queue); 05944 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05945 /* We must cancel any packets that would have been transmitted 05946 because now we're talking to someone new. It's okay, they 05947 were transmitted to someone that didn't care anyway. */ 05948 if (callno == cur->callno) 05949 cur->retries = -1; 05950 } 05951 AST_LIST_UNLOCK(&iaxq.queue); 05952 return 0; 05953 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1071 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().
01072 { 01073 int x; 01074 int power=-1; 01075 /* If it's 128 or smaller, just return it */ 01076 if (subclass < IAX_FLAG_SC_LOG) 01077 return subclass; 01078 /* Otherwise find its power */ 01079 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01080 if (subclass & (1 << x)) { 01081 if (power > -1) { 01082 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01083 return 0; 01084 } else 01085 power = x; 01086 } 01087 } 01088 return power | IAX_FLAG_SC_LOG; 01089 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6861 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().
06862 { 06863 jb_info stats; 06864 jb_getinfo(pvt->jb, &stats); 06865 06866 memset(iep, 0, sizeof(*iep)); 06867 06868 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06869 if(stats.frames_in == 0) stats.frames_in = 1; 06870 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06871 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06872 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06873 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06874 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06875 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3027 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.
03028 { 03029 struct ast_hostent ahp; 03030 struct hostent *hp; 03031 struct iax2_peer *peer; 03032 int res = -1; 03033 struct ast_codec_pref ourprefs; 03034 03035 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03036 cai->sockfd = defaultsockfd; 03037 cai->maxtime = 0; 03038 sin->sin_family = AF_INET; 03039 03040 if (!(peer = find_peer(peername, 1))) { 03041 cai->found = 0; 03042 03043 hp = ast_gethostbyname(peername, &ahp); 03044 if (hp) { 03045 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03046 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03047 /* use global iax prefs for unknown peer/user */ 03048 /* But move the calling channel's native codec to the top of the preference list */ 03049 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03050 if (c) 03051 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03052 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03053 return 0; 03054 } else { 03055 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03056 return -1; 03057 } 03058 } 03059 03060 cai->found = 1; 03061 03062 /* if the peer has no address (current or default), return failure */ 03063 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03064 goto return_unref; 03065 03066 /* if the peer is being monitored and is currently unreachable, return failure */ 03067 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03068 goto return_unref; 03069 03070 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03071 cai->maxtime = peer->maxms; 03072 cai->capability = peer->capability; 03073 cai->encmethods = peer->encmethods; 03074 cai->sockfd = peer->sockfd; 03075 cai->adsi = peer->adsi; 03076 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03077 /* Move the calling channel's native codec to the top of the preference list */ 03078 if (c) { 03079 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03080 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03081 } 03082 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03083 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03084 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03085 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03086 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03087 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03088 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03089 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03090 if (ast_strlen_zero(peer->dbsecret)) { 03091 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03092 } else { 03093 char *family; 03094 char *key = NULL; 03095 03096 family = ast_strdupa(peer->dbsecret); 03097 key = strchr(family, '/'); 03098 if (key) 03099 *key++ = '\0'; 03100 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03101 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03102 goto return_unref; 03103 } 03104 } 03105 03106 if (peer->addr.sin_addr.s_addr) { 03107 sin->sin_addr = peer->addr.sin_addr; 03108 sin->sin_port = peer->addr.sin_port; 03109 } else { 03110 sin->sin_addr = peer->defaddr.sin_addr; 03111 sin->sin_port = peer->defaddr.sin_port; 03112 } 03113 03114 res = 0; 03115 03116 return_unref: 03117 peer_unref(peer); 03118 03119 return res; 03120 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4186 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(), and update_packet().
04187 { 04188 int padding; 04189 unsigned char *workspace; 04190 04191 workspace = alloca(*datalen); 04192 memset(f, 0, sizeof(*f)); 04193 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04194 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04195 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04196 return -1; 04197 /* Decrypt */ 04198 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04199 04200 padding = 16 + (workspace[15] & 0xf); 04201 if (option_debug && iaxdebug) 04202 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04203 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04204 return -1; 04205 04206 *datalen -= padding; 04207 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04208 f->frametype = fh->type; 04209 if (f->frametype == AST_FRAME_VIDEO) { 04210 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04211 } else { 04212 f->subclass = uncompress_subclass(fh->csub); 04213 } 04214 } else { 04215 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04216 if (option_debug && iaxdebug) 04217 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04218 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04219 return -1; 04220 /* Decrypt */ 04221 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04222 padding = 16 + (workspace[15] & 0x0f); 04223 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04224 return -1; 04225 *datalen -= padding; 04226 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04227 } 04228 return 0; 04229 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4272 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), iax2_registry::secret, and strsep().
Referenced by socket_process().
04273 { 04274 int res=-1; 04275 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04276 /* Search for possible keys, given secrets */ 04277 struct MD5Context md5; 04278 unsigned char digest[16]; 04279 char *tmppw, *stringp; 04280 04281 tmppw = ast_strdupa(iaxs[callno]->secret); 04282 stringp = tmppw; 04283 while ((tmppw = strsep(&stringp, ";"))) { 04284 MD5Init(&md5); 04285 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04286 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04287 MD5Final(digest, &md5); 04288 build_encryption_keys(digest, iaxs[callno]); 04289 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04290 if (!res) { 04291 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04292 break; 04293 } 04294 } 04295 } else 04296 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04297 return res; 04298 }
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 6923 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().
06924 { 06925 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06926 struct ast_iax2_full_hdr *fh, *cur_fh; 06927 06928 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06929 return; 06930 06931 pkt_buf->len = from_here->buf_len; 06932 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06933 06934 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06935 ast_mutex_lock(&to_here->lock); 06936 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06937 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06938 if (fh->oseqno < cur_fh->oseqno) { 06939 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06940 break; 06941 } 06942 } 06943 AST_LIST_TRAVERSE_SAFE_END 06944 06945 if (!cur_pkt_buf) 06946 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06947 06948 ast_mutex_unlock(&to_here->lock); 06949 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9847 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.
09848 { 09849 struct iax2_registry *reg; 09850 09851 ao2_callback(users, 0, user_delme_cb, NULL); 09852 09853 AST_LIST_LOCK(®istrations); 09854 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09855 ast_sched_del(sched, reg->expire); 09856 if (reg->callno) { 09857 ast_mutex_lock(&iaxsl[reg->callno]); 09858 if (iaxs[reg->callno]) { 09859 iaxs[reg->callno]->reg = NULL; 09860 iax2_destroy(reg->callno); 09861 } 09862 ast_mutex_unlock(&iaxsl[reg->callno]); 09863 } 09864 if (reg->dnsmgr) 09865 ast_dnsmgr_release(reg->dnsmgr); 09866 free(reg); 09867 } 09868 AST_LIST_UNLOCK(®istrations); 09869 09870 ao2_callback(peers, 0, peer_delme_cb, NULL); 09871 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1750 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01751 { 01752 /* Close firmware */ 01753 if (cur->fwh) { 01754 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01755 } 01756 close(cur->fd); 01757 free(cur); 01758 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6695 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().
06696 { 06697 unsigned short dpstatus = 0; 06698 struct iax_ie_data ied1; 06699 int mm; 06700 06701 memset(&ied1, 0, sizeof(ied1)); 06702 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06703 /* Must be started */ 06704 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06705 dpstatus = IAX_DPSTATUS_EXISTS; 06706 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06707 dpstatus = IAX_DPSTATUS_CANEXIST; 06708 } else { 06709 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06710 } 06711 if (ast_ignore_pattern(context, callednum)) 06712 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06713 if (mm) 06714 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06715 if (!skiplock) 06716 ast_mutex_lock(&iaxsl[callno]); 06717 if (iaxs[callno]) { 06718 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06719 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06720 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06721 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06722 } 06723 if (!skiplock) 06724 ast_mutex_unlock(&iaxsl[callno]); 06725 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6727 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().
06728 { 06729 /* Look up for dpreq */ 06730 struct dpreq_data *dpr = data; 06731 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06732 if (dpr->callerid) 06733 free(dpr->callerid); 06734 free(dpr); 06735 return NULL; 06736 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4231 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(), and update_packet().
04232 { 04233 int padding; 04234 unsigned char *workspace; 04235 workspace = alloca(*datalen + 32); 04236 if (!workspace) 04237 return -1; 04238 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04239 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04240 if (option_debug && iaxdebug) 04241 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04242 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04243 padding = 16 + (padding & 0xf); 04244 memcpy(workspace, poo, padding); 04245 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04246 workspace[15] &= 0xf0; 04247 workspace[15] |= (padding & 0xf); 04248 if (option_debug && iaxdebug) 04249 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]); 04250 *datalen += padding; 04251 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04252 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04253 memcpy(poo, workspace + *datalen - 32, 32); 04254 } else { 04255 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04256 if (option_debug && iaxdebug) 04257 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04258 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04259 padding = 16 + (padding & 0xf); 04260 memcpy(workspace, poo, padding); 04261 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04262 workspace[15] &= 0xf0; 04263 workspace[15] |= (padding & 0x0f); 04264 *datalen += padding; 04265 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04266 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04267 memcpy(poo, workspace + *datalen - 32, 32); 04268 } 04269 return 0; 04270 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6135 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
06136 { 06137 #ifdef SCHED_MULTITHREADED 06138 if (schedule_action(__expire_registry, data)) 06139 #endif 06140 __expire_registry(data); 06141 return 0; 06142 }
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 10405 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().
10406 { 10407 struct iax2_dpcache *dp, *prev = NULL, *next; 10408 struct timeval tv; 10409 int x; 10410 int com[2]; 10411 int timeout; 10412 int old=0; 10413 int outfd; 10414 int abort; 10415 int callno; 10416 struct ast_channel *c; 10417 struct ast_frame *f; 10418 gettimeofday(&tv, NULL); 10419 dp = dpcache; 10420 while(dp) { 10421 next = dp->next; 10422 /* Expire old caches */ 10423 if (ast_tvcmp(tv, dp->expiry) > 0) { 10424 /* It's expired, let it disappear */ 10425 if (prev) 10426 prev->next = dp->next; 10427 else 10428 dpcache = dp->next; 10429 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10430 /* Free memory and go again */ 10431 free(dp); 10432 } else { 10433 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); 10434 } 10435 dp = next; 10436 continue; 10437 } 10438 /* We found an entry that matches us! */ 10439 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10440 break; 10441 prev = dp; 10442 dp = next; 10443 } 10444 if (!dp) { 10445 /* No matching entry. Create a new one. */ 10446 /* First, can we make a callno? */ 10447 callno = cache_get_callno_locked(data); 10448 if (callno < 0) { 10449 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10450 return NULL; 10451 } 10452 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10453 ast_mutex_unlock(&iaxsl[callno]); 10454 return NULL; 10455 } 10456 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10457 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10458 gettimeofday(&dp->expiry, NULL); 10459 dp->orig = dp->expiry; 10460 /* Expires in 30 mins by default */ 10461 dp->expiry.tv_sec += iaxdefaultdpcache; 10462 dp->next = dpcache; 10463 dp->flags = CACHE_FLAG_PENDING; 10464 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10465 dp->waiters[x] = -1; 10466 dpcache = dp; 10467 dp->peer = iaxs[callno]->dpentries; 10468 iaxs[callno]->dpentries = dp; 10469 /* Send the request if we're already up */ 10470 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10471 iax2_dprequest(dp, callno); 10472 ast_mutex_unlock(&iaxsl[callno]); 10473 } 10474 /* By here we must have a dp */ 10475 if (dp->flags & CACHE_FLAG_PENDING) { 10476 /* Okay, here it starts to get nasty. We need a pipe now to wait 10477 for a reply to come back so long as it's pending */ 10478 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10479 /* Find an empty slot */ 10480 if (dp->waiters[x] < 0) 10481 break; 10482 } 10483 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10484 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10485 return NULL; 10486 } 10487 if (pipe(com)) { 10488 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10489 return NULL; 10490 } 10491 dp->waiters[x] = com[1]; 10492 /* Okay, now we wait */ 10493 timeout = iaxdefaulttimeout * 1000; 10494 /* Temporarily unlock */ 10495 ast_mutex_unlock(&dpcache_lock); 10496 /* Defer any dtmf */ 10497 if (chan) 10498 old = ast_channel_defer_dtmf(chan); 10499 abort = 0; 10500 while(timeout) { 10501 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10502 if (outfd > -1) { 10503 break; 10504 } 10505 if (c) { 10506 f = ast_read(c); 10507 if (f) 10508 ast_frfree(f); 10509 else { 10510 /* Got hung up on, abort! */ 10511 break; 10512 abort = 1; 10513 } 10514 } 10515 } 10516 if (!timeout) { 10517 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10518 } 10519 ast_mutex_lock(&dpcache_lock); 10520 dp->waiters[x] = -1; 10521 close(com[1]); 10522 close(com[0]); 10523 if (abort) { 10524 /* Don't interpret anything, just abort. Not sure what th epoint 10525 of undeferring dtmf on a hung up channel is but hey whatever */ 10526 if (!old && chan) 10527 ast_channel_undefer_dtmf(chan); 10528 return NULL; 10529 } 10530 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10531 /* Now to do non-independent analysis the results of our wait */ 10532 if (dp->flags & CACHE_FLAG_PENDING) { 10533 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10534 pending. Don't let it take as long to timeout. */ 10535 dp->flags &= ~CACHE_FLAG_PENDING; 10536 dp->flags |= CACHE_FLAG_TIMEOUT; 10537 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10538 systems without leaving it unavailable once the server comes back online */ 10539 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10540 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10541 if (dp->waiters[x] > -1) 10542 write(dp->waiters[x], "asdf", 4); 10543 } 10544 } 10545 /* Our caller will obtain the rest */ 10546 if (!old && chan) 10547 ast_channel_undefer_dtmf(chan); 10548 } 10549 return dp; 10550 }
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 1650 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01650 { 01651 01652 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01653 }
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 1655 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01655 { 01656 01657 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01658 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 916 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().
00917 { 00918 pthread_attr_t attr; 00919 struct iax2_thread *thread = NULL; 00920 00921 /* Pop the head of the list off */ 00922 AST_LIST_LOCK(&idle_list); 00923 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00924 AST_LIST_UNLOCK(&idle_list); 00925 00926 /* If no idle thread is available from the regular list, try dynamic */ 00927 if (thread == NULL) { 00928 AST_LIST_LOCK(&dynamic_list); 00929 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00930 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00931 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00932 /* We need to MAKE a thread! */ 00933 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00934 thread->threadnum = iaxdynamicthreadcount; 00935 thread->type = IAX_TYPE_DYNAMIC; 00936 ast_mutex_init(&thread->lock); 00937 ast_cond_init(&thread->cond, NULL); 00938 pthread_attr_init(&attr); 00939 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00940 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00941 free(thread); 00942 thread = NULL; 00943 } else { 00944 /* All went well and the thread is up, so increment our count */ 00945 iaxdynamicthreadcount++; 00946 00947 /* Wait for the thread to be ready before returning it to the caller */ 00948 while (!thread->ready_for_signal) 00949 usleep(1); 00950 } 00951 } 00952 } 00953 AST_LIST_UNLOCK(&dynamic_list); 00954 } 00955 00956 /* this thread is not processing a full frame (since it is idle), 00957 so ensure that the field for the full frame call number is empty */ 00958 if (thread) 00959 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00960 00961 return thread; 00962 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1149 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01150 { 01151 struct iax2_peer *peer = NULL; 01152 struct iax2_peer tmp_peer = { 01153 .name = name, 01154 }; 01155 01156 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01157 01158 /* Now go for realtime if applicable */ 01159 if(!peer && realtime) 01160 peer = realtime_peer(name, NULL); 01161 01162 return peer; 01163 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 4031 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().
04032 { 04033 struct iax2_trunk_peer *tpeer; 04034 04035 /* Finds and locks trunk peer */ 04036 ast_mutex_lock(&tpeerlock); 04037 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04038 /* We don't lock here because tpeer->addr *never* changes */ 04039 if (!inaddrcmp(&tpeer->addr, sin)) { 04040 ast_mutex_lock(&tpeer->lock); 04041 break; 04042 } 04043 } 04044 if (!tpeer) { 04045 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04046 ast_mutex_init(&tpeer->lock); 04047 tpeer->lastsent = 9999; 04048 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04049 tpeer->trunkact = ast_tvnow(); 04050 ast_mutex_lock(&tpeer->lock); 04051 tpeer->next = tpeers; 04052 tpeer->sockfd = fd; 04053 tpeers = tpeer; 04054 #ifdef SO_NO_CHECK 04055 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04056 #endif 04057 if (option_debug) 04058 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04059 } 04060 } 04061 ast_mutex_unlock(&tpeerlock); 04062 return tpeer; 04063 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3847 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03848 { 03849 long ms; /* NOT unsigned */ 03850 if (ast_tvzero(iaxs[callno]->rxcore)) { 03851 /* Initialize rxcore time if appropriate */ 03852 gettimeofday(&iaxs[callno]->rxcore, NULL); 03853 /* Round to nearest 20ms so traces look pretty */ 03854 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03855 } 03856 /* Calculate difference between trunk and channel */ 03857 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03858 /* Return as the sum of trunk time and the difference between trunk and real time */ 03859 return ms + ts; 03860 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 9014 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
09015 { 09016 struct iax2_context *conl; 09017 while(con) { 09018 conl = con; 09019 con = con->next; 09020 free(conl); 09021 } 09022 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10674 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.
10675 { 10676 struct iax2_peer *peer; 10677 char *peername, *colname; 10678 10679 peername = ast_strdupa(data); 10680 10681 /* if our channel, return the IP address of the endpoint of current channel */ 10682 if (!strcmp(peername,"CURRENTCHANNEL")) { 10683 unsigned short callno; 10684 if (chan->tech != &iax2_tech) 10685 return -1; 10686 callno = PTR_TO_CALLNO(chan->tech_pvt); 10687 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10688 return 0; 10689 } 10690 10691 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10692 *colname++ = '\0'; 10693 else if ((colname = strchr(peername, '|'))) 10694 *colname++ = '\0'; 10695 else 10696 colname = "ip"; 10697 10698 if (!(peer = find_peer(peername, 1))) 10699 return -1; 10700 10701 if (!strcasecmp(colname, "ip")) { 10702 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10703 } else if (!strcasecmp(colname, "status")) { 10704 peer_status(peer, buf, len); 10705 } else if (!strcasecmp(colname, "mailbox")) { 10706 ast_copy_string(buf, peer->mailbox, len); 10707 } else if (!strcasecmp(colname, "context")) { 10708 ast_copy_string(buf, peer->context, len); 10709 } else if (!strcasecmp(colname, "expire")) { 10710 snprintf(buf, len, "%d", peer->expire); 10711 } else if (!strcasecmp(colname, "dynamic")) { 10712 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10713 } else if (!strcasecmp(colname, "callerid_name")) { 10714 ast_copy_string(buf, peer->cid_name, len); 10715 } else if (!strcasecmp(colname, "callerid_num")) { 10716 ast_copy_string(buf, peer->cid_num, len); 10717 } else if (!strcasecmp(colname, "codecs")) { 10718 ast_getformatname_multiple(buf, len -1, peer->capability); 10719 } else if (!strncasecmp(colname, "codec[", 6)) { 10720 char *codecnum, *ptr; 10721 int index = 0, codec = 0; 10722 10723 codecnum = strchr(colname, '['); 10724 *codecnum = '\0'; 10725 codecnum++; 10726 if ((ptr = strchr(codecnum, ']'))) { 10727 *ptr = '\0'; 10728 } 10729 index = atoi(codecnum); 10730 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10731 ast_copy_string(buf, ast_getformatname(codec), len); 10732 } 10733 } 10734 10735 peer_unref(peer); 10736 10737 return 0; 10738 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9239 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09240 { 09241 int methods = 0; 09242 if (strstr(value, "rsa")) 09243 methods |= IAX_AUTH_RSA; 09244 if (strstr(value, "md5")) 09245 methods |= IAX_AUTH_MD5; 09246 if (strstr(value, "plaintext")) 09247 methods |= IAX_AUTH_PLAINTEXT; 09248 return methods; 09249 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1031 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01032 { 01033 int e; 01034 if (!strcasecmp(s, "aes128")) 01035 e = IAX_ENCRYPT_AES128; 01036 else if (ast_true(s)) 01037 e = IAX_ENCRYPT_AES128; 01038 else 01039 e = 0; 01040 return e; 01041 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2641 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02642 { 02643 #ifdef SCHED_MULTITHREADED 02644 if (schedule_action(__get_from_jb, data)) 02645 #endif 02646 __get_from_jb(data); 02647 return 0; 02648 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6893 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().
06894 { 06895 struct iax2_pkt_buf *pkt_buf; 06896 06897 ast_mutex_lock(&thread->lock); 06898 06899 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06900 ast_mutex_unlock(&thread->lock); 06901 06902 thread->buf = pkt_buf->buf; 06903 thread->buf_len = pkt_buf->len; 06904 thread->buf_size = pkt_buf->len + 1; 06905 06906 socket_process(thread); 06907 06908 thread->buf = NULL; 06909 ast_free(pkt_buf); 06910 06911 ast_mutex_lock(&thread->lock); 06912 } 06913 06914 ast_mutex_unlock(&thread->lock); 06915 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2038 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().
02039 { 02040 /* XXX Ideally we should figure out why an error occured and then abort those 02041 rather than continuing to try. Unfortunately, the published interface does 02042 not seem to work XXX */ 02043 #if 0 02044 struct sockaddr_in *sin; 02045 int res; 02046 struct msghdr m; 02047 struct sock_extended_err e; 02048 m.msg_name = NULL; 02049 m.msg_namelen = 0; 02050 m.msg_iov = NULL; 02051 m.msg_control = &e; 02052 m.msg_controllen = sizeof(e); 02053 m.msg_flags = 0; 02054 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02055 if (res < 0) 02056 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02057 else { 02058 if (m.msg_controllen) { 02059 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02060 if (sin) 02061 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02062 else 02063 ast_log(LOG_WARNING, "No address detected??\n"); 02064 } else { 02065 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02066 } 02067 } 02068 #endif 02069 return 0; 02070 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5956 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().
05957 { 05958 struct iax2_registry *reg; 05959 /* Start pessimistic */ 05960 char peer[256] = ""; 05961 char msgstatus[60]; 05962 int refresh = 60; 05963 char ourip[256] = "<Unspecified>"; 05964 struct sockaddr_in oldus; 05965 struct sockaddr_in us; 05966 int oldmsgs; 05967 05968 memset(&us, 0, sizeof(us)); 05969 if (ies->apparent_addr) 05970 bcopy(ies->apparent_addr, &us, sizeof(us)); 05971 if (ies->username) 05972 ast_copy_string(peer, ies->username, sizeof(peer)); 05973 if (ies->refresh) 05974 refresh = ies->refresh; 05975 if (ies->calling_number) { 05976 /* We don't do anything with it really, but maybe we should */ 05977 } 05978 reg = iaxs[callno]->reg; 05979 if (!reg) { 05980 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05981 return -1; 05982 } 05983 memcpy(&oldus, ®->us, sizeof(oldus)); 05984 oldmsgs = reg->messages; 05985 if (inaddrcmp(®->addr, sin)) { 05986 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05987 return -1; 05988 } 05989 memcpy(®->us, &us, sizeof(reg->us)); 05990 if (ies->msgcount >= 0) 05991 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05992 /* always refresh the registration at the interval requested by the server 05993 we are registering to 05994 */ 05995 reg->refresh = refresh; 05996 AST_SCHED_DEL(sched, reg->expire); 05997 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05998 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05999 if (option_verbose > 2) { 06000 if (reg->messages > 255) 06001 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 06002 else if (reg->messages > 1) 06003 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 06004 else if (reg->messages > 0) 06005 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 06006 else 06007 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 06008 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06009 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 06010 } 06011 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 06012 } 06013 reg->regstate = REG_STATE_REGISTERED; 06014 return 0; 06015 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3647 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.
03648 { 03649 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03650 if (option_debug) 03651 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03652 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03653 }
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 3497 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.
03498 { 03499 struct ast_channel *cs[3]; 03500 struct ast_channel *who, *other; 03501 int to = -1; 03502 int res = -1; 03503 int transferstarted=0; 03504 struct ast_frame *f; 03505 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03506 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03507 struct timeval waittimer = {0, 0}, tv; 03508 03509 lock_both(callno0, callno1); 03510 if (!iaxs[callno0] || !iaxs[callno1]) { 03511 unlock_both(callno0, callno1); 03512 return AST_BRIDGE_FAILED; 03513 } 03514 /* Put them in native bridge mode */ 03515 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03516 iaxs[callno0]->bridgecallno = callno1; 03517 iaxs[callno1]->bridgecallno = callno0; 03518 } 03519 unlock_both(callno0, callno1); 03520 03521 /* If not, try to bridge until we can execute a transfer, if we can */ 03522 cs[0] = c0; 03523 cs[1] = c1; 03524 for (/* ever */;;) { 03525 /* Check in case we got masqueraded into */ 03526 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03527 if (option_verbose > 2) 03528 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03529 /* Remove from native mode */ 03530 if (c0->tech == &iax2_tech) { 03531 ast_mutex_lock(&iaxsl[callno0]); 03532 iaxs[callno0]->bridgecallno = 0; 03533 ast_mutex_unlock(&iaxsl[callno0]); 03534 } 03535 if (c1->tech == &iax2_tech) { 03536 ast_mutex_lock(&iaxsl[callno1]); 03537 iaxs[callno1]->bridgecallno = 0; 03538 ast_mutex_unlock(&iaxsl[callno1]); 03539 } 03540 return AST_BRIDGE_FAILED_NOWARN; 03541 } 03542 if (c0->nativeformats != c1->nativeformats) { 03543 if (option_verbose > 2) { 03544 char buf0[255]; 03545 char buf1[255]; 03546 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03547 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03548 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03549 } 03550 /* Remove from native mode */ 03551 lock_both(callno0, callno1); 03552 if (iaxs[callno0]) 03553 iaxs[callno0]->bridgecallno = 0; 03554 if (iaxs[callno1]) 03555 iaxs[callno1]->bridgecallno = 0; 03556 unlock_both(callno0, callno1); 03557 return AST_BRIDGE_FAILED_NOWARN; 03558 } 03559 /* check if transfered and if we really want native bridging */ 03560 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03561 /* Try the transfer */ 03562 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03563 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03564 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03565 transferstarted = 1; 03566 } 03567 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03568 /* Call has been transferred. We're no longer involved */ 03569 gettimeofday(&tv, NULL); 03570 if (ast_tvzero(waittimer)) { 03571 waittimer = tv; 03572 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03573 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03574 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03575 *fo = NULL; 03576 *rc = c0; 03577 res = AST_BRIDGE_COMPLETE; 03578 break; 03579 } 03580 } 03581 to = 1000; 03582 who = ast_waitfor_n(cs, 2, &to); 03583 if (timeoutms > -1) { 03584 timeoutms -= (1000 - to); 03585 if (timeoutms < 0) 03586 timeoutms = 0; 03587 } 03588 if (!who) { 03589 if (!timeoutms) { 03590 res = AST_BRIDGE_RETRY; 03591 break; 03592 } 03593 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03594 res = AST_BRIDGE_FAILED; 03595 break; 03596 } 03597 continue; 03598 } 03599 f = ast_read(who); 03600 if (!f) { 03601 *fo = NULL; 03602 *rc = who; 03603 res = AST_BRIDGE_COMPLETE; 03604 break; 03605 } 03606 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03607 *fo = f; 03608 *rc = who; 03609 res = AST_BRIDGE_COMPLETE; 03610 break; 03611 } 03612 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03613 if ((f->frametype == AST_FRAME_VOICE) || 03614 (f->frametype == AST_FRAME_TEXT) || 03615 (f->frametype == AST_FRAME_VIDEO) || 03616 (f->frametype == AST_FRAME_IMAGE) || 03617 (f->frametype == AST_FRAME_DTMF)) { 03618 /* monitored dtmf take out of the bridge. 03619 * check if we monitor the specific source. 03620 */ 03621 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03622 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03623 *rc = who; 03624 *fo = f; 03625 res = AST_BRIDGE_COMPLETE; 03626 /* Remove from native mode */ 03627 break; 03628 } 03629 /* everything else goes to the other side */ 03630 ast_write(other, f); 03631 } 03632 ast_frfree(f); 03633 /* Swap who gets priority */ 03634 cs[2] = cs[0]; 03635 cs[0] = cs[1]; 03636 cs[1] = cs[2]; 03637 } 03638 lock_both(callno0, callno1); 03639 if(iaxs[callno0]) 03640 iaxs[callno0]->bridgecallno = 0; 03641 if(iaxs[callno1]) 03642 iaxs[callno1]->bridgecallno = 0; 03643 unlock_both(callno0, callno1); 03644 return res; 03645 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3241 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.
03242 { 03243 struct sockaddr_in sin; 03244 char *l=NULL, *n=NULL, *tmpstr; 03245 struct iax_ie_data ied; 03246 char *defaultrdest = "s"; 03247 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03248 struct parsed_dial_string pds; 03249 struct create_addr_info cai; 03250 03251 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03252 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03253 return -1; 03254 } 03255 03256 memset(&cai, 0, sizeof(cai)); 03257 cai.encmethods = iax2_encryption; 03258 03259 memset(&pds, 0, sizeof(pds)); 03260 tmpstr = ast_strdupa(dest); 03261 parse_dial_string(tmpstr, &pds); 03262 03263 if (ast_strlen_zero(pds.peer)) { 03264 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03265 return -1; 03266 } 03267 03268 if (!pds.exten) { 03269 pds.exten = defaultrdest; 03270 } 03271 03272 if (create_addr(pds.peer, c, &sin, &cai)) { 03273 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03274 return -1; 03275 } 03276 03277 if (!pds.username && !ast_strlen_zero(cai.username)) 03278 pds.username = cai.username; 03279 if (!pds.password && !ast_strlen_zero(cai.secret)) 03280 pds.password = cai.secret; 03281 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03282 pds.key = cai.outkey; 03283 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03284 pds.context = cai.peercontext; 03285 03286 /* Keep track of the context for outgoing calls too */ 03287 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03288 03289 if (pds.port) 03290 sin.sin_port = htons(atoi(pds.port)); 03291 03292 l = c->cid.cid_num; 03293 n = c->cid.cid_name; 03294 03295 /* Now build request */ 03296 memset(&ied, 0, sizeof(ied)); 03297 03298 /* On new call, first IE MUST be IAX version of caller */ 03299 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03300 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03301 if (pds.options && strchr(pds.options, 'a')) { 03302 /* Request auto answer */ 03303 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03304 } 03305 03306 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03307 03308 if (l) { 03309 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03310 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03311 } else { 03312 if (n) 03313 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03314 else 03315 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03316 } 03317 03318 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03319 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03320 03321 if (n) 03322 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03323 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03324 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03325 03326 if (!ast_strlen_zero(c->language)) 03327 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03328 if (!ast_strlen_zero(c->cid.cid_dnid)) 03329 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03330 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03331 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03332 03333 if (pds.context) 03334 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03335 03336 if (pds.username) 03337 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03338 03339 if (cai.encmethods) 03340 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03341 03342 ast_mutex_lock(&iaxsl[callno]); 03343 03344 if (!ast_strlen_zero(c->context)) 03345 ast_string_field_set(iaxs[callno], context, c->context); 03346 03347 if (pds.username) 03348 ast_string_field_set(iaxs[callno], username, pds.username); 03349 03350 iaxs[callno]->encmethods = cai.encmethods; 03351 03352 iaxs[callno]->adsi = cai.adsi; 03353 03354 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03355 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03356 03357 if (pds.key) 03358 ast_string_field_set(iaxs[callno], outkey, pds.key); 03359 if (pds.password) 03360 ast_string_field_set(iaxs[callno], secret, pds.password); 03361 03362 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03363 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03364 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03365 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03366 03367 if (iaxs[callno]->maxtime) { 03368 /* Initialize pingtime and auto-congest time */ 03369 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03370 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03371 } else if (autokill) { 03372 iaxs[callno]->pingtime = autokill / 2; 03373 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03374 } 03375 03376 /* send the command using the appropriate socket for this peer */ 03377 iaxs[callno]->sockfd = cai.sockfd; 03378 03379 /* Transmit the string in a "NEW" request */ 03380 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03381 03382 ast_mutex_unlock(&iaxsl[callno]); 03383 ast_setstate(c, AST_STATE_RINGING); 03384 03385 return 0; 03386 }
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 10576 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.
10577 { 10578 int res = 0; 10579 struct iax2_dpcache *dp; 10580 #if 0 10581 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10582 #endif 10583 if ((priority != 1) && (priority != 2)) 10584 return 0; 10585 ast_mutex_lock(&dpcache_lock); 10586 dp = find_cache(chan, data, context, exten, priority); 10587 if (dp) { 10588 if (dp->flags & CACHE_FLAG_CANEXIST) 10589 res= 1; 10590 } 10591 ast_mutex_unlock(&dpcache_lock); 10592 if (!dp) { 10593 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10594 } 10595 return res; 10596 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3144 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03145 { 03146 time_t t; 03147 struct tm tm; 03148 unsigned int tmp; 03149 time(&t); 03150 if (!ast_strlen_zero(tz)) 03151 ast_localtime(&t, &tm, tz); 03152 else 03153 ast_localtime(&t, &tm, NULL); 03154 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03155 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03156 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03157 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03158 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03159 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03160 return tmp; 03161 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1289 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().
01290 { 01291 struct chan_iax2_pvt *pvt; 01292 struct ast_channel *owner; 01293 01294 retry: 01295 pvt = iaxs[callno]; 01296 gettimeofday(&lastused[callno], NULL); 01297 01298 owner = pvt ? pvt->owner : NULL; 01299 01300 if (owner) { 01301 if (ast_mutex_trylock(&owner->lock)) { 01302 if (option_debug > 2) 01303 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01304 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01305 goto retry; 01306 } 01307 } 01308 if (!owner) { 01309 iaxs[callno] = NULL; 01310 } 01311 01312 if (pvt) { 01313 if (!owner) { 01314 pvt->owner = NULL; 01315 } else { 01316 /* If there's an owner, prod it to give up */ 01317 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01318 * because we already hold the owner channel lock. */ 01319 ast_queue_hangup(owner); 01320 } 01321 01322 if (pvt->peercallno) { 01323 remove_by_peercallno(pvt); 01324 } 01325 01326 if (!owner) { 01327 ao2_ref(pvt, -1); 01328 pvt = NULL; 01329 } 01330 } 01331 01332 if (owner) { 01333 ast_mutex_unlock(&owner->lock); 01334 } 01335 01336 if (callno & 0x4000) { 01337 update_max_trunk(); 01338 } 01339 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1219 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().
01220 { 01221 /* Decrement AUTHREQ count if needed */ 01222 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01223 struct iax2_user *user; 01224 struct iax2_user tmp_user = { 01225 .name = pvt->username, 01226 }; 01227 01228 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01229 if (user) { 01230 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01231 user = user_unref(user); 01232 } 01233 01234 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01235 } 01236 01237 /* No more pings or lagrq's */ 01238 AST_SCHED_DEL(sched, pvt->pingid); 01239 AST_SCHED_DEL(sched, pvt->lagid); 01240 AST_SCHED_DEL(sched, pvt->autoid); 01241 AST_SCHED_DEL(sched, pvt->authid); 01242 AST_SCHED_DEL(sched, pvt->initid); 01243 AST_SCHED_DEL(sched, pvt->jbid); 01244 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10763 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().
10764 { 10765 struct parsed_dial_string pds; 10766 char *tmp = ast_strdupa(data); 10767 struct iax2_peer *p; 10768 int res = AST_DEVICE_INVALID; 10769 10770 memset(&pds, 0, sizeof(pds)); 10771 parse_dial_string(tmp, &pds); 10772 10773 if (ast_strlen_zero(pds.peer)) { 10774 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10775 return res; 10776 } 10777 10778 if (option_debug > 2) 10779 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10780 10781 /* SLD: FIXME: second call to find_peer during registration */ 10782 if (!(p = find_peer(pds.peer, 1))) 10783 return res; 10784 10785 res = AST_DEVICE_UNAVAILABLE; 10786 if (option_debug > 2) 10787 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10788 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10789 10790 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10791 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10792 /* Peer is registered, or have default IP address 10793 and a valid registration */ 10794 if (p->historicms == 0 || p->historicms <= p->maxms) 10795 /* let the core figure out whether it is in use or not */ 10796 res = AST_DEVICE_UNKNOWN; 10797 } 10798 10799 peer_unref(p); 10800 10801 return res; 10802 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2760 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02761 { 02762 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02763 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2765 of file chan_iax2.c.
References AST_FRAME_DTMF_END, 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_DTMF_END, digit, 0, NULL, 0, -1); 02768 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4967 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04968 { 04969 if (argc < 2 || argc > 3) 04970 return RESULT_SHOWUSAGE; 04971 iaxdebug = 1; 04972 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04973 return RESULT_SUCCESS; 04974 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4985 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04986 { 04987 if (argc < 3 || argc > 4) 04988 return RESULT_SHOWUSAGE; 04989 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04990 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04991 return RESULT_SUCCESS; 04992 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8733 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().
08734 { 08735 struct iax_ie_data ied; 08736 if (option_debug && iaxdebug) 08737 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08738 08739 if (reg->dnsmgr && 08740 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08741 /* Maybe the IP has changed, force DNS refresh */ 08742 ast_dnsmgr_refresh(reg->dnsmgr); 08743 } 08744 08745 /* 08746 * if IP has Changed, free allocated call to create a new one with new IP 08747 * call has the pointer to IP and must be updated to the new one 08748 */ 08749 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08750 ast_mutex_lock(&iaxsl[reg->callno]); 08751 iax2_destroy(reg->callno); 08752 ast_mutex_unlock(&iaxsl[reg->callno]); 08753 reg->callno = 0; 08754 } 08755 if (!reg->addr.sin_addr.s_addr) { 08756 if (option_debug && iaxdebug) 08757 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08758 /* Setup the next registration attempt */ 08759 AST_SCHED_DEL(sched, reg->expire); 08760 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08761 return -1; 08762 } 08763 08764 if (!reg->callno) { 08765 if (option_debug) 08766 ast_log(LOG_DEBUG, "Allocate call number\n"); 08767 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08768 if (reg->callno < 1) { 08769 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08770 return -1; 08771 } else if (option_debug) 08772 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08773 iaxs[reg->callno]->reg = reg; 08774 ast_mutex_unlock(&iaxsl[reg->callno]); 08775 } 08776 /* Schedule the next registration attempt */ 08777 AST_SCHED_DEL(sched, reg->expire); 08778 /* Setup the next registration a little early */ 08779 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08780 /* Send the request */ 08781 memset(&ied, 0, sizeof(ied)); 08782 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08783 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08784 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08785 reg->regstate = REG_STATE_REGSENT; 08786 return 0; 08787 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5804 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05805 { 05806 #ifdef SCHED_MULTITHREADED 05807 if (schedule_action(__iax2_do_register_s, data)) 05808 #endif 05809 __iax2_do_register_s(data); 05810 return 0; 05811 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4976 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04977 { 04978 if (argc < 3 || argc > 4) 04979 return RESULT_SHOWUSAGE; 04980 iaxtrunkdebug = 1; 04981 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04982 return RESULT_SUCCESS; 04983 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6504 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().
06505 { 06506 struct iax_ie_data ied; 06507 /* Auto-hangup with 30 seconds of inactivity */ 06508 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06509 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06510 memset(&ied, 0, sizeof(ied)); 06511 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06512 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06513 dp->flags |= CACHE_FLAG_TRANSMITTED; 06514 }
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 10622 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.
10623 { 10624 char odata[256]; 10625 char req[256]; 10626 char *ncontext; 10627 struct iax2_dpcache *dp; 10628 struct ast_app *dial; 10629 #if 0 10630 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); 10631 #endif 10632 if (priority == 2) { 10633 /* Indicate status, can be overridden in dialplan */ 10634 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10635 if (dialstatus) { 10636 dial = pbx_findapp(dialstatus); 10637 if (dial) 10638 pbx_exec(chan, dial, ""); 10639 } 10640 return -1; 10641 } else if (priority != 1) 10642 return -1; 10643 ast_mutex_lock(&dpcache_lock); 10644 dp = find_cache(chan, data, context, exten, priority); 10645 if (dp) { 10646 if (dp->flags & CACHE_FLAG_EXISTS) { 10647 ast_copy_string(odata, data, sizeof(odata)); 10648 ncontext = strchr(odata, '/'); 10649 if (ncontext) { 10650 *ncontext = '\0'; 10651 ncontext++; 10652 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10653 } else { 10654 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10655 } 10656 if (option_verbose > 2) 10657 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10658 } else { 10659 ast_mutex_unlock(&dpcache_lock); 10660 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10661 return -1; 10662 } 10663 } 10664 ast_mutex_unlock(&dpcache_lock); 10665 dial = pbx_findapp("Dial"); 10666 if (dial) { 10667 return pbx_exec(chan, dial, req); 10668 } else { 10669 ast_log(LOG_WARNING, "No dial application registered\n"); 10670 } 10671 return -1; 10672 }
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 10553 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.
10554 { 10555 struct iax2_dpcache *dp; 10556 int res = 0; 10557 #if 0 10558 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10559 #endif 10560 if ((priority != 1) && (priority != 2)) 10561 return 0; 10562 ast_mutex_lock(&dpcache_lock); 10563 dp = find_cache(chan, data, context, exten, priority); 10564 if (dp) { 10565 if (dp->flags & CACHE_FLAG_EXISTS) 10566 res= 1; 10567 } 10568 ast_mutex_unlock(&dpcache_lock); 10569 if (!dp) { 10570 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10571 } 10572 return res; 10573 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2787 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.
02788 { 02789 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02790 ast_mutex_lock(&iaxsl[callno]); 02791 if (iaxs[callno]) 02792 iaxs[callno]->owner = newchan; 02793 else 02794 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02795 ast_mutex_unlock(&iaxsl[callno]); 02796 return 0; 02797 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1283 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().
01284 { 01285 AST_SCHED_DEL(sched, fr->retrans); 01286 iax_frame_free(fr); 01287 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1189 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().
01190 { 01191 struct iax2_peer *peer = NULL; 01192 int res = 0; 01193 struct ao2_iterator i; 01194 01195 i = ao2_iterator_init(peers, 0); 01196 while ((peer = ao2_iterator_next(&i))) { 01197 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01198 (peer->addr.sin_port == sin.sin_port)) { 01199 ast_copy_string(host, peer->name, len); 01200 peer_unref(peer); 01201 res = 1; 01202 break; 01203 } 01204 peer_unref(peer); 01205 } 01206 01207 if (!peer) { 01208 peer = realtime_peer(NULL, &sin); 01209 if (peer) { 01210 ast_copy_string(host, peer->name, len); 01211 peer_unref(peer); 01212 res = 1; 01213 } 01214 } 01215 01216 return res; 01217 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3722 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().
03723 { 03724 struct iax2_peer *peer; 03725 int res = 0; 03726 struct ao2_iterator i; 03727 03728 i = ao2_iterator_init(peers, 0); 03729 while ((peer = ao2_iterator_next(&i))) { 03730 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03731 (peer->addr.sin_port == sin.sin_port)) { 03732 res = ast_test_flag(peer, IAX_TRUNK); 03733 peer_unref(peer); 03734 break; 03735 } 03736 peer_unref(peer); 03737 } 03738 03739 return res; 03740 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3388 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.
03389 { 03390 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03391 int alreadygone; 03392 struct iax_ie_data ied; 03393 memset(&ied, 0, sizeof(ied)); 03394 ast_mutex_lock(&iaxsl[callno]); 03395 if (callno && iaxs[callno]) { 03396 if (option_debug) 03397 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03398 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03399 /* Send the hangup unless we have had a transmission error or are already gone */ 03400 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03401 if (!iaxs[callno]->error && !alreadygone) { 03402 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03403 if (!iaxs[callno]) { 03404 ast_mutex_unlock(&iaxsl[callno]); 03405 return 0; 03406 } 03407 } 03408 /* Explicitly predestroy it */ 03409 iax2_predestroy(callno); 03410 /* If we were already gone to begin with, destroy us now */ 03411 if (alreadygone && iaxs[callno]) { 03412 if (option_debug) 03413 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03414 iax2_destroy(callno); 03415 } 03416 } 03417 ast_mutex_unlock(&iaxsl[callno]); 03418 if (option_verbose > 2) 03419 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03420 return 0; 03421 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3655 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.
03656 { 03657 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03658 struct chan_iax2_pvt *pvt; 03659 int res = 0; 03660 03661 if (option_debug && iaxdebug) 03662 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03663 03664 ast_mutex_lock(&iaxsl[callno]); 03665 pvt = iaxs[callno]; 03666 03667 if (!pvt->peercallno) { 03668 /* We don't know the remote side's call number, yet. :( */ 03669 int count = 10; 03670 while (count-- && pvt && !pvt->peercallno) { 03671 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03672 pvt = iaxs[callno]; 03673 } 03674 if (!pvt->peercallno) { 03675 res = -1; 03676 goto done; 03677 } 03678 } 03679 03680 switch (condition) { 03681 case AST_CONTROL_HOLD: 03682 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03683 ast_moh_start(c, data, pvt->mohinterpret); 03684 goto done; 03685 } 03686 break; 03687 case AST_CONTROL_UNHOLD: 03688 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03689 ast_moh_stop(c); 03690 goto done; 03691 } 03692 } 03693 03694 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03695 03696 done: 03697 ast_mutex_unlock(&iaxsl[callno]); 03698 03699 return res; 03700 }
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 10599 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.
10600 { 10601 int res = 0; 10602 struct iax2_dpcache *dp; 10603 #if 0 10604 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10605 #endif 10606 if ((priority != 1) && (priority != 2)) 10607 return 0; 10608 ast_mutex_lock(&dpcache_lock); 10609 dp = find_cache(chan, data, context, exten, priority); 10610 if (dp) { 10611 if (dp->flags & CACHE_FLAG_MATCHMORE) 10612 res= 1; 10613 } 10614 ast_mutex_unlock(&dpcache_lock); 10615 if (!dp) { 10616 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10617 } 10618 return res; 10619 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4994 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04995 { 04996 if (argc < 3 || argc > 4) 04997 return RESULT_SHOWUSAGE; 04998 iaxdebug = 0; 04999 ast_cli(fd, "IAX2 Debugging Disabled\n"); 05000 return RESULT_SUCCESS; 05001 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5012 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05013 { 05014 if (argc < 4 || argc > 5) 05015 return RESULT_SHOWUSAGE; 05016 jb_setoutput(jb_error_output, jb_warning_output, NULL); 05017 jb_debug_output("\n"); 05018 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 05019 return RESULT_SUCCESS; 05020 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5003 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05004 { 05005 if (argc < 4 || argc > 5) 05006 return RESULT_SHOWUSAGE; 05007 iaxtrunkdebug = 0; 05008 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 05009 return RESULT_SUCCESS; 05010 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8931 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08932 { 08933 struct iax2_peer *peer = (struct iax2_peer *)data; 08934 peer->pokeexpire = -1; 08935 #ifdef SCHED_MULTITHREADED 08936 if (schedule_action(__iax2_poke_noanswer, data)) 08937 #endif 08938 __iax2_poke_noanswer(data); 08939 peer_unref(peer); 08940 return 0; 08941 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8952 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().
08953 { 08954 int callno; 08955 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08956 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08957 immediately after clearing things out */ 08958 peer->lastms = 0; 08959 peer->historicms = 0; 08960 peer->pokeexpire = -1; 08961 peer->callno = 0; 08962 return 0; 08963 } 08964 08965 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 08966 if ((callno = peer->callno) > 0) { 08967 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08968 ast_mutex_lock(&iaxsl[callno]); 08969 iax2_destroy(callno); 08970 ast_mutex_unlock(&iaxsl[callno]); 08971 } 08972 if (heldcall) 08973 ast_mutex_unlock(&iaxsl[heldcall]); 08974 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08975 if (heldcall) 08976 ast_mutex_lock(&iaxsl[heldcall]); 08977 if (peer->callno < 1) { 08978 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08979 return -1; 08980 } 08981 08982 /* Speed up retransmission times for this qualify call */ 08983 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08984 iaxs[peer->callno]->peerpoke = peer; 08985 08986 /* Remove any pending pokeexpire task */ 08987 if (peer->pokeexpire > -1) { 08988 if (!ast_sched_del(sched, peer->pokeexpire)) { 08989 peer->pokeexpire = -1; 08990 peer_unref(peer); 08991 } 08992 } 08993 08994 /* Queue up a new task to handle no reply */ 08995 /* If the host is already unreachable then use the unreachable interval instead */ 08996 if (peer->lastms < 0) { 08997 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08998 } else 08999 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 09000 09001 if (peer->pokeexpire == -1) 09002 peer_unref(peer); 09003 09004 /* And send the poke */ 09005 ast_mutex_lock(&iaxsl[callno]); 09006 if (iaxs[callno]) { 09007 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 09008 } 09009 ast_mutex_unlock(&iaxsl[callno]); 09010 09011 return 0; 09012 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8943 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08944 { 08945 struct iax2_peer *peer = obj; 08946 08947 iax2_poke_peer(peer, 0); 08948 08949 return 0; 08950 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6544 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06545 { 06546 struct iax2_peer *peer = (struct iax2_peer *)data; 06547 peer->pokeexpire = -1; 06548 #ifdef SCHED_MULTITHREADED 06549 if (schedule_action(__iax2_poke_peer_s, data)) 06550 #endif 06551 __iax2_poke_peer_s(data); 06552 return 0; 06553 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2122 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().
02123 { 02124 struct ast_channel *c; 02125 struct chan_iax2_pvt *pvt = iaxs[callno]; 02126 02127 if (!pvt) 02128 return -1; 02129 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02130 iax2_destroy_helper(pvt); 02131 ast_set_flag(pvt, IAX_ALREADYGONE); 02132 } 02133 c = pvt->owner; 02134 if (c) { 02135 c->tech_pvt = NULL; 02136 iax2_queue_hangup(callno); 02137 pvt->owner = NULL; 02138 ast_module_unref(ast_module_info->self); 02139 } 02140 return 0; 02141 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8608 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().
08609 { 08610 struct iax2_thread *thread = data; 08611 struct timeval tv; 08612 struct timespec ts; 08613 int put_into_idle = 0; 08614 08615 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08616 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08617 for(;;) { 08618 /* Wait for something to signal us to be awake */ 08619 ast_mutex_lock(&thread->lock); 08620 08621 /* Flag that we're ready to accept signals */ 08622 thread->ready_for_signal = 1; 08623 08624 /* Put into idle list if applicable */ 08625 if (put_into_idle) 08626 insert_idle_thread(thread); 08627 08628 if (thread->type == IAX_TYPE_DYNAMIC) { 08629 struct iax2_thread *t = NULL; 08630 /* Wait to be signalled or time out */ 08631 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08632 ts.tv_sec = tv.tv_sec; 08633 ts.tv_nsec = tv.tv_usec * 1000; 08634 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08635 /* This thread was never put back into the available dynamic 08636 * thread list, so just go away. */ 08637 if (!put_into_idle) { 08638 ast_mutex_unlock(&thread->lock); 08639 break; 08640 } 08641 AST_LIST_LOCK(&dynamic_list); 08642 /* Account for the case where this thread is acquired *right* after a timeout */ 08643 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08644 iaxdynamicthreadcount--; 08645 AST_LIST_UNLOCK(&dynamic_list); 08646 if (t) { 08647 /* This dynamic thread timed out waiting for a task and was 08648 * not acquired immediately after the timeout, 08649 * so it's time to go away. */ 08650 ast_mutex_unlock(&thread->lock); 08651 break; 08652 } 08653 /* Someone grabbed our thread *right* after we timed out. 08654 * Wait for them to set us up with something to do and signal 08655 * us to continue. */ 08656 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08657 ts.tv_sec = tv.tv_sec; 08658 ts.tv_nsec = tv.tv_usec * 1000; 08659 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08660 { 08661 ast_mutex_unlock(&thread->lock); 08662 break; 08663 } 08664 } 08665 } else { 08666 ast_cond_wait(&thread->cond, &thread->lock); 08667 } 08668 08669 /* Go back into our respective list */ 08670 put_into_idle = 1; 08671 08672 ast_mutex_unlock(&thread->lock); 08673 08674 if (thread->iostate == IAX_IOSTATE_IDLE) 08675 continue; 08676 08677 /* Add ourselves to the active list now */ 08678 AST_LIST_LOCK(&active_list); 08679 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08680 AST_LIST_UNLOCK(&active_list); 08681 08682 /* See what we need to do */ 08683 switch(thread->iostate) { 08684 case IAX_IOSTATE_READY: 08685 thread->actions++; 08686 thread->iostate = IAX_IOSTATE_PROCESSING; 08687 socket_process(thread); 08688 handle_deferred_full_frames(thread); 08689 break; 08690 case IAX_IOSTATE_SCHEDREADY: 08691 thread->actions++; 08692 thread->iostate = IAX_IOSTATE_PROCESSING; 08693 #ifdef SCHED_MULTITHREADED 08694 thread->schedfunc(thread->scheddata); 08695 #endif 08696 break; 08697 } 08698 time(&thread->checktime); 08699 thread->iostate = IAX_IOSTATE_IDLE; 08700 #ifdef DEBUG_SCHED_MULTITHREAD 08701 thread->curfunc[0]='\0'; 08702 #endif 08703 08704 /* Now... remove ourselves from the active list, and return to the idle list */ 08705 AST_LIST_LOCK(&active_list); 08706 AST_LIST_REMOVE(&active_list, thread, list); 08707 AST_LIST_UNLOCK(&active_list); 08708 08709 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08710 handle_deferred_full_frames(thread); 08711 } 08712 08713 /*!\note For some reason, idle threads are exiting without being removed 08714 * from an idle list, which is causing memory corruption. Forcibly remove 08715 * it from the list, if it's there. 08716 */ 08717 AST_LIST_LOCK(&idle_list); 08718 AST_LIST_REMOVE(&idle_list, thread, list); 08719 AST_LIST_UNLOCK(&idle_list); 08720 08721 AST_LIST_LOCK(&dynamic_list); 08722 AST_LIST_REMOVE(&dynamic_list, thread, list); 08723 AST_LIST_UNLOCK(&dynamic_list); 08724 08725 /* I am exiting here on my own volition, I need to clean up my own data structures 08726 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08727 */ 08728 pthread_cleanup_pop(1); 08729 08730 return NULL; 08731 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8599 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08600 { 08601 struct iax2_thread *thread = data; 08602 ast_mutex_destroy(&thread->lock); 08603 ast_cond_destroy(&thread->cond); 08604 free(thread); 08605 ast_atomic_dec_and_test(&iaxactivethreadcount); 08606 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8886 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08887 { 08888 int force = 0; 08889 int res; 08890 if (argc < 4) 08891 return RESULT_SHOWUSAGE; 08892 if ((argc > 4)) { 08893 if (!strcasecmp(argv[4], "forced")) 08894 force = 1; 08895 else 08896 return RESULT_SHOWUSAGE; 08897 } 08898 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08899 if (res < 0) 08900 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08901 else if (res < 1) 08902 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08903 else 08904 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08905 return RESULT_SUCCESS; 08906 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8789 of file chan_iax2.c.
References iax_prov_complete_template().
08790 { 08791 if (pos != 3) 08792 return NULL; 08793 return iax_prov_complete_template(line, word, pos, state); 08794 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8796 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().
08797 { 08798 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08799 is found for template */ 08800 struct iax_ie_data provdata; 08801 struct iax_ie_data ied; 08802 unsigned int sig; 08803 struct sockaddr_in sin; 08804 int callno; 08805 struct create_addr_info cai; 08806 08807 memset(&cai, 0, sizeof(cai)); 08808 08809 if (option_debug) 08810 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08811 08812 if (iax_provision_build(&provdata, &sig, template, force)) { 08813 if (option_debug) 08814 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08815 return 0; 08816 } 08817 08818 if (end) { 08819 memcpy(&sin, end, sizeof(sin)); 08820 cai.sockfd = sockfd; 08821 } else if (create_addr(dest, NULL, &sin, &cai)) 08822 return -1; 08823 08824 /* Build the rest of the message */ 08825 memset(&ied, 0, sizeof(ied)); 08826 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08827 08828 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08829 if (!callno) 08830 return -1; 08831 08832 if (iaxs[callno]) { 08833 /* Schedule autodestruct in case they don't ever give us anything back */ 08834 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08835 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08836 ast_set_flag(iaxs[callno], IAX_PROVISION); 08837 /* Got a call number now, so go ahead and send the provisioning information */ 08838 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08839 } 08840 ast_mutex_unlock(&iaxsl[callno]); 08841 08842 return 1; 08843 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2257 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.
02258 { 02259 struct iax2_peer *peer; 02260 02261 if (argc != 4) 02262 return RESULT_SHOWUSAGE; 02263 if (!strcmp(argv[3],"all")) { 02264 reload_config(); 02265 ast_cli(fd, "OK cache is flushed.\n"); 02266 } else if ((peer = find_peer(argv[3], 0))) { 02267 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02268 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02269 expire_registry(peer_ref(peer)); 02270 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02271 } else { 02272 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02273 } 02274 peer_unref(peer); 02275 } else { 02276 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02277 } 02278 02279 return RESULT_SUCCESS; 02280 }
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 1732 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().
01734 { 01735 for (;;) { 01736 if (iaxs[callno] && iaxs[callno]->owner) { 01737 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01738 /* Avoid deadlock by pausing and trying again */ 01739 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01740 } else { 01741 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01742 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01743 break; 01744 } 01745 } else 01746 break; 01747 } 01748 return 0; 01749 }
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 1670 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().
01671 { 01672 for (;;) { 01673 if (iaxs[callno] && iaxs[callno]->owner) { 01674 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01675 /* Avoid deadlock by pausing and trying again */ 01676 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01677 } else { 01678 ast_queue_frame(iaxs[callno]->owner, f); 01679 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01680 break; 01681 } 01682 } else 01683 break; 01684 } 01685 return 0; 01686 }
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 1701 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().
01702 { 01703 for (;;) { 01704 if (iaxs[callno] && iaxs[callno]->owner) { 01705 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01706 /* Avoid deadlock by pausing and trying again */ 01707 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01708 } else { 01709 ast_queue_hangup(iaxs[callno]->owner); 01710 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01711 break; 01712 } 01713 } else 01714 break; 01715 } 01716 return 0; 01717 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 3449 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03450 { 03451 if (option_verbose > 3) 03452 ast_log(LOG_NOTICE, "I should never be called!\n"); 03453 return &ast_null_frame; 03454 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 6017 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().
06018 { 06019 struct iax2_registry *reg; 06020 char copy[256]; 06021 char *username, *hostname, *secret; 06022 char *porta; 06023 char *stringp=NULL; 06024 06025 if (!value) 06026 return -1; 06027 ast_copy_string(copy, value, sizeof(copy)); 06028 stringp=copy; 06029 username = strsep(&stringp, "@"); 06030 hostname = strsep(&stringp, "@"); 06031 if (!hostname) { 06032 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06033 return -1; 06034 } 06035 stringp=username; 06036 username = strsep(&stringp, ":"); 06037 secret = strsep(&stringp, ":"); 06038 stringp=hostname; 06039 hostname = strsep(&stringp, ":"); 06040 porta = strsep(&stringp, ":"); 06041 06042 if (porta && !atoi(porta)) { 06043 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06044 return -1; 06045 } 06046 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06047 return -1; 06048 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06049 free(reg); 06050 return -1; 06051 } 06052 ast_copy_string(reg->username, username, sizeof(reg->username)); 06053 if (secret) 06054 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06055 reg->expire = -1; 06056 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06057 reg->addr.sin_family = AF_INET; 06058 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06059 AST_LIST_LOCK(®istrations); 06060 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06061 AST_LIST_UNLOCK(®istrations); 06062 06063 return 0; 06064 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10322 of file chan_iax2.c.
References reload_config().
10323 { 10324 return reload_config(); 10325 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 9024 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.
09025 { 09026 int callno; 09027 int res; 09028 int fmt, native; 09029 struct sockaddr_in sin; 09030 struct ast_channel *c; 09031 struct parsed_dial_string pds; 09032 struct create_addr_info cai; 09033 char *tmpstr; 09034 09035 memset(&pds, 0, sizeof(pds)); 09036 tmpstr = ast_strdupa(data); 09037 parse_dial_string(tmpstr, &pds); 09038 09039 if (ast_strlen_zero(pds.peer)) { 09040 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09041 return NULL; 09042 } 09043 09044 memset(&cai, 0, sizeof(cai)); 09045 cai.capability = iax2_capability; 09046 09047 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09048 09049 /* Populate our address from the given */ 09050 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09051 *cause = AST_CAUSE_UNREGISTERED; 09052 return NULL; 09053 } 09054 09055 if (pds.port) 09056 sin.sin_port = htons(atoi(pds.port)); 09057 09058 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09059 if (callno < 1) { 09060 ast_log(LOG_WARNING, "Unable to create call\n"); 09061 *cause = AST_CAUSE_CONGESTION; 09062 return NULL; 09063 } 09064 09065 /* If this is a trunk, update it now */ 09066 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09067 if (ast_test_flag(&cai, IAX_TRUNK)) { 09068 int new_callno; 09069 if ((new_callno = make_trunk(callno, 1)) != -1) 09070 callno = new_callno; 09071 } 09072 iaxs[callno]->maxtime = cai.maxtime; 09073 if (cai.found) 09074 ast_string_field_set(iaxs[callno], host, pds.peer); 09075 09076 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09077 09078 ast_mutex_unlock(&iaxsl[callno]); 09079 09080 if (c) { 09081 /* Choose a format we can live with */ 09082 if (c->nativeformats & format) 09083 c->nativeformats &= format; 09084 else { 09085 native = c->nativeformats; 09086 fmt = format; 09087 res = ast_translator_best_choice(&fmt, &native); 09088 if (res < 0) { 09089 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09090 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09091 ast_hangup(c); 09092 return NULL; 09093 } 09094 c->nativeformats = native; 09095 } 09096 c->readformat = ast_best_codec(c->nativeformats); 09097 c->writeformat = c->readformat; 09098 } 09099 09100 return c; 09101 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 993 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().
00994 { 00995 int res; 00996 00997 res = ast_sched_add(con, when, callback, data); 00998 signal_condition(&sched_lock, &sched_cond); 00999 01000 return res; 01001 }
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 4300 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, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, 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, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, 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().
04301 { 04302 /* Queue a packet for delivery on a given private structure. Use "ts" for 04303 timestamp, or calculate if ts is 0. Send immediately without retransmission 04304 or delayed, with retransmission */ 04305 struct ast_iax2_full_hdr *fh; 04306 struct ast_iax2_mini_hdr *mh; 04307 struct ast_iax2_video_hdr *vh; 04308 struct { 04309 struct iax_frame fr2; 04310 unsigned char buffer[4096]; 04311 } frb; 04312 struct iax_frame *fr; 04313 int res; 04314 int sendmini=0; 04315 unsigned int lastsent; 04316 unsigned int fts; 04317 04318 frb.fr2.afdatalen = sizeof(frb.buffer); 04319 04320 if (!pvt) { 04321 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04322 return -1; 04323 } 04324 04325 lastsent = pvt->lastsent; 04326 04327 /* Calculate actual timestamp */ 04328 fts = calc_timestamp(pvt, ts, f); 04329 04330 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04331 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04332 * increment the "predicted timestamps" for voice, if we're predecting */ 04333 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04334 return 0; 04335 04336 04337 if ((ast_test_flag(pvt, IAX_TRUNK) || 04338 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04339 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04340 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04341 (f->frametype == AST_FRAME_VOICE) 04342 /* is a voice frame */ && 04343 (f->subclass == pvt->svoiceformat) 04344 /* is the same type */ ) { 04345 /* Force immediate rather than delayed transmission */ 04346 now = 1; 04347 /* Mark that mini-style frame is appropriate */ 04348 sendmini = 1; 04349 } 04350 if ( f->frametype == AST_FRAME_VIDEO ) { 04351 /* 04352 * If the lower 15 bits of the timestamp roll over, or if 04353 * the video format changed then send a full frame. 04354 * Otherwise send a mini video frame 04355 */ 04356 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04357 ((f->subclass & ~0x1) == pvt->svideoformat) 04358 ) { 04359 now = 1; 04360 sendmini = 1; 04361 } else { 04362 now = 0; 04363 sendmini = 0; 04364 } 04365 pvt->lastvsent = fts; 04366 } 04367 /* Allocate an iax_frame */ 04368 if (now) { 04369 fr = &frb.fr2; 04370 } else 04371 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)); 04372 if (!fr) { 04373 ast_log(LOG_WARNING, "Out of memory\n"); 04374 return -1; 04375 } 04376 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04377 iax_frame_wrap(fr, f); 04378 04379 fr->ts = fts; 04380 fr->callno = pvt->callno; 04381 fr->transfer = transfer; 04382 fr->final = final; 04383 fr->encmethods = 0; 04384 if (!sendmini) { 04385 /* We need a full frame */ 04386 if (seqno > -1) 04387 fr->oseqno = seqno; 04388 else 04389 fr->oseqno = pvt->oseqno++; 04390 fr->iseqno = pvt->iseqno; 04391 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04392 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04393 fh->ts = htonl(fr->ts); 04394 fh->oseqno = fr->oseqno; 04395 if (transfer) { 04396 fh->iseqno = 0; 04397 } else 04398 fh->iseqno = fr->iseqno; 04399 /* Keep track of the last thing we've acknowledged */ 04400 if (!transfer) 04401 pvt->aseqno = fr->iseqno; 04402 fh->type = fr->af.frametype & 0xFF; 04403 if (fr->af.frametype == AST_FRAME_VIDEO) 04404 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04405 else 04406 fh->csub = compress_subclass(fr->af.subclass); 04407 if (transfer) { 04408 fr->dcallno = pvt->transfercallno; 04409 } else 04410 fr->dcallno = pvt->peercallno; 04411 fh->dcallno = htons(fr->dcallno); 04412 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04413 fr->data = fh; 04414 fr->retries = 0; 04415 /* Retry after 2x the ping time has passed */ 04416 fr->retrytime = pvt->pingtime * 2; 04417 if (fr->retrytime < MIN_RETRY_TIME) 04418 fr->retrytime = MIN_RETRY_TIME; 04419 if (fr->retrytime > MAX_RETRY_TIME) 04420 fr->retrytime = MAX_RETRY_TIME; 04421 /* Acks' don't get retried */ 04422 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04423 fr->retries = -1; 04424 else if (f->frametype == AST_FRAME_VOICE) 04425 pvt->svoiceformat = f->subclass; 04426 else if (f->frametype == AST_FRAME_VIDEO) 04427 pvt->svideoformat = f->subclass & ~0x1; 04428 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04429 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04430 if (iaxdebug) { 04431 if (fr->transfer) 04432 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04433 else 04434 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04435 } 04436 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04437 fr->encmethods = pvt->encmethods; 04438 fr->ecx = pvt->ecx; 04439 fr->mydcx = pvt->mydcx; 04440 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 04441 } else 04442 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04443 } 04444 04445 if (now) { 04446 res = send_packet(fr); 04447 } else 04448 res = iax2_transmit(fr); 04449 } else { 04450 if (ast_test_flag(pvt, IAX_TRUNK)) { 04451 iax2_trunk_queue(pvt, fr); 04452 res = 0; 04453 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04454 /* Video frame have no sequence number */ 04455 fr->oseqno = -1; 04456 fr->iseqno = -1; 04457 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04458 vh->zeros = 0; 04459 vh->callno = htons(0x8000 | fr->callno); 04460 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04461 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04462 fr->data = vh; 04463 fr->retries = -1; 04464 res = send_packet(fr); 04465 } else { 04466 /* Mini-frames have no sequence number */ 04467 fr->oseqno = -1; 04468 fr->iseqno = -1; 04469 /* Mini frame will do */ 04470 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04471 mh->callno = htons(fr->callno); 04472 mh->ts = htons(fr->ts & 0xFFFF); 04473 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04474 fr->data = mh; 04475 fr->retries = -1; 04476 if (pvt->transferring == TRANSFER_MEDIAPASS) 04477 fr->transfer = 1; 04478 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04479 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04480 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04481 } else 04482 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04483 } 04484 res = send_packet(fr); 04485 } 04486 } 04487 return res; 04488 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2782 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02783 { 02784 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02785 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2777 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.
02778 { 02779 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02780 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2770 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02771 { 02772 02773 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02774 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02775 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3423 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, 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.
03424 { 03425 struct ast_option_header *h; 03426 int res; 03427 03428 switch (option) { 03429 case AST_OPTION_TXGAIN: 03430 case AST_OPTION_RXGAIN: 03431 /* these two cannot be sent, because they require a result */ 03432 errno = ENOSYS; 03433 return -1; 03434 default: 03435 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03436 return -1; 03437 03438 h->flag = AST_OPTION_FLAG_REQUEST; 03439 h->option = htons(option); 03440 memcpy(h->data, data, datalen); 03441 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03442 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03443 datalen + sizeof(*h), -1); 03444 free(h); 03445 return res; 03446 } 03447 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2461 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.
02462 { 02463 struct iax2_dpcache *dp; 02464 char tmp[1024], *pc; 02465 int s; 02466 int x,y; 02467 struct timeval tv; 02468 gettimeofday(&tv, NULL); 02469 ast_mutex_lock(&dpcache_lock); 02470 dp = dpcache; 02471 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02472 while(dp) { 02473 s = dp->expiry.tv_sec - tv.tv_sec; 02474 tmp[0] = '\0'; 02475 if (dp->flags & CACHE_FLAG_EXISTS) 02476 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02477 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02478 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02479 if (dp->flags & CACHE_FLAG_CANEXIST) 02480 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02481 if (dp->flags & CACHE_FLAG_PENDING) 02482 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02483 if (dp->flags & CACHE_FLAG_TIMEOUT) 02484 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02485 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02486 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02487 if (dp->flags & CACHE_FLAG_MATCHMORE) 02488 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02489 if (dp->flags & CACHE_FLAG_UNKNOWN) 02490 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02491 /* Trim trailing pipe */ 02492 if (!ast_strlen_zero(tmp)) 02493 tmp[strlen(tmp) - 1] = '\0'; 02494 else 02495 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02496 y=0; 02497 pc = strchr(dp->peercontext, '@'); 02498 if (!pc) 02499 pc = dp->peercontext; 02500 else 02501 pc++; 02502 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02503 if (dp->waiters[x] > -1) 02504 y++; 02505 if (s > 0) 02506 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02507 else 02508 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02509 dp = dp->next; 02510 } 02511 ast_mutex_unlock(&dpcache_lock); 02512 return RESULT_SUCCESS; 02513 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4832 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.
04833 { 04834 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04835 #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" 04836 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04837 int x; 04838 int numchans = 0; 04839 04840 if (argc != 3) 04841 return RESULT_SHOWUSAGE; 04842 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04843 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04844 ast_mutex_lock(&iaxsl[x]); 04845 if (iaxs[x]) { 04846 int lag, jitter, localdelay; 04847 jb_info jbinfo; 04848 04849 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04850 jb_getinfo(iaxs[x]->jb, &jbinfo); 04851 jitter = jbinfo.jitter; 04852 localdelay = jbinfo.current - jbinfo.min; 04853 } else { 04854 jitter = -1; 04855 localdelay = 0; 04856 } 04857 lag = iaxs[x]->remote_rr.delay; 04858 ast_cli(fd, FORMAT, 04859 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04860 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04861 S_OR(iaxs[x]->username, "(None)"), 04862 iaxs[x]->callno, iaxs[x]->peercallno, 04863 iaxs[x]->oseqno, iaxs[x]->iseqno, 04864 lag, 04865 jitter, 04866 localdelay, 04867 ast_getformatname(iaxs[x]->voiceformat) ); 04868 numchans++; 04869 } 04870 ast_mutex_unlock(&iaxsl[x]); 04871 } 04872 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04873 return RESULT_SUCCESS; 04874 #undef FORMAT 04875 #undef FORMAT2 04876 #undef FORMATB 04877 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4743 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.
04744 { 04745 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04746 #if !defined(__FreeBSD__) 04747 #define FORMAT "%-15.15s %-15d %-15d\n" 04748 #else /* __FreeBSD__ */ 04749 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04750 #endif /* __FreeBSD__ */ 04751 struct iax_firmware *cur; 04752 if ((argc != 3) && (argc != 4)) 04753 return RESULT_SHOWUSAGE; 04754 ast_mutex_lock(&waresl.lock); 04755 04756 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04757 for (cur = waresl.wares;cur;cur = cur->next) { 04758 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04759 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04760 (int)ntohl(cur->fwh->datalen)); 04761 } 04762 ast_mutex_unlock(&waresl.lock); 04763 return RESULT_SUCCESS; 04764 #undef FORMAT 04765 #undef FORMAT2 04766 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4955 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04956 { 04957 int numchans = 0; 04958 if (argc != 3) 04959 return RESULT_SHOWUSAGE; 04960 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04961 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04962 numchans = ast_cli_netstats(NULL, fd, 1); 04963 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04964 return RESULT_SUCCESS; 04965 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2351 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.
02352 { 02353 char status[30]; 02354 char cbuf[256]; 02355 struct iax2_peer *peer; 02356 char codec_buf[512]; 02357 int x = 0, codec = 0, load_realtime = 0; 02358 02359 if (argc < 4) 02360 return RESULT_SHOWUSAGE; 02361 02362 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02363 02364 peer = find_peer(argv[3], load_realtime); 02365 if (peer) { 02366 ast_cli(fd,"\n\n"); 02367 ast_cli(fd, " * Name : %s\n", peer->name); 02368 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02369 ast_cli(fd, " Context : %s\n", peer->context); 02370 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02371 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02372 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02373 ast_cli(fd, " Expire : %d\n", peer->expire); 02374 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02375 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)); 02376 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02377 ast_cli(fd, " Username : %s\n", peer->username); 02378 ast_cli(fd, " Codecs : "); 02379 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02380 ast_cli(fd, "%s\n", codec_buf); 02381 02382 ast_cli(fd, " Codec Order : ("); 02383 for(x = 0; x < 32 ; x++) { 02384 codec = ast_codec_pref_index(&peer->prefs,x); 02385 if(!codec) 02386 break; 02387 ast_cli(fd, "%s", ast_getformatname(codec)); 02388 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02389 ast_cli(fd, "|"); 02390 } 02391 02392 if (!x) 02393 ast_cli(fd, "none"); 02394 ast_cli(fd, ")\n"); 02395 02396 ast_cli(fd, " Status : "); 02397 peer_status(peer, status, sizeof(status)); 02398 ast_cli(fd, "%s\n",status); 02399 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02400 ast_cli(fd,"\n"); 02401 peer_unref(peer); 02402 } else { 02403 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02404 ast_cli(fd,"\n"); 02405 } 02406 02407 return RESULT_SUCCESS; 02408 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4732 of file chan_iax2.c.
References __iax2_show_peers().
04733 { 04734 return __iax2_show_peers(0, fd, NULL, argc, argv); 04735 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4804 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.
04805 { 04806 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04807 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04808 struct iax2_registry *reg = NULL; 04809 04810 char host[80]; 04811 char perceived[80]; 04812 if (argc != 3) 04813 return RESULT_SHOWUSAGE; 04814 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04815 AST_LIST_LOCK(®istrations); 04816 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04817 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04818 if (reg->us.sin_addr.s_addr) 04819 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04820 else 04821 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04822 ast_cli(fd, FORMAT, host, 04823 (reg->dnsmgr) ? "Y" : "N", 04824 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04825 } 04826 AST_LIST_UNLOCK(®istrations); 04827 return RESULT_SUCCESS; 04828 #undef FORMAT 04829 #undef FORMAT2 04830 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2435 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.
02436 { 02437 struct iax_frame *cur; 02438 int cnt = 0, dead=0, final=0; 02439 02440 if (argc != 3) 02441 return RESULT_SHOWUSAGE; 02442 02443 AST_LIST_LOCK(&iaxq.queue); 02444 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02445 if (cur->retries < 0) 02446 dead++; 02447 if (cur->final) 02448 final++; 02449 cnt++; 02450 } 02451 AST_LIST_UNLOCK(&iaxq.queue); 02452 02453 ast_cli(fd, " IAX Statistics\n"); 02454 ast_cli(fd, "---------------------\n"); 02455 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02456 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02457 02458 return RESULT_SUCCESS; 02459 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4673 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.
04674 { 04675 struct iax2_thread *thread = NULL; 04676 time_t t; 04677 int threadcount = 0, dynamiccount = 0; 04678 char type; 04679 04680 if (argc != 3) 04681 return RESULT_SHOWUSAGE; 04682 04683 ast_cli(fd, "IAX2 Thread Information\n"); 04684 time(&t); 04685 ast_cli(fd, "Idle Threads:\n"); 04686 AST_LIST_LOCK(&idle_list); 04687 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04688 #ifdef DEBUG_SCHED_MULTITHREAD 04689 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04690 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04691 #else 04692 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04693 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04694 #endif 04695 threadcount++; 04696 } 04697 AST_LIST_UNLOCK(&idle_list); 04698 ast_cli(fd, "Active Threads:\n"); 04699 AST_LIST_LOCK(&active_list); 04700 AST_LIST_TRAVERSE(&active_list, thread, list) { 04701 if (thread->type == IAX_TYPE_DYNAMIC) 04702 type = 'D'; 04703 else 04704 type = 'P'; 04705 #ifdef DEBUG_SCHED_MULTITHREAD 04706 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04707 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04708 #else 04709 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04710 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04711 #endif 04712 threadcount++; 04713 } 04714 AST_LIST_UNLOCK(&active_list); 04715 ast_cli(fd, "Dynamic Threads:\n"); 04716 AST_LIST_LOCK(&dynamic_list); 04717 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04718 #ifdef DEBUG_SCHED_MULTITHREAD 04719 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04720 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04721 #else 04722 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04723 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04724 #endif 04725 dynamiccount++; 04726 } 04727 AST_LIST_UNLOCK(&dynamic_list); 04728 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04729 return RESULT_SUCCESS; 04730 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4490 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.
04491 { 04492 regex_t regexbuf; 04493 int havepattern = 0; 04494 04495 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04496 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04497 04498 struct iax2_user *user = NULL; 04499 char auth[90]; 04500 char *pstr = ""; 04501 struct ao2_iterator i; 04502 04503 switch (argc) { 04504 case 5: 04505 if (!strcasecmp(argv[3], "like")) { 04506 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04507 return RESULT_SHOWUSAGE; 04508 havepattern = 1; 04509 } else 04510 return RESULT_SHOWUSAGE; 04511 case 3: 04512 break; 04513 default: 04514 return RESULT_SHOWUSAGE; 04515 } 04516 04517 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04518 i = ao2_iterator_init(users, 0); 04519 for (user = ao2_iterator_next(&i); user; 04520 user_unref(user), user = ao2_iterator_next(&i)) { 04521 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04522 continue; 04523 04524 if (!ast_strlen_zero(user->secret)) { 04525 ast_copy_string(auth,user->secret,sizeof(auth)); 04526 } else if (!ast_strlen_zero(user->inkeys)) { 04527 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04528 } else 04529 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04530 04531 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04532 pstr = "REQ Only"; 04533 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04534 pstr = "Disabled"; 04535 else 04536 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04537 04538 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04539 user->contexts ? user->contexts->context : context, 04540 user->ha ? "Yes" : "No", pstr); 04541 } 04542 04543 if (havepattern) 04544 regfree(®exbuf); 04545 04546 return RESULT_SUCCESS; 04547 #undef FORMAT 04548 #undef FORMAT2 04549 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3456 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().
03457 { 03458 int res; 03459 struct iax_ie_data ied0; 03460 struct iax_ie_data ied1; 03461 unsigned int transferid = (unsigned int)ast_random(); 03462 memset(&ied0, 0, sizeof(ied0)); 03463 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03464 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03465 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03466 03467 memset(&ied1, 0, sizeof(ied1)); 03468 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03469 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03470 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03471 03472 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03473 if (res) 03474 return -1; 03475 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03476 if (res) 03477 return -1; 03478 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03479 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03480 return 0; 03481 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2282 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02283 { 02284 if (argc != 4) 02285 return RESULT_SHOWUSAGE; 02286 02287 test_losspct = atoi(argv[3]); 02288 02289 return RESULT_SUCCESS; 02290 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3702 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.
03703 { 03704 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03705 struct iax_ie_data ied; 03706 char tmp[256], *context; 03707 ast_copy_string(tmp, dest, sizeof(tmp)); 03708 context = strchr(tmp, '@'); 03709 if (context) { 03710 *context = '\0'; 03711 context++; 03712 } 03713 memset(&ied, 0, sizeof(ied)); 03714 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03715 if (context) 03716 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03717 if (option_debug) 03718 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03719 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03720 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2741 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().
02742 { 02743 /* Lock the queue and place this packet at the end */ 02744 /* By setting this to 0, the network thread will send it for us, and 02745 queue retransmission if necessary */ 02746 fr->sentyet = 0; 02747 AST_LIST_LOCK(&iaxq.queue); 02748 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02749 iaxq.count++; 02750 AST_LIST_UNLOCK(&iaxq.queue); 02751 /* Wake up the network and scheduler thread */ 02752 if (netthreadid != AST_PTHREADT_NULL) 02753 pthread_kill(netthreadid, SIGURG); 02754 signal_condition(&sched_lock, &sched_cond); 02755 return 0; 02756 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6599 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06600 { 06601 /* Drop when trunk is about 5 seconds idle */ 06602 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06603 return 1; 06604 return 0; 06605 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4065 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().
04066 { 04067 struct ast_frame *f; 04068 struct iax2_trunk_peer *tpeer; 04069 void *tmp, *ptr; 04070 struct ast_iax2_meta_trunk_entry *met; 04071 struct ast_iax2_meta_trunk_mini *mtm; 04072 04073 f = &fr->af; 04074 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04075 if (tpeer) { 04076 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04077 /* Need to reallocate space */ 04078 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04079 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04080 ast_mutex_unlock(&tpeer->lock); 04081 return -1; 04082 } 04083 04084 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04085 tpeer->trunkdata = tmp; 04086 if (option_debug) 04087 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); 04088 } else { 04089 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)); 04090 ast_mutex_unlock(&tpeer->lock); 04091 return -1; 04092 } 04093 } 04094 04095 /* Append to meta frame */ 04096 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04097 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04098 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04099 mtm->len = htons(f->datalen); 04100 mtm->mini.callno = htons(pvt->callno); 04101 mtm->mini.ts = htons(0xffff & fr->ts); 04102 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04103 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04104 } else { 04105 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04106 /* Store call number and length in meta header */ 04107 met->callno = htons(pvt->callno); 04108 met->len = htons(f->datalen); 04109 /* Advance pointers/decrease length past trunk entry header */ 04110 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04111 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04112 } 04113 /* Copy actual trunk data */ 04114 memcpy(ptr, f->data, f->datalen); 04115 tpeer->trunkdatalen += f->datalen; 04116 04117 tpeer->calls++; 04118 ast_mutex_unlock(&tpeer->lock); 04119 } 04120 return 0; 04121 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6516 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06517 { 06518 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06519 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 5022 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.
05023 { 05024 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05025 int res = -1; 05026 ast_mutex_lock(&iaxsl[callno]); 05027 if (iaxs[callno]) { 05028 /* If there's an outstanding error, return failure now */ 05029 if (!iaxs[callno]->error) { 05030 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05031 res = 0; 05032 /* Don't waste bandwidth sending null frames */ 05033 else if (f->frametype == AST_FRAME_NULL) 05034 res = 0; 05035 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05036 res = 0; 05037 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05038 res = 0; 05039 else 05040 /* Simple, just queue for transmission */ 05041 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05042 } else { 05043 if (option_debug) 05044 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05045 } 05046 } 05047 /* If it's already gone, just return */ 05048 ast_mutex_unlock(&iaxsl[callno]); 05049 return res; 05050 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1905 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().
01906 { 01907 int res = 0; 01908 struct iax_firmware *cur; 01909 if (!ast_strlen_zero(dev)) { 01910 ast_mutex_lock(&waresl.lock); 01911 cur = waresl.wares; 01912 while(cur) { 01913 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01914 res = ntohs(cur->fwh->version); 01915 break; 01916 } 01917 cur = cur->next; 01918 } 01919 ast_mutex_unlock(&waresl.lock); 01920 } 01921 return res; 01922 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 767 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00768 { 00769 if (iaxdebug) 00770 ast_verbose("%s", data); 00771 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 773 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00774 { 00775 ast_log(LOG_WARNING, "%s", data); 00776 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1924 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().
01925 { 01926 int res = -1; 01927 unsigned int bs = desc & 0xff; 01928 unsigned int start = (desc >> 8) & 0xffffff; 01929 unsigned int bytes; 01930 struct iax_firmware *cur; 01931 if (!ast_strlen_zero((char *)dev) && bs) { 01932 start *= bs; 01933 ast_mutex_lock(&waresl.lock); 01934 cur = waresl.wares; 01935 while(cur) { 01936 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01937 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01938 if (start < ntohl(cur->fwh->datalen)) { 01939 bytes = ntohl(cur->fwh->datalen) - start; 01940 if (bytes > bs) 01941 bytes = bs; 01942 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01943 } else { 01944 bytes = 0; 01945 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01946 } 01947 if (bytes == bs) 01948 res = 0; 01949 else 01950 res = 1; 01951 break; 01952 } 01953 cur = cur->next; 01954 } 01955 ast_mutex_unlock(&waresl.lock); 01956 } 01957 return res; 01958 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6787 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().
06788 { 06789 struct iax_dual *d; 06790 struct ast_channel *chan1m, *chan2m; 06791 pthread_t th; 06792 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06793 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06794 if (chan2m && chan1m) { 06795 /* Make formats okay */ 06796 chan1m->readformat = chan1->readformat; 06797 chan1m->writeformat = chan1->writeformat; 06798 ast_channel_masquerade(chan1m, chan1); 06799 /* Setup the extensions and such */ 06800 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06801 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06802 chan1m->priority = chan1->priority; 06803 06804 /* We make a clone of the peer channel too, so we can play 06805 back the announcement */ 06806 /* Make formats okay */ 06807 chan2m->readformat = chan2->readformat; 06808 chan2m->writeformat = chan2->writeformat; 06809 ast_channel_masquerade(chan2m, chan2); 06810 /* Setup the extensions and such */ 06811 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06812 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06813 chan2m->priority = chan2->priority; 06814 if (ast_do_masquerade(chan2m)) { 06815 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06816 ast_hangup(chan2m); 06817 return -1; 06818 } 06819 } else { 06820 if (chan1m) 06821 ast_hangup(chan1m); 06822 if (chan2m) 06823 ast_hangup(chan2m); 06824 return -1; 06825 } 06826 if ((d = ast_calloc(1, sizeof(*d)))) { 06827 pthread_attr_t attr; 06828 06829 pthread_attr_init(&attr); 06830 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06831 06832 d->chan1 = chan1m; 06833 d->chan2 = chan2m; 06834 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06835 pthread_attr_destroy(&attr); 06836 return 0; 06837 } 06838 pthread_attr_destroy(&attr); 06839 free(d); 06840 } 06841 return -1; 06842 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6767 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().
06768 { 06769 struct ast_channel *chan1, *chan2; 06770 struct iax_dual *d; 06771 struct ast_frame *f; 06772 int ext; 06773 int res; 06774 d = stuff; 06775 chan1 = d->chan1; 06776 chan2 = d->chan2; 06777 free(d); 06778 f = ast_read(chan1); 06779 if (f) 06780 ast_frfree(f); 06781 res = ast_park_call(chan1, chan2, 0, &ext); 06782 ast_hangup(chan2); 06783 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06784 return NULL; 06785 }
Definition at line 1419 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().
01420 { 01421 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01422 if (new) { 01423 size_t afdatalen = new->afdatalen; 01424 memcpy(new, fr, sizeof(*new)); 01425 iax_frame_wrap(new, &fr->af); 01426 new->afdatalen = afdatalen; 01427 new->data = NULL; 01428 new->datalen = 0; 01429 new->direction = DIRECTION_INGRESS; 01430 new->retrans = -1; 01431 } 01432 return new; 01433 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 901 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().
00902 { 00903 if (thread->type == IAX_TYPE_DYNAMIC) { 00904 AST_LIST_LOCK(&dynamic_list); 00905 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00906 AST_LIST_UNLOCK(&dynamic_list); 00907 } else { 00908 AST_LIST_LOCK(&idle_list); 00909 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00910 AST_LIST_UNLOCK(&idle_list); 00911 } 00912 00913 return; 00914 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 802 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00803 { 00804 va_list args; 00805 char buf[1024]; 00806 00807 va_start(args, fmt); 00808 vsnprintf(buf, 1024, fmt, args); 00809 va_end(args); 00810 00811 ast_verbose(buf); 00812 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 778 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00779 { 00780 va_list args; 00781 char buf[1024]; 00782 00783 va_start(args, fmt); 00784 vsnprintf(buf, 1024, fmt, args); 00785 va_end(args); 00786 00787 ast_log(LOG_ERROR, buf); 00788 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 790 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00791 { 00792 va_list args; 00793 char buf[1024]; 00794 00795 va_start(args, fmt); 00796 vsnprintf(buf, 1024, fmt, args); 00797 va_end(args); 00798 00799 ast_log(LOG_WARNING, buf); 00800 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11158 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.
11159 { 11160 char *config = "iax.conf"; 11161 int res = 0; 11162 int x; 11163 struct iax2_registry *reg = NULL; 11164 11165 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11166 if (!peers) 11167 return AST_MODULE_LOAD_FAILURE; 11168 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11169 if (!users) { 11170 ao2_ref(peers, -1); 11171 return AST_MODULE_LOAD_FAILURE; 11172 } 11173 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11174 if (!iax_peercallno_pvts) { 11175 ao2_ref(peers, -1); 11176 ao2_ref(users, -1); 11177 return AST_MODULE_LOAD_FAILURE; 11178 } 11179 11180 ast_custom_function_register(&iaxpeer_function); 11181 11182 iax_set_output(iax_debug_output); 11183 iax_set_error(iax_error_output); 11184 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11185 11186 #ifdef HAVE_ZAPTEL 11187 #ifdef ZT_TIMERACK 11188 timingfd = open("/dev/zap/timer", O_RDWR); 11189 if (timingfd < 0) 11190 #endif 11191 timingfd = open("/dev/zap/pseudo", O_RDWR); 11192 if (timingfd < 0) 11193 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11194 #endif 11195 11196 memset(iaxs, 0, sizeof(iaxs)); 11197 11198 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11199 ast_mutex_init(&iaxsl[x]); 11200 } 11201 11202 ast_cond_init(&sched_cond, NULL); 11203 11204 io = io_context_create(); 11205 sched = sched_context_create(); 11206 11207 if (!io || !sched) { 11208 ast_log(LOG_ERROR, "Out of memory\n"); 11209 return -1; 11210 } 11211 11212 netsock = ast_netsock_list_alloc(); 11213 if (!netsock) { 11214 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11215 return -1; 11216 } 11217 ast_netsock_init(netsock); 11218 11219 outsock = ast_netsock_list_alloc(); 11220 if (!outsock) { 11221 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11222 return -1; 11223 } 11224 ast_netsock_init(outsock); 11225 11226 ast_mutex_init(&waresl.lock); 11227 11228 AST_LIST_HEAD_INIT(&iaxq.queue); 11229 11230 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11231 11232 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11233 11234 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11235 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11236 11237 if(set_config(config, 0) == -1) 11238 return AST_MODULE_LOAD_DECLINE; 11239 11240 if (ast_channel_register(&iax2_tech)) { 11241 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11242 __unload_module(); 11243 return -1; 11244 } 11245 11246 if (ast_register_switch(&iax2_switch)) 11247 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11248 11249 res = start_network_thread(); 11250 if (!res) { 11251 if (option_verbose > 1) 11252 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11253 } else { 11254 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11255 ast_netsock_release(netsock); 11256 ast_netsock_release(outsock); 11257 } 11258 11259 AST_LIST_LOCK(®istrations); 11260 AST_LIST_TRAVERSE(®istrations, reg, entry) 11261 iax2_do_register(reg); 11262 AST_LIST_UNLOCK(®istrations); 11263 11264 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11265 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11266 11267 reload_firmware(0); 11268 iax_provision_reload(); 11269 return res; 11270 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3483 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03484 { 03485 ast_mutex_lock(&iaxsl[callno0]); 03486 while (ast_mutex_trylock(&iaxsl[callno1])) { 03487 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03488 } 03489 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1473 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().
01474 { 01475 int x; 01476 int res= 0; 01477 struct timeval now; 01478 if (iaxs[callno]->oseqno) { 01479 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01480 return -1; 01481 } 01482 if (callno & TRUNK_CALL_START) { 01483 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01484 return -1; 01485 } 01486 gettimeofday(&now, NULL); 01487 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01488 ast_mutex_lock(&iaxsl[x]); 01489 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01490 iaxs[x] = iaxs[callno]; 01491 iaxs[x]->callno = x; 01492 iaxs[callno] = NULL; 01493 /* Update the two timers that should have been started */ 01494 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01495 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01496 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01497 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01498 if (locked) 01499 ast_mutex_unlock(&iaxsl[callno]); 01500 res = x; 01501 if (!locked) 01502 ast_mutex_unlock(&iaxsl[x]); 01503 break; 01504 } 01505 ast_mutex_unlock(&iaxsl[x]); 01506 } 01507 if (x >= ARRAY_LEN(iaxs) - 1) { 01508 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01509 return -1; 01510 } 01511 if (option_debug) 01512 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01513 /* We move this call from a non-trunked to a trunked call */ 01514 update_max_trunk(); 01515 update_max_nontrunk(); 01516 return res; 01517 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4736 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
04737 { 04738 ast_cli_netstats(s, -1, 0); 04739 astman_append(s, "\r\n"); 04740 return RESULT_SUCCESS; 04741 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4769 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by load_module().
04770 { 04771 char *a[] = { "iax2", "show", "users" }; 04772 int ret; 04773 const char *id = astman_get_header(m,"ActionID"); 04774 04775 if (!ast_strlen_zero(id)) 04776 astman_append(s, "ActionID: %s\r\n",id); 04777 ret = __iax2_show_peers(1, -1, s, 3, a ); 04778 astman_append(s, "\r\n\r\n" ); 04779 return ret; 04780 } /* /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 1439 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().
01440 { 01441 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01442 (cur->addr.sin_port == sin->sin_port)) { 01443 /* This is the main host */ 01444 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01445 (check_dcallno ? dcallno == cur->callno : 1) ) { 01446 /* That's us. Be sure we keep track of the peer call number */ 01447 return 1; 01448 } 01449 } 01450 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01451 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01452 /* We're transferring */ 01453 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01454 return 1; 01455 } 01456 return 0; 01457 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4138 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04139 { 04140 #if 0 04141 /* Debug with "fake encryption" */ 04142 int x; 04143 if (len % 16) 04144 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04145 for (x=0;x<len;x++) 04146 dst[x] = src[x] ^ 0xff; 04147 #else 04148 unsigned char lastblock[16] = { 0 }; 04149 int x; 04150 while(len > 0) { 04151 aes_decrypt(src, dst, dcx); 04152 for (x=0;x<16;x++) 04153 dst[x] ^= lastblock[x]; 04154 memcpy(lastblock, src, sizeof(lastblock)); 04155 dst += 16; 04156 src += 16; 04157 len -= 16; 04158 } 04159 #endif 04160 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4162 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04163 { 04164 #if 0 04165 /* Debug with "fake encryption" */ 04166 int x; 04167 if (len % 16) 04168 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04169 for (x=0;x<len;x++) 04170 dst[x] = src[x] ^ 0xff; 04171 #else 04172 unsigned char curblock[16] = { 0 }; 04173 int x; 04174 while(len > 0) { 04175 for (x=0;x<16;x++) 04176 curblock[x] ^= src[x]; 04177 aes_encrypt(curblock, dst, ecx); 04178 memcpy(curblock, dst, sizeof(curblock)); 04179 dst += 16; 04180 src += 16; 04181 len -= 16; 04182 } 04183 #endif 04184 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5359 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05360 { 05361 /* Select exactly one common encryption if there are any */ 05362 p->encmethods &= enc; 05363 if (p->encmethods) { 05364 if (p->encmethods & IAX_ENCRYPT_AES128) 05365 p->encmethods = IAX_ENCRYPT_AES128; 05366 else 05367 p->encmethods = 0; 05368 } 05369 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9131 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().
09132 { 09133 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09134 from the network, and queue them for delivery to the channels */ 09135 int res, count, wakeup; 09136 struct iax_frame *f; 09137 09138 if (timingfd > -1) 09139 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09140 09141 for(;;) { 09142 pthread_testcancel(); 09143 09144 /* Go through the queue, sending messages which have not yet been 09145 sent, and scheduling retransmissions if appropriate */ 09146 AST_LIST_LOCK(&iaxq.queue); 09147 count = 0; 09148 wakeup = -1; 09149 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09150 if (f->sentyet) 09151 continue; 09152 09153 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09154 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09155 wakeup = 1; 09156 continue; 09157 } 09158 09159 f->sentyet++; 09160 09161 if (iaxs[f->callno]) { 09162 send_packet(f); 09163 count++; 09164 } 09165 09166 ast_mutex_unlock(&iaxsl[f->callno]); 09167 09168 if (f->retries < 0) { 09169 /* This is not supposed to be retransmitted */ 09170 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09171 iaxq.count--; 09172 /* Free the iax frame */ 09173 iax_frame_free(f); 09174 } else { 09175 /* We need reliable delivery. Schedule a retransmission */ 09176 f->retries++; 09177 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09178 } 09179 } 09180 AST_LIST_TRAVERSE_SAFE_END 09181 AST_LIST_UNLOCK(&iaxq.queue); 09182 09183 pthread_testcancel(); 09184 09185 if (option_debug && count >= 20) 09186 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09187 09188 /* Now do the IO, and run scheduled tasks */ 09189 res = ast_io_wait(io, wakeup); 09190 if (res >= 0) { 09191 if (option_debug && res >= 20) 09192 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09193 } 09194 } 09195 return NULL; 09196 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1380 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().
01381 { 01382 struct chan_iax2_pvt *tmp; 01383 jb_conf jbconf; 01384 01385 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01386 return NULL; 01387 } 01388 01389 if (ast_string_field_init(tmp, 32)) { 01390 ao2_ref(tmp, -1); 01391 tmp = NULL; 01392 return NULL; 01393 } 01394 01395 tmp->prefs = prefs; 01396 tmp->callno = 0; 01397 tmp->peercallno = 0; 01398 tmp->transfercallno = 0; 01399 tmp->bridgecallno = 0; 01400 tmp->pingid = -1; 01401 tmp->lagid = -1; 01402 tmp->autoid = -1; 01403 tmp->authid = -1; 01404 tmp->initid = -1; 01405 01406 ast_string_field_set(tmp,exten, "s"); 01407 ast_string_field_set(tmp,host, host); 01408 01409 tmp->jb = jb_new(); 01410 tmp->jbid = -1; 01411 jbconf.max_jitterbuf = maxjitterbuffer; 01412 jbconf.resync_threshold = resyncthreshold; 01413 jbconf.max_contig_interp = maxjitterinterps; 01414 jb_setconf(tmp->jb,&jbconf); 01415 01416 return tmp; 01417 }
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 3201 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().
03202 { 03203 if (ast_strlen_zero(data)) 03204 return; 03205 03206 pds->peer = strsep(&data, "/"); 03207 pds->exten = strsep(&data, "/"); 03208 pds->options = data; 03209 03210 if (pds->exten) { 03211 data = pds->exten; 03212 pds->exten = strsep(&data, "@"); 03213 pds->context = data; 03214 } 03215 03216 if (strchr(pds->peer, '@')) { 03217 data = pds->peer; 03218 pds->username = strsep(&data, "@"); 03219 pds->peer = data; 03220 } 03221 03222 if (pds->username) { 03223 data = pds->username; 03224 pds->username = strsep(&data, ":"); 03225 pds->password = data; 03226 } 03227 03228 data = pds->peer; 03229 pds->peer = strsep(&data, ":"); 03230 pds->port = data; 03231 03232 /* check for a key name wrapped in [] in the secret position, if found, 03233 move it to the key field instead 03234 */ 03235 if (pds->password && (pds->password[0] == '[')) { 03236 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03237 pds->password = NULL; 03238 } 03239 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1118 of file chan_iax2.c.
Referenced by load_module().
01119 { 01120 struct iax2_peer *peer = obj, *peer2 = arg; 01121 01122 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01123 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9829 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09830 { 09831 struct iax2_peer *peer = obj; 09832 09833 ast_set_flag(peer, IAX_DELME); 09834 09835 return 0; 09836 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9354 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().
09355 { 09356 struct iax2_peer *peer = obj; 09357 09358 ast_free_ha(peer->ha); 09359 09360 if (peer->callno > 0) { 09361 ast_mutex_lock(&iaxsl[peer->callno]); 09362 iax2_destroy(peer->callno); 09363 ast_mutex_unlock(&iaxsl[peer->callno]); 09364 } 09365 09366 register_peer_exten(peer, 0); 09367 09368 if (peer->dnsmgr) 09369 ast_dnsmgr_release(peer->dnsmgr); 09370 09371 ast_string_field_free_memory(peer); 09372 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1108 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01109 { 01110 const struct iax2_peer *peer = obj; 01111 01112 return ast_str_hash(peer->name); 01113 }
Definition at line 1165 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().
01166 { 01167 ao2_ref(peer, +1); 01168 return peer; 01169 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11129 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11130 { 11131 struct iax2_peer *peer = obj; 11132 11133 if (peer->sockfd < 0) 11134 peer->sockfd = defaultsockfd; 11135 11136 return 0; 11137 }
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 9281 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().
09282 { 09283 struct sockaddr_in sin; 09284 int nonlocal = 1; 09285 int port = IAX_DEFAULT_PORTNO; 09286 int sockfd = defaultsockfd; 09287 char *tmp; 09288 char *addr; 09289 char *portstr; 09290 09291 if (!(tmp = ast_strdupa(srcaddr))) 09292 return -1; 09293 09294 addr = strsep(&tmp, ":"); 09295 portstr = tmp; 09296 09297 if (portstr) { 09298 port = atoi(portstr); 09299 if (port < 1) 09300 port = IAX_DEFAULT_PORTNO; 09301 } 09302 09303 if (!ast_get_ip(&sin, addr)) { 09304 struct ast_netsock *sock; 09305 int res; 09306 09307 sin.sin_port = 0; 09308 sin.sin_family = AF_INET; 09309 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09310 if (res == 0) { 09311 /* ip address valid. */ 09312 sin.sin_port = htons(port); 09313 if (!(sock = ast_netsock_find(netsock, &sin))) 09314 sock = ast_netsock_find(outsock, &sin); 09315 if (sock) { 09316 sockfd = ast_netsock_sockfd(sock); 09317 nonlocal = 0; 09318 } else { 09319 unsigned int orig_saddr = sin.sin_addr.s_addr; 09320 /* INADDR_ANY matches anyway! */ 09321 sin.sin_addr.s_addr = INADDR_ANY; 09322 if (ast_netsock_find(netsock, &sin)) { 09323 sin.sin_addr.s_addr = orig_saddr; 09324 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09325 if (sock) { 09326 sockfd = ast_netsock_sockfd(sock); 09327 ast_netsock_unref(sock); 09328 nonlocal = 0; 09329 } else { 09330 nonlocal = 2; 09331 } 09332 } 09333 } 09334 } 09335 } 09336 09337 peer->sockfd = sockfd; 09338 09339 if (nonlocal == 1) { 09340 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09341 srcaddr, peer->name); 09342 return -1; 09343 } else if (nonlocal == 2) { 09344 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09345 srcaddr, peer->name); 09346 return -1; 09347 } else { 09348 if (option_debug) 09349 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09350 return 0; 09351 } 09352 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2328 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().
02329 { 02330 int res = 0; 02331 if (peer->maxms) { 02332 if (peer->lastms < 0) { 02333 ast_copy_string(status, "UNREACHABLE", statuslen); 02334 } else if (peer->lastms > peer->maxms) { 02335 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02336 res = 1; 02337 } else if (peer->lastms) { 02338 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02339 res = 1; 02340 } else { 02341 ast_copy_string(status, "UNKNOWN", statuslen); 02342 } 02343 } else { 02344 ast_copy_string(status, "Unmonitored", statuslen); 02345 res = -1; 02346 } 02347 return res; 02348 }
Definition at line 1171 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().
01172 { 01173 ao2_ref(peer, -1); 01174 return NULL; 01175 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10290 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10291 { 10292 struct ao2_iterator i; 10293 struct iax2_peer *peer; 10294 10295 i = ao2_iterator_init(peers, 0); 10296 while ((peer = ao2_iterator_next(&i))) { 10297 iax2_poke_peer(peer, 0); 10298 peer_unref(peer); 10299 } 10300 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9887 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09888 { 09889 struct iax2_peer *peer; 09890 struct ao2_iterator i; 09891 09892 i = ao2_iterator_init(peers, 0); 09893 while ((peer = ao2_iterator_next(&i))) { 09894 if (ast_test_flag(peer, IAX_DELME)) 09895 unlink_peer(peer); 09896 peer_unref(peer); 09897 } 09898 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9873 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().
09874 { 09875 struct iax2_user *user; 09876 struct ao2_iterator i; 09877 09878 i = ao2_iterator_init(users, 0); 09879 while ((user = ao2_iterator_next(&i))) { 09880 if (ast_test_flag(user, IAX_DELME)) 09881 ao2_unlink(users, user); 09882 user_unref(user); 09883 } 09884 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11146 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11147 { 11148 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11149 11150 /* The frames_received field is used to hold whether we're matching 11151 * against a full frame or not ... */ 11152 11153 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11154 pvt2->frames_received) ? CMP_MATCH : 0; 11155 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1341 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().
01342 { 01343 struct chan_iax2_pvt *pvt = obj; 01344 struct iax_frame *cur = NULL; 01345 01346 iax2_destroy_helper(pvt); 01347 01348 /* Already gone */ 01349 ast_set_flag(pvt, IAX_ALREADYGONE); 01350 01351 AST_LIST_LOCK(&iaxq.queue); 01352 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01353 /* Cancel any pending transmissions */ 01354 if (cur->callno == pvt->callno) { 01355 cur->retries = -1; 01356 } 01357 } 01358 AST_LIST_UNLOCK(&iaxq.queue); 01359 01360 if (pvt->reg) { 01361 pvt->reg->callno = 0; 01362 } 01363 01364 if (!pvt->owner) { 01365 jb_frame frame; 01366 if (pvt->vars) { 01367 ast_variables_destroy(pvt->vars); 01368 pvt->vars = NULL; 01369 } 01370 01371 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01372 iax2_frame_free(frame.data); 01373 } 01374 01375 jb_destroy(pvt->jb); 01376 ast_string_field_free_memory(pvt); 01377 } 01378 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11139 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11140 { 11141 const struct chan_iax2_pvt *pvt = obj; 11142 11143 return pvt->peercallno; 11144 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5341 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().
05342 { 05343 struct ast_iax2_full_hdr fh; 05344 fh.scallno = htons(src | IAX_FLAG_FULL); 05345 fh.dcallno = htons(dst); 05346 fh.ts = 0; 05347 fh.oseqno = 0; 05348 fh.iseqno = 0; 05349 fh.type = AST_FRAME_IAX; 05350 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05351 if (iaxdebug) 05352 iax_showframe(NULL, &fh, 0, sin, 0); 05353 if (option_debug) 05354 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05355 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05356 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05357 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2803 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.
02804 { 02805 struct ast_variable *var = NULL; 02806 struct ast_variable *tmp; 02807 struct iax2_peer *peer=NULL; 02808 time_t regseconds = 0, nowtime; 02809 int dynamic=0; 02810 02811 if (peername) { 02812 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02813 if (!var && sin) 02814 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02815 } else if (sin) { 02816 char porta[25]; 02817 sprintf(porta, "%d", ntohs(sin->sin_port)); 02818 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02819 if (var) { 02820 /* We'll need the peer name in order to build the structure! */ 02821 for (tmp = var; tmp; tmp = tmp->next) { 02822 if (!strcasecmp(tmp->name, "name")) 02823 peername = tmp->value; 02824 } 02825 } 02826 } 02827 if (!var && peername) { /* Last ditch effort */ 02828 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02829 /*!\note 02830 * If this one loaded something, then we need to ensure that the host 02831 * field matched. The only reason why we can't have this as a criteria 02832 * is because we only have the IP address and the host field might be 02833 * set as a name (and the reverse PTR might not match). 02834 */ 02835 if (var && sin) { 02836 for (tmp = var; tmp; tmp = tmp->next) { 02837 if (!strcasecmp(tmp->name, "host")) { 02838 struct ast_hostent ahp; 02839 struct hostent *hp; 02840 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02841 /* No match */ 02842 ast_variables_destroy(var); 02843 var = NULL; 02844 } 02845 break; 02846 } 02847 } 02848 } 02849 } 02850 if (!var) 02851 return NULL; 02852 02853 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02854 02855 if (!peer) { 02856 ast_variables_destroy(var); 02857 return NULL; 02858 } 02859 02860 for (tmp = var; tmp; tmp = tmp->next) { 02861 /* Make sure it's not a user only... */ 02862 if (!strcasecmp(tmp->name, "type")) { 02863 if (strcasecmp(tmp->value, "friend") && 02864 strcasecmp(tmp->value, "peer")) { 02865 /* Whoops, we weren't supposed to exist! */ 02866 peer = peer_unref(peer); 02867 break; 02868 } 02869 } else if (!strcasecmp(tmp->name, "regseconds")) { 02870 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02871 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02872 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02873 } else if (!strcasecmp(tmp->name, "port")) { 02874 peer->addr.sin_port = htons(atoi(tmp->value)); 02875 } else if (!strcasecmp(tmp->name, "host")) { 02876 if (!strcasecmp(tmp->value, "dynamic")) 02877 dynamic = 1; 02878 } 02879 } 02880 02881 ast_variables_destroy(var); 02882 02883 if (!peer) 02884 return NULL; 02885 02886 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02887 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02888 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02889 if (peer->expire > -1) { 02890 if (!ast_sched_del(sched, peer->expire)) { 02891 peer->expire = -1; 02892 peer_unref(peer); 02893 } 02894 } 02895 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02896 if (peer->expire == -1) 02897 peer_unref(peer); 02898 } 02899 ao2_link(peers, peer); 02900 if (ast_test_flag(peer, IAX_DYNAMIC)) 02901 reg_source_db(peer); 02902 } else { 02903 ast_set_flag(peer, IAX_TEMPONLY); 02904 } 02905 02906 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02907 time(&nowtime); 02908 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02909 memset(&peer->addr, 0, sizeof(peer->addr)); 02910 realtime_update_peer(peer->name, &peer->addr, 0); 02911 if (option_debug) 02912 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02913 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02914 } 02915 else { 02916 if (option_debug) 02917 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02918 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02919 } 02920 } 02921 02922 return peer; 02923 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2996 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
02997 { 02998 char port[10]; 02999 char regseconds[20]; 03000 03001 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03002 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03003 ast_update_realtime("iaxpeers", "name", peername, 03004 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03005 "regseconds", regseconds, NULL); 03006 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2925 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.
02926 { 02927 struct ast_variable *var; 02928 struct ast_variable *tmp; 02929 struct iax2_user *user=NULL; 02930 02931 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02932 if (!var) 02933 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02934 if (!var && sin) { 02935 char porta[6]; 02936 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02937 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02938 if (!var) 02939 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02940 } 02941 if (!var) { /* Last ditch effort */ 02942 var = ast_load_realtime("iaxusers", "name", username, NULL); 02943 /*!\note 02944 * If this one loaded something, then we need to ensure that the host 02945 * field matched. The only reason why we can't have this as a criteria 02946 * is because we only have the IP address and the host field might be 02947 * set as a name (and the reverse PTR might not match). 02948 */ 02949 if (var) { 02950 for (tmp = var; tmp; tmp = tmp->next) { 02951 if (!strcasecmp(tmp->name, "host")) { 02952 struct ast_hostent ahp; 02953 struct hostent *hp; 02954 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02955 /* No match */ 02956 ast_variables_destroy(var); 02957 var = NULL; 02958 } 02959 break; 02960 } 02961 } 02962 } 02963 } 02964 if (!var) 02965 return NULL; 02966 02967 tmp = var; 02968 while(tmp) { 02969 /* Make sure it's not a peer only... */ 02970 if (!strcasecmp(tmp->name, "type")) { 02971 if (strcasecmp(tmp->value, "friend") && 02972 strcasecmp(tmp->value, "user")) { 02973 return NULL; 02974 } 02975 } 02976 tmp = tmp->next; 02977 } 02978 02979 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02980 02981 ast_variables_destroy(var); 02982 02983 if (!user) 02984 return NULL; 02985 02986 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02987 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02988 ao2_link(users, user); 02989 } else { 02990 ast_set_flag(user, IAX_TEMPONLY); 02991 } 02992 02993 return user; 02994 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6146 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().
06147 { 06148 char data[80]; 06149 struct in_addr in; 06150 char *c, *d; 06151 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06152 c = strchr(data, ':'); 06153 if (c) { 06154 *c = '\0'; 06155 c++; 06156 if (inet_aton(data, &in)) { 06157 d = strchr(c, ':'); 06158 if (d) { 06159 *d = '\0'; 06160 d++; 06161 if (option_verbose > 2) 06162 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06163 ast_inet_ntoa(in), atoi(c), atoi(d)); 06164 iax2_poke_peer(p, 0); 06165 p->expiry = atoi(d); 06166 memset(&p->addr, 0, sizeof(p->addr)); 06167 p->addr.sin_family = AF_INET; 06168 p->addr.sin_addr = in; 06169 p->addr.sin_port = htons(atoi(c)); 06170 if (p->expire > -1) { 06171 if (!ast_sched_del(sched, p->expire)) { 06172 p->expire = -1; 06173 peer_unref(p); 06174 } 06175 } 06176 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06177 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06178 if (p->expire == -1) 06179 peer_unref(p); 06180 if (iax2_regfunk) 06181 iax2_regfunk(p->name, 1); 06182 register_peer_exten(p, 1); 06183 } 06184 06185 } 06186 } 06187 } 06188 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6066 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().
06067 { 06068 char multi[256]; 06069 char *stringp, *ext; 06070 if (!ast_strlen_zero(regcontext)) { 06071 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06072 stringp = multi; 06073 while((ext = strsep(&stringp, "&"))) { 06074 if (onoff) { 06075 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06076 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06077 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06078 } else 06079 ast_context_remove_extension(regcontext, ext, 1, NULL); 06080 } 06081 } 06082 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5508 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().
05509 { 05510 char requeststr[256] = ""; 05511 char peer[256] = ""; 05512 char md5secret[256] = ""; 05513 char rsasecret[256] = ""; 05514 char secret[256] = ""; 05515 struct iax2_peer *p = NULL; 05516 struct ast_key *key; 05517 char *keyn; 05518 int x; 05519 int expire = 0; 05520 int res = -1; 05521 05522 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05523 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05524 if (ies->username) 05525 ast_copy_string(peer, ies->username, sizeof(peer)); 05526 if (ies->password) 05527 ast_copy_string(secret, ies->password, sizeof(secret)); 05528 if (ies->md5_result) 05529 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05530 if (ies->rsa_result) 05531 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05532 if (ies->refresh) 05533 expire = ies->refresh; 05534 05535 if (ast_strlen_zero(peer)) { 05536 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05537 return -1; 05538 } 05539 05540 /* SLD: first call to lookup peer during registration */ 05541 ast_mutex_unlock(&iaxsl[callno]); 05542 p = find_peer(peer, 1); 05543 ast_mutex_lock(&iaxsl[callno]); 05544 if (!p || !iaxs[callno]) { 05545 if (iaxs[callno]) { 05546 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 05547 05548 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05549 05550 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 05551 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 05552 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 05553 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 05554 * to be plaintext, indicating it is an authmethod used by other peers on the system. 05555 * 05556 * If none of these cases exist, res will be returned as 0 without authentication indicating 05557 * an AUTHREQ needs to be sent out. */ 05558 05559 if (ast_strlen_zero(iaxs[callno]->challenge) && 05560 !(!ast_strlen_zero(secret) && plaintext)) { 05561 /* by setting res to 0, an REGAUTH will be sent */ 05562 res = 0; 05563 } 05564 } 05565 if (authdebug && !p) 05566 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05567 05568 goto return_unref; 05569 } 05570 05571 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05572 if (authdebug) 05573 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05574 goto return_unref; 05575 } 05576 05577 if (!ast_apply_ha(p->ha, sin)) { 05578 if (authdebug) 05579 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05580 goto return_unref; 05581 } 05582 ast_string_field_set(iaxs[callno], secret, p->secret); 05583 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05584 /* Check secret against what we have on file */ 05585 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05586 if (!ast_strlen_zero(p->inkeys)) { 05587 char tmpkeys[256]; 05588 char *stringp=NULL; 05589 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05590 stringp=tmpkeys; 05591 keyn = strsep(&stringp, ":"); 05592 while(keyn) { 05593 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05594 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05595 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05596 break; 05597 } else if (!key) 05598 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05599 keyn = strsep(&stringp, ":"); 05600 } 05601 if (!keyn) { 05602 if (authdebug) 05603 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05604 goto return_unref; 05605 } 05606 } else { 05607 if (authdebug) 05608 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05609 goto return_unref; 05610 } 05611 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05612 struct MD5Context md5; 05613 unsigned char digest[16]; 05614 char *tmppw, *stringp; 05615 05616 tmppw = ast_strdupa(p->secret); 05617 stringp = tmppw; 05618 while((tmppw = strsep(&stringp, ";"))) { 05619 MD5Init(&md5); 05620 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05621 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05622 MD5Final(digest, &md5); 05623 for (x=0;x<16;x++) 05624 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05625 if (!strcasecmp(requeststr, md5secret)) 05626 break; 05627 } 05628 if (tmppw) { 05629 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05630 } else { 05631 if (authdebug) 05632 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05633 goto return_unref; 05634 } 05635 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05636 /* They've provided a plain text password and we support that */ 05637 if (strcmp(secret, p->secret)) { 05638 if (authdebug) 05639 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05640 goto return_unref; 05641 } else 05642 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05643 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 05644 /* if challenge has been sent, but no challenge response if given, reject. */ 05645 goto return_unref; 05646 } 05647 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05648 05649 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 05650 res = 0; 05651 return_unref: 05652 if (iaxs[callno]) { 05653 ast_string_field_set(iaxs[callno], peer, peer); 05654 } 05655 /* Choose lowest expiry number */ 05656 if (expire && (expire < iaxs[callno]->expiry)) { 05657 iaxs[callno]->expiry = expire; 05658 } 05659 05660 if (p) 05661 peer_unref(p); 05662 return res; 05663 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6325 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().
06326 { 06327 struct iax_ie_data ied; 06328 struct iax2_peer *p; 06329 char challenge[10]; 06330 const char *peer_name; 06331 int sentauthmethod; 06332 06333 peer_name = ast_strdupa(iaxs[callno]->peer); 06334 06335 /* SLD: third call to find_peer in registration */ 06336 ast_mutex_unlock(&iaxsl[callno]); 06337 if ((p = find_peer(peer_name, 1))) { 06338 last_authmethod = p->authmethods; 06339 } 06340 06341 ast_mutex_lock(&iaxsl[callno]); 06342 if (!iaxs[callno]) 06343 goto return_unref; 06344 06345 memset(&ied, 0, sizeof(ied)); 06346 /* The selection of which delayed reject is sent may leak information, 06347 * if it sets a static response. For example, if a host is known to only 06348 * use MD5 authentication, then an RSA response would indicate that the 06349 * peer does not exist, and vice-versa. 06350 * Therefore, we use whatever the last peer used (which may vary over the 06351 * course of a server, which should leak minimal information). */ 06352 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06353 if (!p) { 06354 iaxs[callno]->authmethods = sentauthmethod; 06355 } 06356 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06357 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06358 /* Build the challenge */ 06359 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06360 ast_string_field_set(iaxs[callno], challenge, challenge); 06361 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06362 } 06363 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06364 06365 return_unref: 06366 if (p) { 06367 peer_unref(p); 06368 } 06369 06370 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06371 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6373 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().
06374 { 06375 struct iax2_registry *reg; 06376 /* Start pessimistic */ 06377 struct iax_ie_data ied; 06378 char peer[256] = ""; 06379 char challenge[256] = ""; 06380 int res; 06381 int authmethods = 0; 06382 if (ies->authmethods) 06383 authmethods = ies->authmethods; 06384 if (ies->username) 06385 ast_copy_string(peer, ies->username, sizeof(peer)); 06386 if (ies->challenge) 06387 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06388 memset(&ied, 0, sizeof(ied)); 06389 reg = iaxs[callno]->reg; 06390 if (reg) { 06391 if (inaddrcmp(®->addr, sin)) { 06392 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06393 return -1; 06394 } 06395 if (ast_strlen_zero(reg->secret)) { 06396 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06397 reg->regstate = REG_STATE_NOAUTH; 06398 return -1; 06399 } 06400 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06401 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06402 if (reg->secret[0] == '[') { 06403 char tmpkey[256]; 06404 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06405 tmpkey[strlen(tmpkey) - 1] = '\0'; 06406 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 06407 } else 06408 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 06409 if (!res) { 06410 reg->regstate = REG_STATE_AUTHSENT; 06411 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06412 } else 06413 return -1; 06414 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06415 } else 06416 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06417 return -1; 06418 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4782 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().
04783 { 04784 switch(regstate) { 04785 case REG_STATE_UNREGISTERED: 04786 return "Unregistered"; 04787 case REG_STATE_REGSENT: 04788 return "Request Sent"; 04789 case REG_STATE_AUTHSENT: 04790 return "Auth. Sent"; 04791 case REG_STATE_REGISTERED: 04792 return "Registered"; 04793 case REG_STATE_REJECTED: 04794 return "Rejected"; 04795 case REG_STATE_TIMEOUT: 04796 return "Timeout"; 04797 case REG_STATE_NOAUTH: 04798 return "No Authentication"; 04799 default: 04800 return "Unknown"; 04801 } 04802 }
static int reload | ( | void | ) | [static] |
Definition at line 10327 of file chan_iax2.c.
References reload_config().
10328 { 10329 return reload_config(); 10330 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10301 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().
10302 { 10303 char *config = "iax.conf"; 10304 struct iax2_registry *reg; 10305 10306 if (set_config(config, 1) > 0) { 10307 prune_peers(); 10308 prune_users(); 10309 AST_LIST_LOCK(®istrations); 10310 AST_LIST_TRAVERSE(®istrations, reg, entry) 10311 iax2_do_register(reg); 10312 AST_LIST_UNLOCK(®istrations); 10313 /* Qualify hosts, too */ 10314 poke_all_peers(); 10315 } 10316 reload_firmware(0); 10317 iax_provision_reload(); 10318 10319 return 0; 10320 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1961 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().
01962 { 01963 struct iax_firmware *cur, *curl, *curp; 01964 DIR *fwd; 01965 struct dirent *de; 01966 char dir[256]; 01967 char fn[256]; 01968 /* Mark all as dead */ 01969 ast_mutex_lock(&waresl.lock); 01970 cur = waresl.wares; 01971 while(cur) { 01972 cur->dead = 1; 01973 cur = cur->next; 01974 } 01975 01976 /* Now that we've freed them, load the new ones */ 01977 if (!unload) { 01978 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01979 fwd = opendir(dir); 01980 if (fwd) { 01981 while((de = readdir(fwd))) { 01982 if (de->d_name[0] != '.') { 01983 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01984 if (!try_firmware(fn)) { 01985 if (option_verbose > 1) 01986 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01987 } 01988 } 01989 } 01990 closedir(fwd); 01991 } else 01992 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01993 } 01994 01995 /* Clean up leftovers */ 01996 cur = waresl.wares; 01997 curp = NULL; 01998 while(cur) { 01999 curl = cur; 02000 cur = cur->next; 02001 if (curl->dead) { 02002 if (curp) { 02003 curp->next = cur; 02004 } else { 02005 waresl.wares = cur; 02006 } 02007 destroy_firmware(curl); 02008 } else { 02009 curp = cur; 02010 } 02011 } 02012 ast_mutex_unlock(&waresl.lock); 02013 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1256 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().
01257 { 01258 if (!pvt->peercallno) { 01259 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01260 return; 01261 } 01262 01263 ao2_unlink(iax_peercallno_pvts, pvt); 01264 }
Definition at line 6877 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().
06878 { 06879 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06880 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06881 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06882 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06883 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06884 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06885 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06886 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9103 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().
09104 { 09105 int count; 09106 int res; 09107 struct timeval tv; 09108 struct timespec ts; 09109 09110 for (;;) { 09111 res = ast_sched_wait(sched); 09112 if ((res > 1000) || (res < 0)) 09113 res = 1000; 09114 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09115 ts.tv_sec = tv.tv_sec; 09116 ts.tv_nsec = tv.tv_usec * 1000; 09117 09118 pthread_testcancel(); 09119 ast_mutex_lock(&sched_lock); 09120 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09121 ast_mutex_unlock(&sched_lock); 09122 pthread_testcancel(); 09123 09124 count = ast_sched_runq(sched); 09125 if (option_debug && count >= 20) 09126 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09127 } 09128 return NULL; 09129 }
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 2656 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().
02657 { 02658 int type, len; 02659 int ret; 02660 int needfree = 0; 02661 struct ast_channel *owner = NULL; 02662 struct ast_channel *bridge = NULL; 02663 02664 /* Attempt to recover wrapped timestamps */ 02665 unwrap_timestamp(fr); 02666 02667 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02668 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02669 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02670 else { 02671 #if 0 02672 if (option_debug) 02673 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02674 #endif 02675 fr->af.delivery = ast_tv(0,0); 02676 } 02677 02678 type = JB_TYPE_CONTROL; 02679 len = 0; 02680 02681 if(fr->af.frametype == AST_FRAME_VOICE) { 02682 type = JB_TYPE_VOICE; 02683 len = ast_codec_get_samples(&fr->af) / 8; 02684 } else if(fr->af.frametype == AST_FRAME_CNG) { 02685 type = JB_TYPE_SILENCE; 02686 } 02687 02688 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02689 if (tsout) 02690 *tsout = fr->ts; 02691 __do_deliver(fr); 02692 return -1; 02693 } 02694 02695 if ((owner = iaxs[fr->callno]->owner)) 02696 bridge = ast_bridged_channel(owner); 02697 02698 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02699 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02700 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02701 jb_frame frame; 02702 02703 /* deliver any frames in the jb */ 02704 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02705 __do_deliver(frame.data); 02706 /* __do_deliver() can make the call disappear */ 02707 if (!iaxs[fr->callno]) 02708 return -1; 02709 } 02710 02711 jb_reset(iaxs[fr->callno]->jb); 02712 02713 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02714 02715 /* deliver this frame now */ 02716 if (tsout) 02717 *tsout = fr->ts; 02718 __do_deliver(fr); 02719 return -1; 02720 } 02721 02722 /* insert into jitterbuffer */ 02723 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02724 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02725 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02726 if (ret == JB_DROP) { 02727 needfree++; 02728 } else if (ret == JB_SCHED) { 02729 update_jbsched(iaxs[fr->callno]); 02730 } 02731 if (tsout) 02732 *tsout = fr->ts; 02733 if (needfree) { 02734 /* Free our iax frame */ 02735 iax2_frame_free(fr); 02736 return -1; 02737 } 02738 return 0; 02739 }
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 3174 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and ast_iax2_full_hdr::scallno.
Referenced by socket_process().
03175 { 03176 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03177 .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX, 03178 .csub = compress_subclass(command) }; 03179 03180 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03181 }
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 5066 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().
05067 { 05068 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05069 }
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 5085 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().
05086 { 05087 int call_num = i->callno; 05088 /* It is assumed that the callno has already been locked */ 05089 iax2_predestroy(i->callno); 05090 if (!iaxs[call_num]) 05091 return -1; 05092 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05093 }
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 5095 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05096 { 05097 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05098 }
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 5071 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().
05072 { 05073 int res; 05074 ast_mutex_lock(&iaxsl[callno]); 05075 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05076 ast_mutex_unlock(&iaxsl[callno]); 05077 return res; 05078 }
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 5100 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05101 { 05102 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05103 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1062 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01063 { 01064 #ifdef SCHED_MULTITHREADED 01065 if (schedule_action(__send_lagrq, data)) 01066 #endif 01067 __send_lagrq(data); 01068 return 0; 01069 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2086 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().
02087 { 02088 int res; 02089 int callno = f->callno; 02090 02091 /* Don't send if there was an error, but return error instead */ 02092 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02093 return -1; 02094 02095 /* Called with iaxsl held */ 02096 if (option_debug > 2 && iaxdebug) 02097 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)); 02098 if (f->transfer) { 02099 if (iaxdebug) 02100 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02101 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02102 sizeof(iaxs[callno]->transfer)); 02103 } else { 02104 if (iaxdebug) 02105 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02106 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02107 sizeof(iaxs[callno]->addr)); 02108 } 02109 if (res < 0) { 02110 if (option_debug && iaxdebug) 02111 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02112 handle_error(); 02113 } else 02114 res = 0; 02115 return res; 02116 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1022 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01023 { 01024 #ifdef SCHED_MULTITHREADED 01025 if (schedule_action(__send_ping, data)) 01026 #endif 01027 __send_ping(data); 01028 return 0; 01029 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6555 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().
06556 { 06557 int res = 0; 06558 struct iax_frame *fr; 06559 struct ast_iax2_meta_hdr *meta; 06560 struct ast_iax2_meta_trunk_hdr *mth; 06561 int calls = 0; 06562 06563 /* Point to frame */ 06564 fr = (struct iax_frame *)tpeer->trunkdata; 06565 /* Point to meta data */ 06566 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06567 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06568 if (tpeer->trunkdatalen) { 06569 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06570 meta->zeros = 0; 06571 meta->metacmd = IAX_META_TRUNK; 06572 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06573 meta->cmddata = IAX_META_TRUNK_MINI; 06574 else 06575 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06576 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06577 /* And the rest of the ast_iax2 header */ 06578 fr->direction = DIRECTION_OUTGRESS; 06579 fr->retrans = -1; 06580 fr->transfer = 0; 06581 /* Any appropriate call will do */ 06582 fr->data = fr->afdata; 06583 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06584 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06585 calls = tpeer->calls; 06586 #if 0 06587 if (option_debug) 06588 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)); 06589 #endif 06590 /* Reset transmit trunk side data */ 06591 tpeer->trunkdatalen = 0; 06592 tpeer->calls = 0; 06593 } 06594 if (res < 0) 06595 return res; 06596 return calls; 06597 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9931 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().
09932 { 09933 struct ast_config *cfg, *ucfg; 09934 int capability=iax2_capability; 09935 struct ast_variable *v; 09936 char *cat; 09937 const char *utype; 09938 const char *tosval; 09939 int format; 09940 int portno = IAX_DEFAULT_PORTNO; 09941 int x; 09942 struct iax2_user *user; 09943 struct iax2_peer *peer; 09944 struct ast_netsock *ns; 09945 #if 0 09946 static unsigned short int last_port=0; 09947 #endif 09948 09949 cfg = ast_config_load(config_file); 09950 09951 if (!cfg) { 09952 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09953 return -1; 09954 } 09955 09956 if (reload) { 09957 set_config_destroy(); 09958 } 09959 09960 /* Reset global codec prefs */ 09961 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09962 09963 /* Reset Global Flags */ 09964 memset(&globalflags, 0, sizeof(globalflags)); 09965 ast_set_flag(&globalflags, IAX_RTUPDATE); 09966 09967 #ifdef SO_NO_CHECK 09968 nochecksums = 0; 09969 #endif 09970 09971 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09972 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09973 09974 maxauthreq = 3; 09975 09976 v = ast_variable_browse(cfg, "general"); 09977 09978 /* Seed initial tos value */ 09979 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09980 if (tosval) { 09981 if (ast_str2tos(tosval, &tos)) 09982 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09983 } 09984 while(v) { 09985 if (!strcasecmp(v->name, "bindport")){ 09986 if (reload) 09987 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09988 else 09989 portno = atoi(v->value); 09990 } else if (!strcasecmp(v->name, "pingtime")) 09991 ping_time = atoi(v->value); 09992 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09993 if (reload) { 09994 if (atoi(v->value) != iaxthreadcount) 09995 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09996 } else { 09997 iaxthreadcount = atoi(v->value); 09998 if (iaxthreadcount < 1) { 09999 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 10000 iaxthreadcount = 1; 10001 } else if (iaxthreadcount > 256) { 10002 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 10003 iaxthreadcount = 256; 10004 } 10005 } 10006 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 10007 if (reload) { 10008 AST_LIST_LOCK(&dynamic_list); 10009 iaxmaxthreadcount = atoi(v->value); 10010 AST_LIST_UNLOCK(&dynamic_list); 10011 } else { 10012 iaxmaxthreadcount = atoi(v->value); 10013 if (iaxmaxthreadcount < 0) { 10014 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 10015 iaxmaxthreadcount = 0; 10016 } else if (iaxmaxthreadcount > 256) { 10017 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 10018 iaxmaxthreadcount = 256; 10019 } 10020 } 10021 } else if (!strcasecmp(v->name, "nochecksums")) { 10022 #ifdef SO_NO_CHECK 10023 if (ast_true(v->value)) 10024 nochecksums = 1; 10025 else 10026 nochecksums = 0; 10027 #else 10028 if (ast_true(v->value)) 10029 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 10030 #endif 10031 } 10032 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10033 maxjitterbuffer = atoi(v->value); 10034 else if (!strcasecmp(v->name, "resyncthreshold")) 10035 resyncthreshold = atoi(v->value); 10036 else if (!strcasecmp(v->name, "maxjitterinterps")) 10037 maxjitterinterps = atoi(v->value); 10038 else if (!strcasecmp(v->name, "lagrqtime")) 10039 lagrq_time = atoi(v->value); 10040 else if (!strcasecmp(v->name, "maxregexpire")) 10041 max_reg_expire = atoi(v->value); 10042 else if (!strcasecmp(v->name, "minregexpire")) 10043 min_reg_expire = atoi(v->value); 10044 else if (!strcasecmp(v->name, "bindaddr")) { 10045 if (reload) { 10046 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10047 } else { 10048 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10049 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10050 } else { 10051 if (option_verbose > 1) { 10052 if (strchr(v->value, ':')) 10053 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10054 else 10055 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10056 } 10057 if (defaultsockfd < 0) 10058 defaultsockfd = ast_netsock_sockfd(ns); 10059 ast_netsock_unref(ns); 10060 } 10061 } 10062 } else if (!strcasecmp(v->name, "authdebug")) 10063 authdebug = ast_true(v->value); 10064 else if (!strcasecmp(v->name, "encryption")) 10065 iax2_encryption = get_encrypt_methods(v->value); 10066 else if (!strcasecmp(v->name, "notransfer")) { 10067 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10068 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10069 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10070 } else if (!strcasecmp(v->name, "transfer")) { 10071 if (!strcasecmp(v->value, "mediaonly")) { 10072 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10073 } else if (ast_true(v->value)) { 10074 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10075 } else 10076 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10077 } else if (!strcasecmp(v->name, "codecpriority")) { 10078 if(!strcasecmp(v->value, "caller")) 10079 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10080 else if(!strcasecmp(v->value, "disabled")) 10081 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10082 else if(!strcasecmp(v->value, "reqonly")) { 10083 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10084 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10085 } 10086 } else if (!strcasecmp(v->name, "jitterbuffer")) 10087 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10088 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10089 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10090 else if (!strcasecmp(v->name, "delayreject")) 10091 delayreject = ast_true(v->value); 10092 else if (!strcasecmp(v->name, "allowfwdownload")) 10093 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10094 else if (!strcasecmp(v->name, "rtcachefriends")) 10095 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10096 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10097 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10098 else if (!strcasecmp(v->name, "rtupdate")) 10099 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10100 else if (!strcasecmp(v->name, "trunktimestamps")) 10101 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10102 else if (!strcasecmp(v->name, "rtautoclear")) { 10103 int i = atoi(v->value); 10104 if(i > 0) 10105 global_rtautoclear = i; 10106 else 10107 i = 0; 10108 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10109 } else if (!strcasecmp(v->name, "trunkfreq")) { 10110 trunkfreq = atoi(v->value); 10111 if (trunkfreq < 10) 10112 trunkfreq = 10; 10113 } else if (!strcasecmp(v->name, "autokill")) { 10114 if (sscanf(v->value, "%d", &x) == 1) { 10115 if (x >= 0) 10116 autokill = x; 10117 else 10118 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10119 } else if (ast_true(v->value)) { 10120 autokill = DEFAULT_MAXMS; 10121 } else { 10122 autokill = 0; 10123 } 10124 } else if (!strcasecmp(v->name, "bandwidth")) { 10125 if (!strcasecmp(v->value, "low")) { 10126 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10127 } else if (!strcasecmp(v->value, "medium")) { 10128 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10129 } else if (!strcasecmp(v->value, "high")) { 10130 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10131 } else 10132 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10133 } else if (!strcasecmp(v->name, "allow")) { 10134 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10135 } else if (!strcasecmp(v->name, "disallow")) { 10136 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10137 } else if (!strcasecmp(v->name, "register")) { 10138 iax2_register(v->value, v->lineno); 10139 } else if (!strcasecmp(v->name, "iaxcompat")) { 10140 iaxcompat = ast_true(v->value); 10141 } else if (!strcasecmp(v->name, "regcontext")) { 10142 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10143 /* Create context if it doesn't exist already */ 10144 if (!ast_context_find(regcontext)) 10145 ast_context_create(NULL, regcontext, "IAX2"); 10146 } else if (!strcasecmp(v->name, "tos")) { 10147 if (ast_str2tos(v->value, &tos)) 10148 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10149 } else if (!strcasecmp(v->name, "accountcode")) { 10150 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10151 } else if (!strcasecmp(v->name, "mohinterpret")) { 10152 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 10153 } else if (!strcasecmp(v->name, "mohsuggest")) { 10154 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 10155 } else if (!strcasecmp(v->name, "amaflags")) { 10156 format = ast_cdr_amaflags2int(v->value); 10157 if (format < 0) { 10158 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10159 } else { 10160 amaflags = format; 10161 } 10162 } else if (!strcasecmp(v->name, "language")) { 10163 ast_copy_string(language, v->value, sizeof(language)); 10164 } else if (!strcasecmp(v->name, "maxauthreq")) { 10165 maxauthreq = atoi(v->value); 10166 if (maxauthreq < 0) 10167 maxauthreq = 0; 10168 } else if (!strcasecmp(v->name, "adsi")) { 10169 adsi = ast_true(v->value); 10170 } /*else if (strcasecmp(v->name,"type")) */ 10171 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10172 v = v->next; 10173 } 10174 10175 if (defaultsockfd < 0) { 10176 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10177 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10178 } else { 10179 if (option_verbose > 1) 10180 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10181 defaultsockfd = ast_netsock_sockfd(ns); 10182 ast_netsock_unref(ns); 10183 } 10184 } 10185 if (reload) { 10186 ast_netsock_release(outsock); 10187 outsock = ast_netsock_list_alloc(); 10188 if (!outsock) { 10189 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10190 return -1; 10191 } 10192 ast_netsock_init(outsock); 10193 } 10194 10195 if (min_reg_expire > max_reg_expire) { 10196 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10197 min_reg_expire, max_reg_expire, max_reg_expire); 10198 min_reg_expire = max_reg_expire; 10199 } 10200 iax2_capability = capability; 10201 10202 ucfg = ast_config_load("users.conf"); 10203 if (ucfg) { 10204 struct ast_variable *gen; 10205 int genhasiax; 10206 int genregisteriax; 10207 const char *hasiax, *registeriax; 10208 10209 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10210 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10211 gen = ast_variable_browse(ucfg, "general"); 10212 cat = ast_category_browse(ucfg, NULL); 10213 while (cat) { 10214 if (strcasecmp(cat, "general")) { 10215 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10216 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10217 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10218 /* Start with general parameters, then specific parameters, user and peer */ 10219 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10220 if (user) { 10221 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10222 user = user_unref(user); 10223 } 10224 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10225 if (peer) { 10226 if (ast_test_flag(peer, IAX_DYNAMIC)) 10227 reg_source_db(peer); 10228 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10229 peer = peer_unref(peer); 10230 } 10231 } 10232 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10233 char tmp[256]; 10234 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10235 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10236 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10237 if (!host) 10238 host = ast_variable_retrieve(ucfg, "general", "host"); 10239 if (!username) 10240 username = ast_variable_retrieve(ucfg, "general", "username"); 10241 if (!secret) 10242 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10243 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10244 if (!ast_strlen_zero(secret)) 10245 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10246 else 10247 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10248 iax2_register(tmp, 0); 10249 } 10250 } 10251 } 10252 cat = ast_category_browse(ucfg, cat); 10253 } 10254 ast_config_destroy(ucfg); 10255 } 10256 10257 cat = ast_category_browse(cfg, NULL); 10258 while(cat) { 10259 if (strcasecmp(cat, "general")) { 10260 utype = ast_variable_retrieve(cfg, cat, "type"); 10261 if (utype) { 10262 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10263 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10264 if (user) { 10265 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10266 user = user_unref(user); 10267 } 10268 } 10269 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10270 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10271 if (peer) { 10272 if (ast_test_flag(peer, IAX_DYNAMIC)) 10273 reg_source_db(peer); 10274 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10275 peer = peer_unref(peer); 10276 } 10277 } else if (strcasecmp(utype, "user")) { 10278 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10279 } 10280 } else 10281 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10282 } 10283 cat = ast_category_browse(cfg, cat); 10284 } 10285 ast_config_destroy(cfg); 10286 set_timing(); 10287 return 1; 10288 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9915 of file chan_iax2.c.
References ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09916 { 09917 strcpy(accountcode, ""); 09918 strcpy(language, ""); 09919 strcpy(mohinterpret, "default"); 09920 strcpy(mohsuggest, ""); 09921 amaflags = 0; 09922 delayreject = 0; 09923 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09924 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09925 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09926 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09927 delete_users(); 09928 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9900 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09901 { 09902 #ifdef HAVE_ZAPTEL 09903 int bs = trunkfreq * 8; 09904 if (timingfd > -1) { 09905 if ( 09906 #ifdef ZT_TIMERACK 09907 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09908 #endif 09909 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09910 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09911 } 09912 #endif 09913 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 760 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().
00761 { 00762 ast_mutex_lock(lock); 00763 ast_cond_signal(cond); 00764 ast_mutex_unlock(lock); 00765 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 7029 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().
07030 { 07031 struct sockaddr_in sin; 07032 int res; 07033 int updatehistory=1; 07034 int new = NEW_PREVENT; 07035 void *ptr; 07036 int dcallno = 0; 07037 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07038 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07039 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07040 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07041 struct ast_iax2_meta_trunk_hdr *mth; 07042 struct ast_iax2_meta_trunk_entry *mte; 07043 struct ast_iax2_meta_trunk_mini *mtm; 07044 struct iax_frame *fr; 07045 struct iax_frame *cur; 07046 struct ast_frame f = { 0, }; 07047 struct ast_channel *c; 07048 struct iax2_dpcache *dp; 07049 struct iax2_peer *peer; 07050 struct iax2_trunk_peer *tpeer; 07051 struct timeval rxtrunktime; 07052 struct iax_ies ies; 07053 struct iax_ie_data ied0, ied1; 07054 int format; 07055 int fd; 07056 int exists; 07057 int minivid = 0; 07058 unsigned int ts; 07059 char empty[32]=""; /* Safety measure */ 07060 struct iax_frame *duped_fr; 07061 char host_pref_buf[128]; 07062 char caller_pref_buf[128]; 07063 struct ast_codec_pref pref; 07064 char *using_prefs = "mine"; 07065 07066 /* allocate an iax_frame with 4096 bytes of data buffer */ 07067 fr = alloca(sizeof(*fr) + 4096); 07068 memset(fr, 0, sizeof(*fr)); 07069 fr->afdatalen = 4096; /* From alloca() above */ 07070 07071 /* Copy frequently used parameters to the stack */ 07072 res = thread->buf_len; 07073 fd = thread->iofd; 07074 memcpy(&sin, &thread->iosin, sizeof(sin)); 07075 07076 if (res < sizeof(*mh)) { 07077 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07078 return 1; 07079 } 07080 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07081 if (res < sizeof(*vh)) { 07082 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)); 07083 return 1; 07084 } 07085 07086 /* This is a video frame, get call number */ 07087 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07088 minivid = 1; 07089 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07090 unsigned char metatype; 07091 07092 if (res < sizeof(*meta)) { 07093 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)); 07094 return 1; 07095 } 07096 07097 /* This is a meta header */ 07098 switch(meta->metacmd) { 07099 case IAX_META_TRUNK: 07100 if (res < (sizeof(*meta) + sizeof(*mth))) { 07101 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07102 sizeof(*meta) + sizeof(*mth)); 07103 return 1; 07104 } 07105 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07106 ts = ntohl(mth->ts); 07107 metatype = meta->cmddata; 07108 res -= (sizeof(*meta) + sizeof(*mth)); 07109 ptr = mth->data; 07110 tpeer = find_tpeer(&sin, fd); 07111 if (!tpeer) { 07112 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)); 07113 return 1; 07114 } 07115 tpeer->trunkact = ast_tvnow(); 07116 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07117 tpeer->rxtrunktime = tpeer->trunkact; 07118 rxtrunktime = tpeer->rxtrunktime; 07119 ast_mutex_unlock(&tpeer->lock); 07120 while(res >= sizeof(*mte)) { 07121 /* Process channels */ 07122 unsigned short callno, trunked_ts, len; 07123 07124 if (metatype == IAX_META_TRUNK_MINI) { 07125 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07126 ptr += sizeof(*mtm); 07127 res -= sizeof(*mtm); 07128 len = ntohs(mtm->len); 07129 callno = ntohs(mtm->mini.callno); 07130 trunked_ts = ntohs(mtm->mini.ts); 07131 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07132 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07133 ptr += sizeof(*mte); 07134 res -= sizeof(*mte); 07135 len = ntohs(mte->len); 07136 callno = ntohs(mte->callno); 07137 trunked_ts = 0; 07138 } else { 07139 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07140 break; 07141 } 07142 /* Stop if we don't have enough data */ 07143 if (len > res) 07144 break; 07145 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07146 if (fr->callno) { 07147 /* If it's a valid call, deliver the contents. If not, we 07148 drop it, since we don't have a scallno to use for an INVAL */ 07149 /* Process as a mini frame */ 07150 memset(&f, 0, sizeof(f)); 07151 f.frametype = AST_FRAME_VOICE; 07152 if (iaxs[fr->callno]) { 07153 if (iaxs[fr->callno]->voiceformat > 0) { 07154 f.subclass = iaxs[fr->callno]->voiceformat; 07155 f.datalen = len; 07156 if (f.datalen >= 0) { 07157 if (f.datalen) 07158 f.data = ptr; 07159 if(trunked_ts) { 07160 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07161 } else 07162 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07163 /* Don't pass any packets until we're started */ 07164 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07165 /* Common things */ 07166 f.src = "IAX2"; 07167 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07168 f.samples = ast_codec_get_samples(&f); 07169 iax_frame_wrap(fr, &f); 07170 duped_fr = iaxfrdup2(fr); 07171 if (duped_fr) { 07172 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07173 } 07174 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07175 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07176 iaxs[fr->callno]->last = fr->ts; 07177 #if 1 07178 if (option_debug && iaxdebug) 07179 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07180 #endif 07181 } 07182 } 07183 } else { 07184 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07185 } 07186 } else { 07187 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 07188 iax2_vnak(fr->callno); 07189 } 07190 } 07191 ast_mutex_unlock(&iaxsl[fr->callno]); 07192 } 07193 ptr += len; 07194 res -= len; 07195 } 07196 07197 } 07198 return 1; 07199 } 07200 07201 #ifdef DEBUG_SUPPORT 07202 if (iaxdebug && (res >= sizeof(*fh))) 07203 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07204 #endif 07205 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07206 if (res < sizeof(*fh)) { 07207 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)); 07208 return 1; 07209 } 07210 07211 /* Get the destination call number */ 07212 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07213 /* Retrieve the type and subclass */ 07214 f.frametype = fh->type; 07215 if (f.frametype == AST_FRAME_VIDEO) { 07216 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07217 } else { 07218 f.subclass = uncompress_subclass(fh->csub); 07219 } 07220 07221 /* Deal with POKE/PONG without allocating a callno */ 07222 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07223 /* Reply back with a PONG, but don't care about the result. */ 07224 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno); 07225 return 1; 07226 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07227 /* Ignore */ 07228 return 1; 07229 } 07230 07231 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07232 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07233 (f.subclass == IAX_COMMAND_REGREL))) 07234 new = NEW_ALLOW; 07235 } else { 07236 /* Don't know anything about it yet */ 07237 f.frametype = AST_FRAME_NULL; 07238 f.subclass = 0; 07239 } 07240 07241 if (!fr->callno) { 07242 int check_dcallno = 0; 07243 07244 /* 07245 * We enforce accurate destination call numbers for all full frames except 07246 * LAGRQ and PING commands. This is because older versions of Asterisk 07247 * schedule these commands to get sent very quickly, and they will sometimes 07248 * be sent before they receive the first frame from the other side. When 07249 * that happens, it doesn't contain the destination call number. However, 07250 * not checking it for these frames is safe. 07251 * 07252 * Discussed in the following thread: 07253 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07254 */ 07255 07256 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07257 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07258 } 07259 07260 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07261 } 07262 07263 if (fr->callno > 0) 07264 ast_mutex_lock(&iaxsl[fr->callno]); 07265 07266 if (!fr->callno || !iaxs[fr->callno]) { 07267 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07268 frame, reply with an inval */ 07269 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07270 /* We can only raw hangup control frames */ 07271 if (((f.subclass != IAX_COMMAND_INVAL) && 07272 (f.subclass != IAX_COMMAND_TXCNT) && 07273 (f.subclass != IAX_COMMAND_TXACC) && 07274 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07275 (f.frametype != AST_FRAME_IAX)) 07276 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07277 fd); 07278 } 07279 if (fr->callno > 0) 07280 ast_mutex_unlock(&iaxsl[fr->callno]); 07281 return 1; 07282 } 07283 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07284 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07285 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07286 ast_mutex_unlock(&iaxsl[fr->callno]); 07287 return 1; 07288 } 07289 #ifdef DEBUG_SUPPORT 07290 else if (iaxdebug) 07291 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07292 #endif 07293 } 07294 07295 /* count this frame */ 07296 iaxs[fr->callno]->frames_received++; 07297 07298 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07299 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07300 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07301 unsigned short new_peercallno; 07302 07303 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07304 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07305 if (iaxs[fr->callno]->peercallno) { 07306 remove_by_peercallno(iaxs[fr->callno]); 07307 } 07308 iaxs[fr->callno]->peercallno = new_peercallno; 07309 store_by_peercallno(iaxs[fr->callno]); 07310 } 07311 } 07312 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07313 if (option_debug && iaxdebug) 07314 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07315 /* Check if it's out of order (and not an ACK or INVAL) */ 07316 fr->oseqno = fh->oseqno; 07317 fr->iseqno = fh->iseqno; 07318 fr->ts = ntohl(fh->ts); 07319 #ifdef IAXTESTS 07320 if (test_resync) { 07321 if (option_debug) 07322 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07323 fr->ts += test_resync; 07324 } 07325 #endif /* IAXTESTS */ 07326 #if 0 07327 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07328 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07329 (f.subclass == IAX_COMMAND_NEW || 07330 f.subclass == IAX_COMMAND_AUTHREQ || 07331 f.subclass == IAX_COMMAND_ACCEPT || 07332 f.subclass == IAX_COMMAND_REJECT)) ) ) 07333 #endif 07334 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07335 updatehistory = 0; 07336 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07337 (iaxs[fr->callno]->iseqno || 07338 ((f.subclass != IAX_COMMAND_TXCNT) && 07339 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07340 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07341 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07342 (f.subclass != IAX_COMMAND_TXACC)) || 07343 (f.frametype != AST_FRAME_IAX))) { 07344 if ( 07345 ((f.subclass != IAX_COMMAND_ACK) && 07346 (f.subclass != IAX_COMMAND_INVAL) && 07347 (f.subclass != IAX_COMMAND_TXCNT) && 07348 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07349 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07350 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07351 (f.subclass != IAX_COMMAND_TXACC) && 07352 (f.subclass != IAX_COMMAND_VNAK)) || 07353 (f.frametype != AST_FRAME_IAX)) { 07354 /* If it's not an ACK packet, it's out of order. */ 07355 if (option_debug) 07356 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07357 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07358 /* Check to see if we need to request retransmission, 07359 * and take sequence number wraparound into account */ 07360 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07361 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07362 if ((f.frametype != AST_FRAME_IAX) || 07363 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07364 if (option_debug) 07365 ast_log(LOG_DEBUG, "Acking anyway\n"); 07366 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07367 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07368 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07369 } 07370 } else { 07371 /* Send a VNAK requesting retransmission */ 07372 iax2_vnak(fr->callno); 07373 } 07374 ast_mutex_unlock(&iaxsl[fr->callno]); 07375 return 1; 07376 } 07377 } else { 07378 /* Increment unless it's an ACK or VNAK */ 07379 if (((f.subclass != IAX_COMMAND_ACK) && 07380 (f.subclass != IAX_COMMAND_INVAL) && 07381 (f.subclass != IAX_COMMAND_TXCNT) && 07382 (f.subclass != IAX_COMMAND_TXACC) && 07383 (f.subclass != IAX_COMMAND_VNAK)) || 07384 (f.frametype != AST_FRAME_IAX)) 07385 iaxs[fr->callno]->iseqno++; 07386 } 07387 /* A full frame */ 07388 if (res < sizeof(*fh)) { 07389 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07390 ast_mutex_unlock(&iaxsl[fr->callno]); 07391 return 1; 07392 } 07393 /* Ensure text frames are NULL-terminated */ 07394 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07395 if (res < thread->buf_size) 07396 thread->buf[res++] = '\0'; 07397 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07398 thread->buf[res - 1] = '\0'; 07399 } 07400 f.datalen = res - sizeof(*fh); 07401 07402 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07403 from the real peer, not the transfer peer */ 07404 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07405 ((f.subclass != IAX_COMMAND_INVAL) || 07406 (f.frametype != AST_FRAME_IAX))) { 07407 unsigned char x; 07408 int call_to_destroy; 07409 /* XXX This code is not very efficient. Surely there is a better way which still 07410 properly handles boundary conditions? XXX */ 07411 /* First we have to qualify that the ACKed value is within our window */ 07412 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07413 if (fr->iseqno == x) 07414 break; 07415 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07416 /* The acknowledgement is within our window. Time to acknowledge everything 07417 that it says to */ 07418 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07419 /* Ack the packet with the given timestamp */ 07420 if (option_debug && iaxdebug) 07421 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07422 call_to_destroy = 0; 07423 AST_LIST_LOCK(&iaxq.queue); 07424 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07425 /* If it's our call, and our timestamp, mark -1 retries */ 07426 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07427 cur->retries = -1; 07428 /* Destroy call if this is the end */ 07429 if (cur->final) 07430 call_to_destroy = fr->callno; 07431 } 07432 } 07433 AST_LIST_UNLOCK(&iaxq.queue); 07434 if (call_to_destroy) { 07435 if (iaxdebug && option_debug) 07436 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07437 ast_mutex_lock(&iaxsl[call_to_destroy]); 07438 iax2_destroy(call_to_destroy); 07439 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07440 } 07441 } 07442 /* Note how much we've received acknowledgement for */ 07443 if (iaxs[fr->callno]) 07444 iaxs[fr->callno]->rseqno = fr->iseqno; 07445 else { 07446 /* Stop processing now */ 07447 ast_mutex_unlock(&iaxsl[fr->callno]); 07448 return 1; 07449 } 07450 } else if (option_debug) 07451 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07452 } 07453 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07454 ((f.frametype != AST_FRAME_IAX) || 07455 ((f.subclass != IAX_COMMAND_TXACC) && 07456 (f.subclass != IAX_COMMAND_TXCNT)))) { 07457 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07458 ast_mutex_unlock(&iaxsl[fr->callno]); 07459 return 1; 07460 } 07461 07462 if (f.datalen) { 07463 if (f.frametype == AST_FRAME_IAX) { 07464 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07465 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07466 ast_mutex_unlock(&iaxsl[fr->callno]); 07467 return 1; 07468 } 07469 f.data = NULL; 07470 f.datalen = 0; 07471 } else 07472 f.data = thread->buf + sizeof(*fh); 07473 } else { 07474 if (f.frametype == AST_FRAME_IAX) 07475 f.data = NULL; 07476 else 07477 f.data = empty; 07478 memset(&ies, 0, sizeof(ies)); 07479 } 07480 07481 /* when we receive the first full frame for a new incoming channel, 07482 it is safe to start the PBX on the channel because we have now 07483 completed a 3-way handshake with the peer */ 07484 if ((f.frametype == AST_FRAME_VOICE) || 07485 (f.frametype == AST_FRAME_VIDEO) || 07486 (f.frametype == AST_FRAME_IAX)) { 07487 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07488 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07489 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07490 ast_mutex_unlock(&iaxsl[fr->callno]); 07491 return 1; 07492 } 07493 } 07494 } 07495 07496 if (f.frametype == AST_FRAME_VOICE) { 07497 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07498 iaxs[fr->callno]->voiceformat = f.subclass; 07499 if (option_debug) 07500 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07501 if (iaxs[fr->callno]->owner) { 07502 int orignative; 07503 retryowner: 07504 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07505 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07506 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07507 } 07508 if (iaxs[fr->callno]) { 07509 if (iaxs[fr->callno]->owner) { 07510 orignative = iaxs[fr->callno]->owner->nativeformats; 07511 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07512 if (iaxs[fr->callno]->owner->readformat) 07513 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07514 iaxs[fr->callno]->owner->nativeformats = orignative; 07515 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07516 } 07517 } else { 07518 if (option_debug) 07519 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07520 ast_mutex_unlock(&iaxsl[fr->callno]); 07521 return 1; 07522 } 07523 } 07524 } 07525 } 07526 if (f.frametype == AST_FRAME_VIDEO) { 07527 if (f.subclass != iaxs[fr->callno]->videoformat) { 07528 if (option_debug) 07529 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07530 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07531 } 07532 } 07533 if (f.frametype == AST_FRAME_IAX) { 07534 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07535 /* Handle the IAX pseudo frame itself */ 07536 if (option_debug && iaxdebug) 07537 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07538 07539 /* Update last ts unless the frame's timestamp originated with us. */ 07540 if (iaxs[fr->callno]->last < fr->ts && 07541 f.subclass != IAX_COMMAND_ACK && 07542 f.subclass != IAX_COMMAND_PONG && 07543 f.subclass != IAX_COMMAND_LAGRP) { 07544 iaxs[fr->callno]->last = fr->ts; 07545 if (option_debug && iaxdebug) 07546 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07547 } 07548 07549 switch(f.subclass) { 07550 case IAX_COMMAND_ACK: 07551 /* Do nothing */ 07552 break; 07553 case IAX_COMMAND_QUELCH: 07554 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07555 /* Generate Manager Hold event, if necessary*/ 07556 if (iaxs[fr->callno]->owner) { 07557 manager_event(EVENT_FLAG_CALL, "Hold", 07558 "Channel: %s\r\n" 07559 "Uniqueid: %s\r\n", 07560 iaxs[fr->callno]->owner->name, 07561 iaxs[fr->callno]->owner->uniqueid); 07562 } 07563 07564 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07565 if (ies.musiconhold) { 07566 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07567 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07568 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07569 S_OR(mohsuggest, NULL), 07570 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07571 if (!iaxs[fr->callno]) { 07572 ast_mutex_unlock(&iaxsl[fr->callno]); 07573 return 1; 07574 } 07575 } 07576 } 07577 } 07578 break; 07579 case IAX_COMMAND_UNQUELCH: 07580 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07581 /* Generate Manager Unhold event, if necessary*/ 07582 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07583 manager_event(EVENT_FLAG_CALL, "Unhold", 07584 "Channel: %s\r\n" 07585 "Uniqueid: %s\r\n", 07586 iaxs[fr->callno]->owner->name, 07587 iaxs[fr->callno]->owner->uniqueid); 07588 } 07589 07590 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07591 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07592 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07593 if (!iaxs[fr->callno]) { 07594 ast_mutex_unlock(&iaxsl[fr->callno]); 07595 return 1; 07596 } 07597 } 07598 } 07599 break; 07600 case IAX_COMMAND_TXACC: 07601 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07602 /* Ack the packet with the given timestamp */ 07603 AST_LIST_LOCK(&iaxq.queue); 07604 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07605 /* Cancel any outstanding txcnt's */ 07606 if ((fr->callno == cur->callno) && (cur->transfer)) 07607 cur->retries = -1; 07608 } 07609 AST_LIST_UNLOCK(&iaxq.queue); 07610 memset(&ied1, 0, sizeof(ied1)); 07611 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07612 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07613 iaxs[fr->callno]->transferring = TRANSFER_READY; 07614 } 07615 break; 07616 case IAX_COMMAND_NEW: 07617 /* Ignore if it's already up */ 07618 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07619 break; 07620 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07621 ast_mutex_unlock(&iaxsl[fr->callno]); 07622 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07623 ast_mutex_lock(&iaxsl[fr->callno]); 07624 if (!iaxs[fr->callno]) { 07625 ast_mutex_unlock(&iaxsl[fr->callno]); 07626 return 1; 07627 } 07628 } 07629 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07630 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07631 int new_callno; 07632 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07633 fr->callno = new_callno; 07634 } 07635 /* For security, always ack immediately */ 07636 if (delayreject) 07637 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07638 if (check_access(fr->callno, &sin, &ies)) { 07639 /* They're not allowed on */ 07640 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07641 if (authdebug) 07642 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); 07643 break; 07644 } 07645 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07646 const char *context, *exten, *cid_num; 07647 07648 context = ast_strdupa(iaxs[fr->callno]->context); 07649 exten = ast_strdupa(iaxs[fr->callno]->exten); 07650 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07651 07652 /* This might re-enter the IAX code and need the lock */ 07653 ast_mutex_unlock(&iaxsl[fr->callno]); 07654 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07655 ast_mutex_lock(&iaxsl[fr->callno]); 07656 07657 if (!iaxs[fr->callno]) { 07658 ast_mutex_unlock(&iaxsl[fr->callno]); 07659 return 1; 07660 } 07661 } else 07662 exists = 0; 07663 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07664 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07665 memset(&ied0, 0, sizeof(ied0)); 07666 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07667 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07668 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07669 if (!iaxs[fr->callno]) { 07670 ast_mutex_unlock(&iaxsl[fr->callno]); 07671 return 1; 07672 } 07673 if (authdebug) 07674 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); 07675 } else { 07676 /* Select an appropriate format */ 07677 07678 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07679 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07680 using_prefs = "reqonly"; 07681 } else { 07682 using_prefs = "disabled"; 07683 } 07684 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07685 memset(&pref, 0, sizeof(pref)); 07686 strcpy(caller_pref_buf, "disabled"); 07687 strcpy(host_pref_buf, "disabled"); 07688 } else { 07689 using_prefs = "mine"; 07690 /* If the information elements are in here... use them */ 07691 if (ies.codec_prefs) 07692 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07693 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07694 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07695 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07696 pref = iaxs[fr->callno]->rprefs; 07697 using_prefs = "caller"; 07698 } else { 07699 pref = iaxs[fr->callno]->prefs; 07700 } 07701 } else 07702 pref = iaxs[fr->callno]->prefs; 07703 07704 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07705 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07706 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07707 } 07708 if (!format) { 07709 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07710 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07711 if (!format) { 07712 memset(&ied0, 0, sizeof(ied0)); 07713 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07714 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07715 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07716 if (!iaxs[fr->callno]) { 07717 ast_mutex_unlock(&iaxsl[fr->callno]); 07718 return 1; 07719 } 07720 if (authdebug) { 07721 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07722 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); 07723 else 07724 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); 07725 } 07726 } else { 07727 /* Pick one... */ 07728 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07729 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07730 format = 0; 07731 } else { 07732 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07733 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07734 memset(&pref, 0, sizeof(pref)); 07735 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07736 strcpy(caller_pref_buf,"disabled"); 07737 strcpy(host_pref_buf,"disabled"); 07738 } else { 07739 using_prefs = "mine"; 07740 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07741 /* Do the opposite of what we tried above. */ 07742 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07743 pref = iaxs[fr->callno]->prefs; 07744 } else { 07745 pref = iaxs[fr->callno]->rprefs; 07746 using_prefs = "caller"; 07747 } 07748 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07749 07750 } else /* if no codec_prefs IE do it the old way */ 07751 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07752 } 07753 } 07754 07755 if (!format) { 07756 memset(&ied0, 0, sizeof(ied0)); 07757 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07758 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07759 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07760 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07761 if (!iaxs[fr->callno]) { 07762 ast_mutex_unlock(&iaxsl[fr->callno]); 07763 return 1; 07764 } 07765 if (authdebug) 07766 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); 07767 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07768 break; 07769 } 07770 } 07771 } 07772 if (format) { 07773 /* No authentication required, let them in */ 07774 memset(&ied1, 0, sizeof(ied1)); 07775 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07776 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07777 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07778 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07779 if (option_verbose > 2) 07780 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07781 "%srequested format = %s,\n" 07782 "%srequested prefs = %s,\n" 07783 "%sactual format = %s,\n" 07784 "%shost prefs = %s,\n" 07785 "%spriority = %s\n", 07786 ast_inet_ntoa(sin.sin_addr), 07787 VERBOSE_PREFIX_4, 07788 ast_getformatname(iaxs[fr->callno]->peerformat), 07789 VERBOSE_PREFIX_4, 07790 caller_pref_buf, 07791 VERBOSE_PREFIX_4, 07792 ast_getformatname(format), 07793 VERBOSE_PREFIX_4, 07794 host_pref_buf, 07795 VERBOSE_PREFIX_4, 07796 using_prefs); 07797 07798 iaxs[fr->callno]->chosenformat = format; 07799 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07800 } else { 07801 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07802 /* If this is a TBD call, we're ready but now what... */ 07803 if (option_verbose > 2) 07804 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07805 } 07806 } 07807 } 07808 break; 07809 } 07810 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07811 merge_encryption(iaxs[fr->callno],ies.encmethods); 07812 else 07813 iaxs[fr->callno]->encmethods = 0; 07814 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07815 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07816 if (!iaxs[fr->callno]) { 07817 ast_mutex_unlock(&iaxsl[fr->callno]); 07818 return 1; 07819 } 07820 break; 07821 case IAX_COMMAND_DPREQ: 07822 /* Request status in the dialplan */ 07823 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07824 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07825 if (iaxcompat) { 07826 /* Spawn a thread for the lookup */ 07827 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07828 } else { 07829 /* Just look it up */ 07830 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07831 } 07832 } 07833 break; 07834 case IAX_COMMAND_HANGUP: 07835 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07836 if (option_debug) 07837 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07838 /* Set hangup cause according to remote */ 07839 if (ies.causecode && iaxs[fr->callno]->owner) 07840 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07841 /* Send ack immediately, before we destroy */ 07842 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07843 iax2_destroy(fr->callno); 07844 break; 07845 case IAX_COMMAND_REJECT: 07846 /* Set hangup cause according to remote */ 07847 if (ies.causecode && iaxs[fr->callno]->owner) 07848 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07849 07850 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07851 if (iaxs[fr->callno]->owner && authdebug) 07852 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07853 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07854 ies.cause ? ies.cause : "<Unknown>"); 07855 if (option_debug) 07856 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07857 fr->callno); 07858 } 07859 /* Send ack immediately, before we destroy */ 07860 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07861 fr->ts, NULL, 0, fr->iseqno); 07862 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07863 iaxs[fr->callno]->error = EPERM; 07864 iax2_destroy(fr->callno); 07865 break; 07866 case IAX_COMMAND_TRANSFER: 07867 { 07868 struct ast_channel *bridged_chan; 07869 07870 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07871 /* Set BLINDTRANSFER channel variables */ 07872 07873 ast_mutex_unlock(&iaxsl[fr->callno]); 07874 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07875 ast_mutex_lock(&iaxsl[fr->callno]); 07876 if (!iaxs[fr->callno]) { 07877 ast_mutex_unlock(&iaxsl[fr->callno]); 07878 return 1; 07879 } 07880 07881 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07882 if (!strcmp(ies.called_number, ast_parking_ext())) { 07883 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07884 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07885 } else { 07886 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07887 } 07888 } else { 07889 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07890 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07891 ies.called_number, iaxs[fr->callno]->context); 07892 else 07893 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07894 ies.called_number, iaxs[fr->callno]->context); 07895 } 07896 } else 07897 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07898 07899 break; 07900 } 07901 case IAX_COMMAND_ACCEPT: 07902 /* Ignore if call is already up or needs authentication or is a TBD */ 07903 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07904 break; 07905 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07906 /* Send ack immediately, before we destroy */ 07907 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07908 iax2_destroy(fr->callno); 07909 break; 07910 } 07911 if (ies.format) { 07912 iaxs[fr->callno]->peerformat = ies.format; 07913 } else { 07914 if (iaxs[fr->callno]->owner) 07915 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07916 else 07917 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07918 } 07919 if (option_verbose > 2) 07920 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)); 07921 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07922 memset(&ied0, 0, sizeof(ied0)); 07923 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07924 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07925 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07926 if (!iaxs[fr->callno]) { 07927 ast_mutex_unlock(&iaxsl[fr->callno]); 07928 return 1; 07929 } 07930 if (authdebug) 07931 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); 07932 } else { 07933 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07934 if (iaxs[fr->callno]->owner) { 07935 /* Switch us to use a compatible format */ 07936 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07937 if (option_verbose > 2) 07938 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07939 retryowner2: 07940 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07941 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07942 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07943 } 07944 07945 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07946 /* Setup read/write formats properly. */ 07947 if (iaxs[fr->callno]->owner->writeformat) 07948 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07949 if (iaxs[fr->callno]->owner->readformat) 07950 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07951 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07952 } 07953 } 07954 } 07955 if (iaxs[fr->callno]) { 07956 ast_mutex_lock(&dpcache_lock); 07957 dp = iaxs[fr->callno]->dpentries; 07958 while(dp) { 07959 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07960 iax2_dprequest(dp, fr->callno); 07961 } 07962 dp = dp->peer; 07963 } 07964 ast_mutex_unlock(&dpcache_lock); 07965 } 07966 break; 07967 case IAX_COMMAND_POKE: 07968 /* Send back a pong packet with the original timestamp */ 07969 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07970 if (!iaxs[fr->callno]) { 07971 ast_mutex_unlock(&iaxsl[fr->callno]); 07972 return 1; 07973 } 07974 break; 07975 case IAX_COMMAND_PING: 07976 { 07977 struct iax_ie_data pingied; 07978 construct_rr(iaxs[fr->callno], &pingied); 07979 /* Send back a pong packet with the original timestamp */ 07980 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07981 } 07982 break; 07983 case IAX_COMMAND_PONG: 07984 /* Calculate ping time */ 07985 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07986 /* save RR info */ 07987 save_rr(fr, &ies); 07988 07989 if (iaxs[fr->callno]->peerpoke) { 07990 peer = iaxs[fr->callno]->peerpoke; 07991 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07992 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07993 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07994 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07995 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07996 } 07997 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07998 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07999 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 08000 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08001 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08002 } 08003 } 08004 peer->lastms = iaxs[fr->callno]->pingtime; 08005 if (peer->smoothing && (peer->lastms > -1)) 08006 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 08007 else if (peer->smoothing && peer->lastms < 0) 08008 peer->historicms = (0 + peer->historicms) / 2; 08009 else 08010 peer->historicms = iaxs[fr->callno]->pingtime; 08011 08012 /* Remove scheduled iax2_poke_noanswer */ 08013 if (peer->pokeexpire > -1) { 08014 if (!ast_sched_del(sched, peer->pokeexpire)) { 08015 peer_unref(peer); 08016 peer->pokeexpire = -1; 08017 } 08018 } 08019 /* Schedule the next cycle */ 08020 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 08021 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08022 else 08023 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 08024 if (peer->pokeexpire == -1) 08025 peer_unref(peer); 08026 /* and finally send the ack */ 08027 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08028 /* And wrap up the qualify call */ 08029 iax2_destroy(fr->callno); 08030 peer->callno = 0; 08031 if (option_debug) 08032 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08033 } 08034 break; 08035 case IAX_COMMAND_LAGRQ: 08036 case IAX_COMMAND_LAGRP: 08037 f.src = "LAGRQ"; 08038 f.mallocd = 0; 08039 f.offset = 0; 08040 f.samples = 0; 08041 iax_frame_wrap(fr, &f); 08042 if(f.subclass == IAX_COMMAND_LAGRQ) { 08043 /* Received a LAGRQ - echo back a LAGRP */ 08044 fr->af.subclass = IAX_COMMAND_LAGRP; 08045 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08046 } else { 08047 /* Received LAGRP in response to our LAGRQ */ 08048 unsigned int ts; 08049 /* This is a reply we've been given, actually measure the difference */ 08050 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08051 iaxs[fr->callno]->lag = ts - fr->ts; 08052 if (option_debug && iaxdebug) 08053 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08054 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08055 } 08056 break; 08057 case IAX_COMMAND_AUTHREQ: 08058 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08059 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>"); 08060 break; 08061 } 08062 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08063 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08064 .subclass = AST_CONTROL_HANGUP, 08065 }; 08066 ast_log(LOG_WARNING, 08067 "I don't know how to authenticate %s to %s\n", 08068 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08069 iax2_queue_frame(fr->callno, &hangup_fr); 08070 } 08071 if (!iaxs[fr->callno]) { 08072 ast_mutex_unlock(&iaxsl[fr->callno]); 08073 return 1; 08074 } 08075 break; 08076 case IAX_COMMAND_AUTHREP: 08077 /* For security, always ack immediately */ 08078 if (delayreject) 08079 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08080 /* Ignore once we've started */ 08081 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08082 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>"); 08083 break; 08084 } 08085 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08086 if (authdebug) 08087 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); 08088 memset(&ied0, 0, sizeof(ied0)); 08089 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08090 break; 08091 } 08092 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08093 /* This might re-enter the IAX code and need the lock */ 08094 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08095 } else 08096 exists = 0; 08097 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08098 if (authdebug) 08099 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); 08100 memset(&ied0, 0, sizeof(ied0)); 08101 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08102 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08103 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08104 if (!iaxs[fr->callno]) { 08105 ast_mutex_unlock(&iaxsl[fr->callno]); 08106 return 1; 08107 } 08108 } else { 08109 /* Select an appropriate format */ 08110 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08111 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08112 using_prefs = "reqonly"; 08113 } else { 08114 using_prefs = "disabled"; 08115 } 08116 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08117 memset(&pref, 0, sizeof(pref)); 08118 strcpy(caller_pref_buf, "disabled"); 08119 strcpy(host_pref_buf, "disabled"); 08120 } else { 08121 using_prefs = "mine"; 08122 if (ies.codec_prefs) 08123 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08124 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08125 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08126 pref = iaxs[fr->callno]->rprefs; 08127 using_prefs = "caller"; 08128 } else { 08129 pref = iaxs[fr->callno]->prefs; 08130 } 08131 } else /* if no codec_prefs IE do it the old way */ 08132 pref = iaxs[fr->callno]->prefs; 08133 08134 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08135 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08136 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08137 } 08138 if (!format) { 08139 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08140 if (option_debug) 08141 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); 08142 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08143 } 08144 if (!format) { 08145 if (authdebug) { 08146 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08147 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); 08148 else 08149 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); 08150 } 08151 memset(&ied0, 0, sizeof(ied0)); 08152 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08153 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08154 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08155 if (!iaxs[fr->callno]) { 08156 ast_mutex_unlock(&iaxsl[fr->callno]); 08157 return 1; 08158 } 08159 } else { 08160 /* Pick one... */ 08161 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08162 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08163 format = 0; 08164 } else { 08165 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08166 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08167 memset(&pref, 0, sizeof(pref)); 08168 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08169 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08170 strcpy(caller_pref_buf,"disabled"); 08171 strcpy(host_pref_buf,"disabled"); 08172 } else { 08173 using_prefs = "mine"; 08174 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08175 /* Do the opposite of what we tried above. */ 08176 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08177 pref = iaxs[fr->callno]->prefs; 08178 } else { 08179 pref = iaxs[fr->callno]->rprefs; 08180 using_prefs = "caller"; 08181 } 08182 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08183 } else /* if no codec_prefs IE do it the old way */ 08184 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08185 } 08186 } 08187 if (!format) { 08188 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08189 if (authdebug) { 08190 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08191 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); 08192 else 08193 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); 08194 } 08195 memset(&ied0, 0, sizeof(ied0)); 08196 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08197 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08198 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08199 if (!iaxs[fr->callno]) { 08200 ast_mutex_unlock(&iaxsl[fr->callno]); 08201 return 1; 08202 } 08203 } 08204 } 08205 } 08206 if (format) { 08207 /* Authentication received */ 08208 memset(&ied1, 0, sizeof(ied1)); 08209 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08210 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08211 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08212 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08213 if (option_verbose > 2) 08214 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08215 "%srequested format = %s,\n" 08216 "%srequested prefs = %s,\n" 08217 "%sactual format = %s,\n" 08218 "%shost prefs = %s,\n" 08219 "%spriority = %s\n", 08220 ast_inet_ntoa(sin.sin_addr), 08221 VERBOSE_PREFIX_4, 08222 ast_getformatname(iaxs[fr->callno]->peerformat), 08223 VERBOSE_PREFIX_4, 08224 caller_pref_buf, 08225 VERBOSE_PREFIX_4, 08226 ast_getformatname(format), 08227 VERBOSE_PREFIX_4, 08228 host_pref_buf, 08229 VERBOSE_PREFIX_4, 08230 using_prefs); 08231 08232 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08233 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08234 iax2_destroy(fr->callno); 08235 } else { 08236 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08237 /* If this is a TBD call, we're ready but now what... */ 08238 if (option_verbose > 2) 08239 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08240 } 08241 } 08242 } 08243 break; 08244 case IAX_COMMAND_DIAL: 08245 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08246 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08247 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08248 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08249 if (authdebug) 08250 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); 08251 memset(&ied0, 0, sizeof(ied0)); 08252 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08253 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08254 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08255 if (!iaxs[fr->callno]) { 08256 ast_mutex_unlock(&iaxsl[fr->callno]); 08257 return 1; 08258 } 08259 } else { 08260 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08261 if (option_verbose > 2) 08262 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08263 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08264 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08265 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08266 iax2_destroy(fr->callno); 08267 } 08268 } 08269 break; 08270 case IAX_COMMAND_INVAL: 08271 iaxs[fr->callno]->error = ENOTCONN; 08272 if (option_debug) 08273 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08274 iax2_destroy(fr->callno); 08275 if (option_debug) 08276 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08277 break; 08278 case IAX_COMMAND_VNAK: 08279 if (option_debug) 08280 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08281 /* Force retransmission */ 08282 vnak_retransmit(fr->callno, fr->iseqno); 08283 break; 08284 case IAX_COMMAND_REGREQ: 08285 case IAX_COMMAND_REGREL: 08286 /* For security, always ack immediately */ 08287 if (delayreject) 08288 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08289 if (register_verify(fr->callno, &sin, &ies)) { 08290 if (!iaxs[fr->callno]) { 08291 ast_mutex_unlock(&iaxsl[fr->callno]); 08292 return 1; 08293 } 08294 /* Send delayed failure */ 08295 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08296 break; 08297 } 08298 if (!iaxs[fr->callno]) { 08299 ast_mutex_unlock(&iaxsl[fr->callno]); 08300 return 1; 08301 } 08302 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08303 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 08304 08305 if (f.subclass == IAX_COMMAND_REGREL) 08306 memset(&sin, 0, sizeof(sin)); 08307 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08308 ast_log(LOG_WARNING, "Registry error\n"); 08309 if (!iaxs[fr->callno]) { 08310 ast_mutex_unlock(&iaxsl[fr->callno]); 08311 return 1; 08312 } 08313 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08314 ast_mutex_unlock(&iaxsl[fr->callno]); 08315 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08316 ast_mutex_lock(&iaxsl[fr->callno]); 08317 if (!iaxs[fr->callno]) { 08318 ast_mutex_unlock(&iaxsl[fr->callno]); 08319 return 1; 08320 } 08321 } 08322 break; 08323 } 08324 registry_authrequest(fr->callno); 08325 if (!iaxs[fr->callno]) { 08326 ast_mutex_unlock(&iaxsl[fr->callno]); 08327 return 1; 08328 } 08329 break; 08330 case IAX_COMMAND_REGACK: 08331 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08332 ast_log(LOG_WARNING, "Registration failure\n"); 08333 /* Send ack immediately, before we destroy */ 08334 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08335 iax2_destroy(fr->callno); 08336 break; 08337 case IAX_COMMAND_REGREJ: 08338 if (iaxs[fr->callno]->reg) { 08339 if (authdebug) { 08340 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)); 08341 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>"); 08342 } 08343 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08344 } 08345 /* Send ack immediately, before we destroy */ 08346 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08347 iax2_destroy(fr->callno); 08348 break; 08349 case IAX_COMMAND_REGAUTH: 08350 /* Authentication request */ 08351 if (registry_rerequest(&ies, fr->callno, &sin)) { 08352 memset(&ied0, 0, sizeof(ied0)); 08353 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08354 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08355 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08356 if (!iaxs[fr->callno]) { 08357 ast_mutex_unlock(&iaxsl[fr->callno]); 08358 return 1; 08359 } 08360 } 08361 break; 08362 case IAX_COMMAND_TXREJ: 08363 iaxs[fr->callno]->transferring = 0; 08364 if (option_verbose > 2) 08365 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08366 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08367 if (iaxs[fr->callno]->bridgecallno) { 08368 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08369 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08370 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08371 } 08372 } 08373 break; 08374 case IAX_COMMAND_TXREADY: 08375 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08376 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08377 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08378 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08379 else 08380 iaxs[fr->callno]->transferring = TRANSFER_READY; 08381 if (option_verbose > 2) 08382 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08383 if (iaxs[fr->callno]->bridgecallno) { 08384 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08385 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08386 /* They're both ready, now release them. */ 08387 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08388 if (option_verbose > 2) 08389 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08390 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08391 08392 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08393 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 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_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08400 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08401 } else { 08402 if (option_verbose > 2) 08403 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08404 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08405 08406 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08407 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08408 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08409 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08410 08411 /* Stop doing lag & ping requests */ 08412 stop_stuff(fr->callno); 08413 stop_stuff(iaxs[fr->callno]->bridgecallno); 08414 08415 memset(&ied0, 0, sizeof(ied0)); 08416 memset(&ied1, 0, sizeof(ied1)); 08417 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08418 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08419 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08420 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08421 } 08422 08423 } 08424 } 08425 } 08426 break; 08427 case IAX_COMMAND_TXREQ: 08428 try_transfer(iaxs[fr->callno], &ies); 08429 break; 08430 case IAX_COMMAND_TXCNT: 08431 if (iaxs[fr->callno]->transferring) 08432 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08433 break; 08434 case IAX_COMMAND_TXREL: 08435 /* Send ack immediately, rather than waiting until we've changed addresses */ 08436 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08437 complete_transfer(fr->callno, &ies); 08438 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08439 break; 08440 case IAX_COMMAND_TXMEDIA: 08441 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08442 AST_LIST_LOCK(&iaxq.queue); 08443 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08444 /* Cancel any outstanding frames and start anew */ 08445 if ((fr->callno == cur->callno) && (cur->transfer)) { 08446 cur->retries = -1; 08447 } 08448 } 08449 AST_LIST_UNLOCK(&iaxq.queue); 08450 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08451 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08452 } 08453 break; 08454 case IAX_COMMAND_DPREP: 08455 complete_dpreply(iaxs[fr->callno], &ies); 08456 break; 08457 case IAX_COMMAND_UNSUPPORT: 08458 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08459 break; 08460 case IAX_COMMAND_FWDOWNL: 08461 /* Firmware download */ 08462 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08463 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08464 break; 08465 } 08466 memset(&ied0, 0, sizeof(ied0)); 08467 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08468 if (res < 0) 08469 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08470 else if (res > 0) 08471 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08472 else 08473 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08474 if (!iaxs[fr->callno]) { 08475 ast_mutex_unlock(&iaxsl[fr->callno]); 08476 return 1; 08477 } 08478 break; 08479 default: 08480 if (option_debug) 08481 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08482 memset(&ied0, 0, sizeof(ied0)); 08483 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08484 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08485 } 08486 /* Don't actually pass these frames along */ 08487 if ((f.subclass != IAX_COMMAND_ACK) && 08488 (f.subclass != IAX_COMMAND_TXCNT) && 08489 (f.subclass != IAX_COMMAND_TXACC) && 08490 (f.subclass != IAX_COMMAND_INVAL) && 08491 (f.subclass != IAX_COMMAND_VNAK)) { 08492 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08493 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08494 } 08495 ast_mutex_unlock(&iaxsl[fr->callno]); 08496 return 1; 08497 } 08498 /* Unless this is an ACK or INVAL frame, ack it */ 08499 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08500 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08501 } else if (minivid) { 08502 f.frametype = AST_FRAME_VIDEO; 08503 if (iaxs[fr->callno]->videoformat > 0) 08504 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08505 else { 08506 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08507 iax2_vnak(fr->callno); 08508 ast_mutex_unlock(&iaxsl[fr->callno]); 08509 return 1; 08510 } 08511 f.datalen = res - sizeof(*vh); 08512 if (f.datalen) 08513 f.data = thread->buf + sizeof(*vh); 08514 else 08515 f.data = NULL; 08516 #ifdef IAXTESTS 08517 if (test_resync) { 08518 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08519 } else 08520 #endif /* IAXTESTS */ 08521 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08522 } else { 08523 /* A mini frame */ 08524 f.frametype = AST_FRAME_VOICE; 08525 if (iaxs[fr->callno]->voiceformat > 0) 08526 f.subclass = iaxs[fr->callno]->voiceformat; 08527 else { 08528 if (option_debug) 08529 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08530 iax2_vnak(fr->callno); 08531 ast_mutex_unlock(&iaxsl[fr->callno]); 08532 return 1; 08533 } 08534 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08535 if (f.datalen < 0) { 08536 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08537 ast_mutex_unlock(&iaxsl[fr->callno]); 08538 return 1; 08539 } 08540 if (f.datalen) 08541 f.data = thread->buf + sizeof(*mh); 08542 else 08543 f.data = NULL; 08544 #ifdef IAXTESTS 08545 if (test_resync) { 08546 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08547 } else 08548 #endif /* IAXTESTS */ 08549 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08550 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08551 } 08552 /* Don't pass any packets until we're started */ 08553 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08554 ast_mutex_unlock(&iaxsl[fr->callno]); 08555 return 1; 08556 } 08557 /* Common things */ 08558 f.src = "IAX2"; 08559 f.mallocd = 0; 08560 f.offset = 0; 08561 f.len = 0; 08562 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08563 f.samples = ast_codec_get_samples(&f); 08564 /* We need to byteswap incoming slinear samples from network byte order */ 08565 if (f.subclass == AST_FORMAT_SLINEAR) 08566 ast_frame_byteswap_be(&f); 08567 } else 08568 f.samples = 0; 08569 iax_frame_wrap(fr, &f); 08570 08571 /* If this is our most recent packet, use it as our basis for timestamping */ 08572 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08573 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08574 fr->outoforder = 0; 08575 } else { 08576 if (option_debug && iaxdebug && iaxs[fr->callno]) 08577 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); 08578 fr->outoforder = -1; 08579 } 08580 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08581 duped_fr = iaxfrdup2(fr); 08582 if (duped_fr) { 08583 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08584 } 08585 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08586 iaxs[fr->callno]->last = fr->ts; 08587 #if 1 08588 if (option_debug && iaxdebug) 08589 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08590 #endif 08591 } 08592 08593 /* Always run again */ 08594 ast_mutex_unlock(&iaxsl[fr->callno]); 08595 return 1; 08596 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6951 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().
06952 { 06953 struct iax2_thread *thread; 06954 socklen_t len; 06955 time_t t; 06956 static time_t last_errtime = 0; 06957 struct ast_iax2_full_hdr *fh; 06958 06959 if (!(thread = find_idle_thread())) { 06960 time(&t); 06961 if (t != last_errtime && option_debug) 06962 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06963 last_errtime = t; 06964 usleep(1); 06965 return 1; 06966 } 06967 06968 len = sizeof(thread->iosin); 06969 thread->iofd = fd; 06970 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06971 thread->buf_size = sizeof(thread->readbuf); 06972 thread->buf = thread->readbuf; 06973 if (thread->buf_len < 0) { 06974 if (errno != ECONNREFUSED && errno != EAGAIN) 06975 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06976 handle_error(); 06977 thread->iostate = IAX_IOSTATE_IDLE; 06978 signal_condition(&thread->lock, &thread->cond); 06979 return 1; 06980 } 06981 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06982 thread->iostate = IAX_IOSTATE_IDLE; 06983 signal_condition(&thread->lock, &thread->cond); 06984 return 1; 06985 } 06986 06987 /* Determine if this frame is a full frame; if so, and any thread is currently 06988 processing a full frame for the same callno from this peer, then drop this 06989 frame (and the peer will retransmit it) */ 06990 fh = (struct ast_iax2_full_hdr *) thread->buf; 06991 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06992 struct iax2_thread *cur = NULL; 06993 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06994 06995 AST_LIST_LOCK(&active_list); 06996 AST_LIST_TRAVERSE(&active_list, cur, list) { 06997 if ((cur->ffinfo.callno == callno) && 06998 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06999 break; 07000 } 07001 if (cur) { 07002 /* we found another thread processing a full frame for this call, 07003 so queue it up for processing later. */ 07004 defer_full_frame(thread, cur); 07005 AST_LIST_UNLOCK(&active_list); 07006 thread->iostate = IAX_IOSTATE_IDLE; 07007 signal_condition(&thread->lock, &thread->cond); 07008 return 1; 07009 } else { 07010 /* this thread is going to process this frame, so mark it */ 07011 thread->ffinfo.callno = callno; 07012 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 07013 thread->ffinfo.type = fh->type; 07014 thread->ffinfo.csub = fh->csub; 07015 } 07016 AST_LIST_UNLOCK(&active_list); 07017 } 07018 07019 /* Mark as ready and send on its way */ 07020 thread->iostate = IAX_IOSTATE_READY; 07021 #ifdef DEBUG_SCHED_MULTITHREAD 07022 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 07023 #endif 07024 signal_condition(&thread->lock, &thread->cond); 07025 07026 return 1; 07027 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6738 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().
06739 { 06740 pthread_t newthread; 06741 struct dpreq_data *dpr; 06742 pthread_attr_t attr; 06743 06744 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06745 return; 06746 06747 pthread_attr_init(&attr); 06748 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06749 06750 dpr->callno = callno; 06751 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06752 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06753 if (callerid) 06754 dpr->callerid = ast_strdup(callerid); 06755 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06756 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06757 } 06758 06759 pthread_attr_destroy(&attr); 06760 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9198 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().
09199 { 09200 pthread_attr_t attr; 09201 int threadcount = 0; 09202 int x; 09203 for (x = 0; x < iaxthreadcount; x++) { 09204 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09205 if (thread) { 09206 thread->type = IAX_TYPE_POOL; 09207 thread->threadnum = ++threadcount; 09208 ast_mutex_init(&thread->lock); 09209 ast_cond_init(&thread->cond, NULL); 09210 pthread_attr_init(&attr); 09211 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09212 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09213 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09214 free(thread); 09215 thread = NULL; 09216 } 09217 AST_LIST_LOCK(&idle_list); 09218 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09219 AST_LIST_UNLOCK(&idle_list); 09220 } 09221 } 09222 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09223 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09224 if (option_verbose > 1) 09225 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 09226 return 0; 09227 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6420 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06421 { 06422 iax2_destroy_helper(iaxs[callno]); 06423 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1246 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().
01247 { 01248 if (!pvt->peercallno) { 01249 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01250 return; 01251 } 01252 01253 ao2_link(iax_peercallno_pvts, pvt); 01254 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6607 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().
06608 { 06609 char buf[1024]; 06610 int res; 06611 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06612 int processed = 0; 06613 int totalcalls = 0; 06614 #ifdef ZT_TIMERACK 06615 int x = 1; 06616 #endif 06617 struct timeval now; 06618 if (iaxtrunkdebug) 06619 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06620 gettimeofday(&now, NULL); 06621 if (events & AST_IO_PRI) { 06622 #ifdef ZT_TIMERACK 06623 /* Great, this is a timing interface, just call the ioctl */ 06624 if (ioctl(fd, ZT_TIMERACK, &x)) { 06625 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06626 usleep(1); 06627 return -1; 06628 } 06629 #endif 06630 } else { 06631 /* Read and ignore from the pseudo channel for timing */ 06632 res = read(fd, buf, sizeof(buf)); 06633 if (res < 1) { 06634 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06635 return 1; 06636 } 06637 } 06638 /* For each peer that supports trunking... */ 06639 ast_mutex_lock(&tpeerlock); 06640 tpeer = tpeers; 06641 while(tpeer) { 06642 processed++; 06643 res = 0; 06644 ast_mutex_lock(&tpeer->lock); 06645 /* We can drop a single tpeer per pass. That makes all this logic 06646 substantially easier */ 06647 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06648 /* Take it out of the list, but don't free it yet, because it 06649 could be in use */ 06650 if (prev) 06651 prev->next = tpeer->next; 06652 else 06653 tpeers = tpeer->next; 06654 drop = tpeer; 06655 } else { 06656 res = send_trunk(tpeer, &now); 06657 if (iaxtrunkdebug) 06658 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); 06659 } 06660 totalcalls += res; 06661 res = 0; 06662 ast_mutex_unlock(&tpeer->lock); 06663 prev = tpeer; 06664 tpeer = tpeer->next; 06665 } 06666 ast_mutex_unlock(&tpeerlock); 06667 if (drop) { 06668 ast_mutex_lock(&drop->lock); 06669 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06670 because by the time they could get tpeerlock, we've already grabbed it */ 06671 if (option_debug) 06672 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06673 if (drop->trunkdata) { 06674 free(drop->trunkdata); 06675 drop->trunkdata = NULL; 06676 } 06677 ast_mutex_unlock(&drop->lock); 06678 ast_mutex_destroy(&drop->lock); 06679 free(drop); 06680 06681 } 06682 if (iaxtrunkdebug) 06683 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06684 iaxtrunkdebug =0; 06685 return 1; 06686 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2072 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().
02073 { 02074 int res; 02075 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02076 sizeof(*sin)); 02077 if (res < 0) { 02078 if (option_debug) 02079 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02080 handle_error(); 02081 } else 02082 res = 0; 02083 return res; 02084 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1760 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().
01761 { 01762 struct stat stbuf; 01763 struct iax_firmware *cur; 01764 int ifd; 01765 int fd; 01766 int res; 01767 01768 struct ast_iax2_firmware_header *fwh, fwh2; 01769 struct MD5Context md5; 01770 unsigned char sum[16]; 01771 unsigned char buf[1024]; 01772 int len, chunk; 01773 char *s2; 01774 char *last; 01775 s2 = alloca(strlen(s) + 100); 01776 if (!s2) { 01777 ast_log(LOG_WARNING, "Alloca failed!\n"); 01778 return -1; 01779 } 01780 last = strrchr(s, '/'); 01781 if (last) 01782 last++; 01783 else 01784 last = s; 01785 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01786 res = stat(s, &stbuf); 01787 if (res < 0) { 01788 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01789 return -1; 01790 } 01791 /* Make sure it's not a directory */ 01792 if (S_ISDIR(stbuf.st_mode)) 01793 return -1; 01794 ifd = open(s, O_RDONLY); 01795 if (ifd < 0) { 01796 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01797 return -1; 01798 } 01799 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01800 if (fd < 0) { 01801 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01802 close(ifd); 01803 return -1; 01804 } 01805 /* Unlink our newly created file */ 01806 unlink(s2); 01807 01808 /* Now copy the firmware into it */ 01809 len = stbuf.st_size; 01810 while(len) { 01811 chunk = len; 01812 if (chunk > sizeof(buf)) 01813 chunk = sizeof(buf); 01814 res = read(ifd, buf, chunk); 01815 if (res != chunk) { 01816 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01817 close(ifd); 01818 close(fd); 01819 return -1; 01820 } 01821 res = write(fd, buf, chunk); 01822 if (res != chunk) { 01823 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01824 close(ifd); 01825 close(fd); 01826 return -1; 01827 } 01828 len -= chunk; 01829 } 01830 close(ifd); 01831 /* Return to the beginning */ 01832 lseek(fd, 0, SEEK_SET); 01833 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01834 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01835 close(fd); 01836 return -1; 01837 } 01838 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01839 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01840 close(fd); 01841 return -1; 01842 } 01843 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01844 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01845 close(fd); 01846 return -1; 01847 } 01848 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01849 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01850 close(fd); 01851 return -1; 01852 } 01853 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01854 if (fwh == (void *) -1) { 01855 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01856 close(fd); 01857 return -1; 01858 } 01859 MD5Init(&md5); 01860 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01861 MD5Final(sum, &md5); 01862 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01863 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01864 munmap((void*)fwh, stbuf.st_size); 01865 close(fd); 01866 return -1; 01867 } 01868 cur = waresl.wares; 01869 while(cur) { 01870 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01871 /* Found a candidate */ 01872 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01873 /* The version we have on loaded is older, load this one instead */ 01874 break; 01875 /* This version is no newer than what we have. Don't worry about it. 01876 We'll consider it a proper load anyhow though */ 01877 munmap((void*)fwh, stbuf.st_size); 01878 close(fd); 01879 return 0; 01880 } 01881 cur = cur->next; 01882 } 01883 if (!cur) { 01884 /* Allocate a new one and link it */ 01885 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01886 cur->fd = -1; 01887 cur->next = waresl.wares; 01888 waresl.wares = cur; 01889 } 01890 } 01891 if (cur) { 01892 if (cur->fwh) { 01893 munmap((void*)cur->fwh, cur->mmaplen); 01894 } 01895 if (cur->fd > -1) 01896 close(cur->fd); 01897 cur->fwh = fwh; 01898 cur->fd = fd; 01899 cur->mmaplen = stbuf.st_size; 01900 cur->dead = 0; 01901 } 01902 return 0; 01903 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5813 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().
05814 { 05815 int newcall = 0; 05816 char newip[256]; 05817 struct iax_ie_data ied; 05818 struct sockaddr_in new; 05819 05820 05821 memset(&ied, 0, sizeof(ied)); 05822 if (ies->apparent_addr) 05823 bcopy(ies->apparent_addr, &new, sizeof(new)); 05824 if (ies->callno) 05825 newcall = ies->callno; 05826 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05827 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05828 return -1; 05829 } 05830 pvt->transfercallno = newcall; 05831 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05832 inet_aton(newip, &pvt->transfer.sin_addr); 05833 pvt->transfer.sin_family = AF_INET; 05834 pvt->transferring = TRANSFER_BEGIN; 05835 pvt->transferid = ies->transferid; 05836 if (ies->transferid) 05837 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05838 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05839 return 0; 05840 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1091 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01092 { 01093 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01094 if (csub & IAX_FLAG_SC_LOG) { 01095 /* special case for 'compressed' -1 */ 01096 if (csub == 0xff) 01097 return -1; 01098 else 01099 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01100 } 01101 else 01102 return csub; 01103 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6085 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().
06086 { 06087 if (peer->expire > -1) { 06088 if (!ast_sched_del(sched, peer->expire)) { 06089 peer->expire = -1; 06090 peer_unref(peer); 06091 } 06092 } 06093 06094 if (peer->pokeexpire > -1) { 06095 if (!ast_sched_del(sched, peer->pokeexpire)) { 06096 peer->pokeexpire = -1; 06097 peer_unref(peer); 06098 } 06099 } 06100 06101 ao2_unlink(peers, peer); 06102 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11123 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11124 { 11125 ast_custom_function_unregister(&iaxpeer_function); 11126 return __unload_module(); 11127 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3491 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03492 { 03493 ast_mutex_unlock(&iaxsl[callno1]); 03494 ast_mutex_unlock(&iaxsl[callno0]); 03495 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2517 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().
02518 { 02519 int x; 02520 02521 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02522 x = fr->ts - iaxs[fr->callno]->last; 02523 if (x < -50000) { 02524 /* Sudden big jump backwards in timestamp: 02525 What likely happened here is that miniframe timestamp has circled but we haven't 02526 gotten the update from the main packet. We'll just pretend that we did, and 02527 update the timestamp appropriately. */ 02528 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02529 if (option_debug && iaxdebug) 02530 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02531 } 02532 if (x > 50000) { 02533 /* Sudden apparent big jump forwards in timestamp: 02534 What's likely happened is this is an old miniframe belonging to the previous 02535 top-16-bit timestamp that has turned up out of order. 02536 Adjust the timestamp appropriately. */ 02537 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02538 if (option_debug && iaxdebug) 02539 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02540 } 02541 } 02542 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2546 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().
02547 { 02548 int when; 02549 02550 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02551 02552 when = jb_next(pvt->jb) - when; 02553 02554 AST_SCHED_DEL(sched, pvt->jbid); 02555 02556 if(when <= 0) { 02557 /* XXX should really just empty until when > 0.. */ 02558 when = 1; 02559 } 02560 02561 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02562 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1459 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().
01460 { 01461 int max = 1; 01462 int x; 01463 /* XXX Prolly don't need locks here XXX */ 01464 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01465 if (iaxs[x]) 01466 max = x + 1; 01467 } 01468 maxnontrunkcall = max; 01469 if (option_debug && iaxdebug) 01470 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01471 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1266 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().
01267 { 01268 int max = TRUNK_CALL_START; 01269 int x; 01270 01271 /* XXX Prolly don't need locks here XXX */ 01272 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01273 if (iaxs[x]) { 01274 max = x + 1; 01275 } 01276 } 01277 01278 maxtrunkcall = max; 01279 if (option_debug && iaxdebug) 01280 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01281 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2143 of file chan_iax2.c.
References iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.
Referenced by __attempt_transmit().
02144 { 02145 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02146 struct ast_iax2_full_hdr *fh = f->data; 02147 struct ast_frame af; 02148 02149 /* if frame is encrypted. decrypt before updating it. */ 02150 if (f->encmethods) { 02151 decode_frame(&f->mydcx, fh, &af, &f->datalen); 02152 } 02153 /* Mark this as a retransmission */ 02154 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02155 /* Update iseqno */ 02156 f->iseqno = iaxs[f->callno]->iseqno; 02157 fh->iseqno = f->iseqno; 02158 02159 /* Now re-encrypt the frame */ 02160 if (f->encmethods) { 02161 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 02162 } 02163 return 0; 02164 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6196 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().
06197 { 06198 /* Called from IAX thread only, with proper iaxsl lock */ 06199 struct iax_ie_data ied; 06200 struct iax2_peer *p; 06201 int msgcount; 06202 char data[80]; 06203 int version; 06204 const char *peer_name; 06205 int res = -1; 06206 06207 memset(&ied, 0, sizeof(ied)); 06208 06209 peer_name = ast_strdupa(iaxs[callno]->peer); 06210 06211 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06212 ast_mutex_unlock(&iaxsl[callno]); 06213 if (!(p = find_peer(peer_name, 1))) { 06214 ast_mutex_lock(&iaxsl[callno]); 06215 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06216 return -1; 06217 } 06218 ast_mutex_lock(&iaxsl[callno]); 06219 if (!iaxs[callno]) 06220 goto return_unref; 06221 06222 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06223 if (sin->sin_addr.s_addr) { 06224 time_t nowtime; 06225 time(&nowtime); 06226 realtime_update_peer(peer_name, sin, nowtime); 06227 } else { 06228 realtime_update_peer(peer_name, sin, 0); 06229 } 06230 } 06231 if (inaddrcmp(&p->addr, sin)) { 06232 if (iax2_regfunk) 06233 iax2_regfunk(p->name, 1); 06234 /* Stash the IP address from which they registered */ 06235 memcpy(&p->addr, sin, sizeof(p->addr)); 06236 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06237 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06238 ast_db_put("IAX/Registry", p->name, data); 06239 if (option_verbose > 2) 06240 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06241 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06242 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06243 register_peer_exten(p, 1); 06244 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06245 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06246 if (option_verbose > 2) 06247 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06248 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06249 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06250 register_peer_exten(p, 0); 06251 ast_db_del("IAX/Registry", p->name); 06252 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06253 } 06254 /* Update the host */ 06255 /* Verify that the host is really there */ 06256 iax2_poke_peer(p, callno); 06257 } 06258 06259 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06260 if (!iaxs[callno]) { 06261 res = 0; 06262 goto return_unref; 06263 } 06264 06265 /* Store socket fd */ 06266 p->sockfd = fd; 06267 /* Setup the expiry */ 06268 if (p->expire > -1) { 06269 if (!ast_sched_del(sched, p->expire)) { 06270 p->expire = -1; 06271 peer_unref(p); 06272 } 06273 } 06274 /* treat an unspecified refresh interval as the minimum */ 06275 if (!refresh) 06276 refresh = min_reg_expire; 06277 if (refresh > max_reg_expire) { 06278 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06279 p->name, max_reg_expire, refresh); 06280 p->expiry = max_reg_expire; 06281 } else if (refresh < min_reg_expire) { 06282 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06283 p->name, min_reg_expire, refresh); 06284 p->expiry = min_reg_expire; 06285 } else { 06286 p->expiry = refresh; 06287 } 06288 if (p->expiry && sin->sin_addr.s_addr) { 06289 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06290 if (p->expire == -1) 06291 peer_unref(p); 06292 } 06293 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06294 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06295 if (sin->sin_addr.s_addr) { 06296 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06297 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06298 if (!ast_strlen_zero(p->mailbox)) { 06299 int new, old; 06300 ast_app_inboxcount(p->mailbox, &new, &old); 06301 if (new > 255) 06302 new = 255; 06303 if (old > 255) 06304 old = 255; 06305 msgcount = (old << 8) | new; 06306 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06307 } 06308 if (ast_test_flag(p, IAX_HASCALLERID)) { 06309 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06310 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06311 } 06312 } 06313 version = iax_check_version(devtype); 06314 if (version) 06315 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06316 06317 res = 0; 06318 06319 return_unref: 06320 peer_unref(p); 06321 06322 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06323 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1138 of file chan_iax2.c.
Referenced by load_module().
01139 { 01140 struct iax2_user *user = obj, *user2 = arg; 01141 01142 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01143 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9838 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09839 { 09840 struct iax2_user *user = obj; 09841 09842 ast_set_flag(user, IAX_DELME); 09843 09844 return 0; 09845 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9602 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().
09603 { 09604 struct iax2_user *user = obj; 09605 09606 ast_free_ha(user->ha); 09607 free_context(user->contexts); 09608 if(user->vars) { 09609 ast_variables_destroy(user->vars); 09610 user->vars = NULL; 09611 } 09612 ast_string_field_free_memory(user); 09613 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1128 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01129 { 01130 const struct iax2_user *user = obj; 01131 01132 return ast_str_hash(user->name); 01133 }
Definition at line 1177 of file chan_iax2.c.
References ao2_ref().
01178 { 01179 ao2_ref(user, +1); 01180 return user; 01181 }
Definition at line 1183 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().
01184 { 01185 ao2_ref(user, -1); 01186 return NULL; 01187 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6521 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().
06522 { 06523 struct iax_frame *f; 06524 06525 AST_LIST_LOCK(&iaxq.queue); 06526 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06527 /* Send a copy immediately */ 06528 if ((f->callno == callno) && iaxs[f->callno] && 06529 ((unsigned char ) (f->oseqno - last) < 128) && 06530 (f->retries >= 0)) { 06531 send_packet(f); 06532 } 06533 } 06534 AST_LIST_UNLOCK(&iaxq.queue); 06535 }
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 10919 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 10924 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 10934 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 10929 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 10914 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 10888 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 10880 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 10872 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 10830 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 873 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 10896 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 828 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 815 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 816 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 817 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 835 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 10892 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 10884 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 10876 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 8847 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peers [static] |
Definition at line 653 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 10826 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 10818 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 10846 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 10864 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 10850 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 10822 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 10858 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10834 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 10868 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 10814 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 10854 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 10841 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 656 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().