#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
Create new call, interface with the PBX core. | |
static | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (sched_lock) | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static void | poke_all_peers (void) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ast_cli_entry | cli_iax2 [] |
static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(* | iax2_regfunk )(const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
struct ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static struct timeval | lastused [ARRAY_LEN(iaxs)] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ao2_container * | peers |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static char | show_cache_usage [] |
static char | show_channels_usage [] |
static char | show_firmware_usage [] |
static char | show_netstats_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_prov_usage [] |
static char | show_reg_usage [] |
static char | show_stats_usage [] |
static char | show_threads_usage [] |
static char | show_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static unsigned int | tos = 0 |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 666 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache().
#define CACHE_FLAG_EXISTS (1 << 0) |
Extension exists
Definition at line 662 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache().
#define CACHE_FLAG_MATCHMORE (1 << 7) |
Matchmore
Definition at line 676 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache().
#define CACHE_FLAG_NONEXISTENT (1 << 1) |
Extension is nonexistent
Definition at line 664 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CACHE_FLAG_PENDING (1 << 3) |
Waiting to hear back response
Definition at line 668 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TIMEOUT (1 << 4) |
Timed out
Definition at line 670 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 672 of file chan_iax2.c.
Referenced by iax2_dprequest(), iax2_show_cache(), and socket_process().
#define CACHE_FLAG_UNKNOWN (1 << 6) |
Timeout
Definition at line 674 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 126 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 114 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 134 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 200 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 199 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 198 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 128 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 442 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15d %-15d\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 139 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 181 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 189 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 194 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 183 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
Definition at line 700 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 703 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 117 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 439 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 1 |
This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.
Definition at line 648 of file chan_iax2.c.
Referenced by load_module(), and set_config().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 445 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 443 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 131 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 440 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define NEW_ALLOW 1 |
#define NEW_FORCE 2 |
Definition at line 1431 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request().
#define NEW_PREVENT 0 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 125 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().
#define SCHED_MULTITHREADED |
Definition at line 110 of file chan_iax2.c.
Definition at line 984 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
Definition at line 830 of file chan_iax2.c.
Referenced by __find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 448 of file chan_iax2.c.
anonymous enum |
Definition at line 234 of file chan_iax2.c.
00234 { 00235 IAX_STATE_STARTED = (1 << 0), 00236 IAX_STATE_AUTHENTICATED = (1 << 1), 00237 IAX_STATE_TBD = (1 << 2), 00238 } iax2_state;
anonymous enum |
Definition at line 245 of file chan_iax2.c.
00245 { 00246 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00247 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00248 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00249 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00250 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00251 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00252 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00253 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00254 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00255 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00256 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00257 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00258 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00259 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00260 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00261 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00262 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00263 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00264 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00265 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00266 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00267 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00268 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00269 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00270 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00271 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00272 response, so that we've achieved a three-way handshake with 00273 them before sending voice or anything else*/ 00274 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00275 } iax2_flags;
enum iax_reg_state |
REG_STATE_UNREGISTERED | |
REG_STATE_REGSENT | |
REG_STATE_AUTHSENT | |
REG_STATE_REGISTERED | |
REG_STATE_REJECTED | |
REG_STATE_TIMEOUT | |
REG_STATE_NOAUTH |
Definition at line 394 of file chan_iax2.c.
00394 { 00395 REG_STATE_UNREGISTERED = 0, 00396 REG_STATE_REGSENT, 00397 REG_STATE_AUTHSENT, 00398 REG_STATE_REGISTERED, 00399 REG_STATE_REJECTED, 00400 REG_STATE_TIMEOUT, 00401 REG_STATE_NOAUTH 00402 };
enum iax_transfer_state |
TRANSFER_NONE | |
TRANSFER_BEGIN | |
TRANSFER_READY | |
TRANSFER_RELEASED | |
TRANSFER_PASSTHROUGH | |
TRANSFER_MBEGIN | |
TRANSFER_MREADY | |
TRANSFER_MRELEASED | |
TRANSFER_MPASSTHROUGH | |
TRANSFER_MEDIA | |
TRANSFER_MEDIAPASS |
Definition at line 404 of file chan_iax2.c.
00404 { 00405 TRANSFER_NONE = 0, 00406 TRANSFER_BEGIN, 00407 TRANSFER_READY, 00408 TRANSFER_RELEASED, 00409 TRANSFER_PASSTHROUGH, 00410 TRANSFER_MBEGIN, 00411 TRANSFER_MREADY, 00412 TRANSFER_MRELEASED, 00413 TRANSFER_MPASSTHROUGH, 00414 TRANSFER_MEDIA, 00415 TRANSFER_MEDIAPASS 00416 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2150 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, iax2_registry::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02151 { 02152 /* Attempt to transmit the frame to the remote peer... 02153 Called without iaxsl held. */ 02154 struct iax_frame *f = (struct iax_frame *)data; 02155 int freeme=0; 02156 int callno = f->callno; 02157 /* Make sure this call is still active */ 02158 if (callno) 02159 ast_mutex_lock(&iaxsl[callno]); 02160 if (callno && iaxs[callno]) { 02161 if ((f->retries < 0) /* Already ACK'd */ || 02162 (f->retries >= max_retries) /* Too many attempts */) { 02163 /* Record an error if we've transmitted too many times */ 02164 if (f->retries >= max_retries) { 02165 if (f->transfer) { 02166 /* Transfer timeout */ 02167 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02168 } else if (f->final) { 02169 if (f->final) 02170 iax2_destroy(callno); 02171 } else { 02172 if (iaxs[callno]->owner) 02173 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); 02174 iaxs[callno]->error = ETIMEDOUT; 02175 if (iaxs[callno]->owner) { 02176 struct ast_frame fr = { 0, }; 02177 /* Hangup the fd */ 02178 fr.frametype = AST_FRAME_CONTROL; 02179 fr.subclass = AST_CONTROL_HANGUP; 02180 iax2_queue_frame(callno, &fr); // XXX 02181 /* Remember, owner could disappear */ 02182 if (iaxs[callno] && iaxs[callno]->owner) 02183 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02184 } else { 02185 if (iaxs[callno]->reg) { 02186 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02187 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02188 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02189 } 02190 iax2_destroy(callno); 02191 } 02192 } 02193 02194 } 02195 freeme++; 02196 } else { 02197 /* Update it if it needs it */ 02198 update_packet(f); 02199 /* Attempt transmission */ 02200 send_packet(f); 02201 f->retries++; 02202 /* Try again later after 10 times as long */ 02203 f->retrytime *= 10; 02204 if (f->retrytime > MAX_RETRY_TIME) 02205 f->retrytime = MAX_RETRY_TIME; 02206 /* Transfer messages max out at one second */ 02207 if (f->transfer && (f->retrytime > 1000)) 02208 f->retrytime = 1000; 02209 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02210 } 02211 } else { 02212 /* Make sure it gets freed */ 02213 f->retries = -1; 02214 freeme++; 02215 } 02216 if (callno) 02217 ast_mutex_unlock(&iaxsl[callno]); 02218 /* Do not try again */ 02219 if (freeme) { 02220 /* Don't attempt delivery, just remove it from the queue */ 02221 AST_LIST_LOCK(&iaxq.queue); 02222 AST_LIST_REMOVE(&iaxq.queue, f, list); 02223 iaxq.count--; 02224 AST_LIST_UNLOCK(&iaxq.queue); 02225 f->retrans = -1; 02226 /* Free the IAX frame */ 02227 iax2_frame_free(f); 02228 } 02229 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6393 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().
06394 { 06395 /* Called from IAX thread only, without iaxs lock */ 06396 int callno = (int)(long)(nothing); 06397 struct iax_ie_data ied; 06398 ast_mutex_lock(&iaxsl[callno]); 06399 if (iaxs[callno]) { 06400 memset(&ied, 0, sizeof(ied)); 06401 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06402 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06403 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06404 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06405 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06406 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06407 } 06408 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06409 } 06410 ast_mutex_unlock(&iaxsl[callno]); 06411 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3105 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03106 { 03107 int callno = PTR_TO_CALLNO(nothing); 03108 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03109 ast_mutex_lock(&iaxsl[callno]); 03110 if (iaxs[callno]) { 03111 iaxs[callno]->initid = -1; 03112 iax2_queue_frame(callno, &f); 03113 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03114 } 03115 ast_mutex_unlock(&iaxsl[callno]); 03116 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6442 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().
06443 { 06444 /* Called from IAX thread only, without iaxs lock */ 06445 int callno = (int)(long)(nothing); 06446 struct iax_ie_data ied; 06447 ast_mutex_lock(&iaxsl[callno]); 06448 if (iaxs[callno]) { 06449 memset(&ied, 0, sizeof(ied)); 06450 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06451 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06452 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06453 } 06454 ast_mutex_unlock(&iaxsl[callno]); 06455 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 2017 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
02018 { 02019 /* Just deliver the packet by using queueing. This is called by 02020 the IAX thread with the iaxsl lock held. */ 02021 struct iax_frame *fr = data; 02022 fr->retrans = -1; 02023 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02024 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02025 iax2_queue_frame(fr->callno, &fr->af); 02026 /* Free our iax frame */ 02027 iax2_frame_free(fr); 02028 /* And don't run again */ 02029 return 0; 02030 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6072 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().
06073 { 06074 struct iax2_peer *peer = (struct iax2_peer *) data; 06075 06076 if (!peer) 06077 return; 06078 06079 peer->expire = -1; 06080 06081 if (option_debug) 06082 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06083 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06084 realtime_update_peer(peer->name, &peer->addr, 0); 06085 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06086 /* Reset the address */ 06087 memset(&peer->addr, 0, sizeof(peer->addr)); 06088 /* Reset expiry value */ 06089 peer->expiry = min_reg_expire; 06090 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06091 ast_db_del("IAX/Registry", peer->name); 06092 register_peer_exten(peer, 0); 06093 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06094 if (iax2_regfunk) 06095 iax2_regfunk(peer->name, 0); 06096 06097 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06098 unlink_peer(peer); 06099 06100 peer_unref(peer); 06101 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1516 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01517 { 01518 int res = 0; 01519 int x; 01520 struct timeval now; 01521 char host[80]; 01522 01523 if (new <= NEW_ALLOW) { 01524 if (callno) { 01525 struct chan_iax2_pvt *pvt; 01526 struct chan_iax2_pvt tmp_pvt = { 01527 .callno = dcallno, 01528 .peercallno = callno, 01529 /* hack!! */ 01530 .frames_received = check_dcallno, 01531 }; 01532 01533 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01534 01535 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01536 if (return_locked) { 01537 ast_mutex_lock(&iaxsl[pvt->callno]); 01538 } 01539 res = pvt->callno; 01540 ao2_ref(pvt, -1); 01541 pvt = NULL; 01542 return res; 01543 } 01544 } 01545 01546 /* Look for an existing connection first */ 01547 for (x = 1; !res && x < maxnontrunkcall; x++) { 01548 ast_mutex_lock(&iaxsl[x]); 01549 if (iaxs[x]) { 01550 /* Look for an exact match */ 01551 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01552 res = x; 01553 } 01554 } 01555 if (!res || !return_locked) 01556 ast_mutex_unlock(&iaxsl[x]); 01557 } 01558 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01559 ast_mutex_lock(&iaxsl[x]); 01560 if (iaxs[x]) { 01561 /* Look for an exact match */ 01562 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01563 res = x; 01564 } 01565 } 01566 if (!res || !return_locked) 01567 ast_mutex_unlock(&iaxsl[x]); 01568 } 01569 } 01570 if (!res && (new >= NEW_ALLOW)) { 01571 int start, found = 0; 01572 01573 /* It may seem odd that we look through the peer list for a name for 01574 * this *incoming* call. Well, it is weird. However, users don't 01575 * have an IP address/port number that we can match against. So, 01576 * this is just checking for a peer that has that IP/port and 01577 * assuming that we have a user of the same name. This isn't always 01578 * correct, but it will be changed if needed after authentication. */ 01579 if (!iax2_getpeername(*sin, host, sizeof(host))) 01580 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01581 01582 now = ast_tvnow(); 01583 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01584 for (x = start; 1; x++) { 01585 if (x == TRUNK_CALL_START) { 01586 x = 1; 01587 continue; 01588 } 01589 01590 /* Find first unused call number that hasn't been used in a while */ 01591 ast_mutex_lock(&iaxsl[x]); 01592 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01593 found = 1; 01594 break; 01595 } 01596 ast_mutex_unlock(&iaxsl[x]); 01597 01598 if (x == start - 1) { 01599 break; 01600 } 01601 } 01602 /* We've still got lock held if we found a spot */ 01603 if (x == start - 1 && !found) { 01604 ast_log(LOG_WARNING, "No more space\n"); 01605 return 0; 01606 } 01607 iaxs[x] = new_iax(sin, host); 01608 update_max_nontrunk(); 01609 if (iaxs[x]) { 01610 if (option_debug && iaxdebug) 01611 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01612 iaxs[x]->sockfd = sockfd; 01613 iaxs[x]->addr.sin_port = sin->sin_port; 01614 iaxs[x]->addr.sin_family = sin->sin_family; 01615 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01616 iaxs[x]->peercallno = callno; 01617 iaxs[x]->callno = x; 01618 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01619 iaxs[x]->expiry = min_reg_expire; 01620 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01621 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01622 iaxs[x]->amaflags = amaflags; 01623 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01624 01625 ast_string_field_set(iaxs[x], accountcode, accountcode); 01626 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01627 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01628 01629 if (iaxs[x]->peercallno) { 01630 store_by_peercallno(iaxs[x]); 01631 } 01632 } else { 01633 ast_log(LOG_WARNING, "Out of resources\n"); 01634 ast_mutex_unlock(&iaxsl[x]); 01635 return 0; 01636 } 01637 if (!return_locked) 01638 ast_mutex_unlock(&iaxsl[x]); 01639 res = x; 01640 } 01641 return res; 01642 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2547 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
02548 { 02549 int callno = PTR_TO_CALLNO(p); 02550 struct chan_iax2_pvt *pvt = NULL; 02551 struct iax_frame *fr; 02552 jb_frame frame; 02553 int ret; 02554 long now; 02555 long next; 02556 struct timeval tv; 02557 02558 /* Make sure we have a valid private structure before going on */ 02559 ast_mutex_lock(&iaxsl[callno]); 02560 pvt = iaxs[callno]; 02561 if (!pvt) { 02562 /* No go! */ 02563 ast_mutex_unlock(&iaxsl[callno]); 02564 return; 02565 } 02566 02567 pvt->jbid = -1; 02568 02569 gettimeofday(&tv,NULL); 02570 /* round up a millisecond since ast_sched_runq does; */ 02571 /* prevents us from spinning while waiting for our now */ 02572 /* to catch up with runq's now */ 02573 tv.tv_usec += 1000; 02574 02575 now = ast_tvdiff_ms(tv, pvt->rxcore); 02576 02577 if(now >= (next = jb_next(pvt->jb))) { 02578 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02579 switch(ret) { 02580 case JB_OK: 02581 fr = frame.data; 02582 __do_deliver(fr); 02583 /* __do_deliver() can cause the call to disappear */ 02584 pvt = iaxs[callno]; 02585 break; 02586 case JB_INTERP: 02587 { 02588 struct ast_frame af = { 0, }; 02589 02590 /* create an interpolation frame */ 02591 af.frametype = AST_FRAME_VOICE; 02592 af.subclass = pvt->voiceformat; 02593 af.samples = frame.ms * 8; 02594 af.src = "IAX2 JB interpolation"; 02595 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02596 af.offset = AST_FRIENDLY_OFFSET; 02597 02598 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02599 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02600 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02601 iax2_queue_frame(callno, &af); 02602 /* iax2_queue_frame() could cause the call to disappear */ 02603 pvt = iaxs[callno]; 02604 } 02605 } 02606 break; 02607 case JB_DROP: 02608 iax2_frame_free(frame.data); 02609 break; 02610 case JB_NOFRAME: 02611 case JB_EMPTY: 02612 /* do nothing */ 02613 break; 02614 default: 02615 /* shouldn't happen */ 02616 break; 02617 } 02618 } 02619 if (pvt) 02620 update_jbsched(pvt); 02621 ast_mutex_unlock(&iaxsl[callno]); 02622 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5765 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05766 { 05767 struct iax2_registry *reg = (struct iax2_registry *)data; 05768 reg->expire = -1; 05769 iax2_do_register(reg); 05770 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8876 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().
08877 { 08878 struct iax2_peer *peer = (struct iax2_peer *)data; 08879 int callno; 08880 08881 if (peer->lastms > -1) { 08882 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08883 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08884 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08885 } 08886 if ((callno = peer->callno) > 0) { 08887 ast_mutex_lock(&iaxsl[callno]); 08888 iax2_destroy(callno); 08889 ast_mutex_unlock(&iaxsl[callno]); 08890 } 08891 peer->callno = 0; 08892 peer->lastms = -1; 08893 /* Try again quickly */ 08894 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08895 if (peer->pokeexpire == -1) 08896 peer_unref(peer); 08897 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6505 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06506 { 06507 struct iax2_peer *peer = (struct iax2_peer *)data; 06508 iax2_poke_peer(peer, 0); 06509 peer_unref(peer); 06510 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4520 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().
04521 { 04522 regex_t regexbuf; 04523 int havepattern = 0; 04524 int total_peers = 0; 04525 int online_peers = 0; 04526 int offline_peers = 0; 04527 int unmonitored_peers = 0; 04528 struct ao2_iterator i; 04529 04530 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04531 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04532 04533 struct iax2_peer *peer = NULL; 04534 char name[256]; 04535 int registeredonly=0; 04536 char *term = manager ? "\r\n" : "\n"; 04537 04538 switch (argc) { 04539 case 6: 04540 if (!strcasecmp(argv[3], "registered")) 04541 registeredonly = 1; 04542 else 04543 return RESULT_SHOWUSAGE; 04544 if (!strcasecmp(argv[4], "like")) { 04545 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04546 return RESULT_SHOWUSAGE; 04547 havepattern = 1; 04548 } else 04549 return RESULT_SHOWUSAGE; 04550 break; 04551 case 5: 04552 if (!strcasecmp(argv[3], "like")) { 04553 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04554 return RESULT_SHOWUSAGE; 04555 havepattern = 1; 04556 } else 04557 return RESULT_SHOWUSAGE; 04558 break; 04559 case 4: 04560 if (!strcasecmp(argv[3], "registered")) 04561 registeredonly = 1; 04562 else 04563 return RESULT_SHOWUSAGE; 04564 break; 04565 case 3: 04566 break; 04567 default: 04568 return RESULT_SHOWUSAGE; 04569 } 04570 04571 04572 if (s) 04573 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04574 else 04575 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04576 04577 i = ao2_iterator_init(peers, 0); 04578 for (peer = ao2_iterator_next(&i); peer; 04579 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04580 char nm[20]; 04581 char status[20]; 04582 char srch[2000]; 04583 int retstatus; 04584 04585 if (registeredonly && !peer->addr.sin_addr.s_addr) 04586 continue; 04587 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04588 continue; 04589 04590 if (!ast_strlen_zero(peer->username)) 04591 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04592 else 04593 ast_copy_string(name, peer->name, sizeof(name)); 04594 04595 retstatus = peer_status(peer, status, sizeof(status)); 04596 if (retstatus > 0) 04597 online_peers++; 04598 else if (!retstatus) 04599 offline_peers++; 04600 else 04601 unmonitored_peers++; 04602 04603 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04604 04605 snprintf(srch, sizeof(srch), FORMAT, name, 04606 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04607 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04608 nm, 04609 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04610 peer->encmethods ? "(E)" : " ", status, term); 04611 04612 if (s) 04613 astman_append(s, FORMAT, name, 04614 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04615 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04616 nm, 04617 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04618 peer->encmethods ? "(E)" : " ", status, term); 04619 else 04620 ast_cli(fd, FORMAT, name, 04621 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04622 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04623 nm, 04624 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04625 peer->encmethods ? "(E)" : " ", status, term); 04626 total_peers++; 04627 } 04628 04629 if (s) 04630 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04631 else 04632 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04633 04634 if (havepattern) 04635 regfree(®exbuf); 04636 04637 return RESULT_SUCCESS; 04638 #undef FORMAT 04639 #undef FORMAT2 04640 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 959 of file chan_iax2.c.
References ast_log(), find_idle_thread(), func, IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00960 { 00961 struct iax2_thread *thread = NULL; 00962 static time_t lasterror; 00963 static time_t t; 00964 00965 thread = find_idle_thread(); 00966 00967 if (thread != NULL) { 00968 thread->schedfunc = func; 00969 thread->scheddata = data; 00970 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00971 #ifdef DEBUG_SCHED_MULTITHREAD 00972 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00973 #endif 00974 signal_condition(&thread->lock, &thread->cond); 00975 return 0; 00976 } 00977 time(&t); 00978 if (t != lasterror && option_debug) 00979 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00980 lasterror = t; 00981 00982 return -1; 00983 }
static int __send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 5021 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().
05023 { 05024 struct ast_frame f = { 0, }; 05025 05026 f.frametype = type; 05027 f.subclass = command; 05028 f.datalen = datalen; 05029 f.src = __FUNCTION__; 05030 f.data = (void *) data; 05031 05032 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05033 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1039 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01040 { 01041 int callno = (long) data; 01042 01043 ast_mutex_lock(&iaxsl[callno]); 01044 01045 while (iaxs[callno] && iaxs[callno]->lagid > -1) { 01046 if (iaxs[callno]->peercallno) { 01047 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01048 } 01049 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01050 break; 01051 } 01052 01053 ast_mutex_unlock(&iaxsl[callno]); 01054 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 999 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01000 { 01001 int callno = (long) data; 01002 01003 ast_mutex_lock(&iaxsl[callno]); 01004 01005 while (iaxs[callno] && iaxs[callno]->pingid != -1) { 01006 if (iaxs[callno]->peercallno) { 01007 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01008 } 01009 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01010 break; 01011 } 01012 01013 ast_mutex_unlock(&iaxsl[callno]); 01014 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11003 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().
11004 { 11005 struct iax2_thread *thread = NULL; 11006 int x; 11007 11008 /* Make sure threads do not hold shared resources when they are canceled */ 11009 11010 /* Grab the sched lock resource to keep it away from threads about to die */ 11011 /* Cancel the network thread, close the net socket */ 11012 if (netthreadid != AST_PTHREADT_NULL) { 11013 AST_LIST_LOCK(&iaxq.queue); 11014 ast_mutex_lock(&sched_lock); 11015 pthread_cancel(netthreadid); 11016 ast_cond_signal(&sched_cond); 11017 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11018 AST_LIST_UNLOCK(&iaxq.queue); 11019 pthread_join(netthreadid, NULL); 11020 } 11021 if (schedthreadid != AST_PTHREADT_NULL) { 11022 ast_mutex_lock(&sched_lock); 11023 pthread_cancel(schedthreadid); 11024 ast_cond_signal(&sched_cond); 11025 ast_mutex_unlock(&sched_lock); 11026 pthread_join(schedthreadid, NULL); 11027 } 11028 11029 /* Call for all threads to halt */ 11030 AST_LIST_LOCK(&idle_list); 11031 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11032 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11033 pthread_cancel(thread->threadid); 11034 } 11035 AST_LIST_TRAVERSE_SAFE_END 11036 AST_LIST_UNLOCK(&idle_list); 11037 11038 AST_LIST_LOCK(&active_list); 11039 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11040 AST_LIST_REMOVE_CURRENT(&active_list, list); 11041 pthread_cancel(thread->threadid); 11042 } 11043 AST_LIST_TRAVERSE_SAFE_END 11044 AST_LIST_UNLOCK(&active_list); 11045 11046 AST_LIST_LOCK(&dynamic_list); 11047 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11048 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11049 pthread_cancel(thread->threadid); 11050 } 11051 AST_LIST_TRAVERSE_SAFE_END 11052 AST_LIST_UNLOCK(&dynamic_list); 11053 11054 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11055 11056 /* Wait for threads to exit */ 11057 while(0 < iaxactivethreadcount) 11058 usleep(10000); 11059 11060 ast_netsock_release(netsock); 11061 ast_netsock_release(outsock); 11062 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11063 if (iaxs[x]) { 11064 iax2_destroy(x); 11065 } 11066 } 11067 ast_manager_unregister( "IAXpeers" ); 11068 ast_manager_unregister( "IAXnetstats" ); 11069 ast_unregister_application(papp); 11070 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11071 ast_unregister_switch(&iax2_switch); 11072 ast_channel_unregister(&iax2_tech); 11073 delete_users(); 11074 iax_provision_unload(); 11075 sched_context_destroy(sched); 11076 reload_firmware(1); 11077 11078 ast_mutex_destroy(&waresl.lock); 11079 11080 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11081 ast_mutex_destroy(&iaxsl[x]); 11082 } 11083 11084 ao2_ref(peers, -1); 11085 ao2_ref(users, -1); 11086 ao2_ref(iax_peercallno_pvts, -1); 11087 11088 return 0; 11089 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5074 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05075 { 05076 while(con) { 05077 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05078 return -1; 05079 con = con->next; 05080 } 05081 return 0; 05082 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4848 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().
04849 { 04850 int x; 04851 int numchans = 0; 04852 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04853 ast_mutex_lock(&iaxsl[x]); 04854 if (iaxs[x]) { 04855 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04856 char *fmt; 04857 jb_info jbinfo; 04858 04859 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04860 jb_getinfo(iaxs[x]->jb, &jbinfo); 04861 localjitter = jbinfo.jitter; 04862 localdelay = jbinfo.current - jbinfo.min; 04863 locallost = jbinfo.frames_lost; 04864 locallosspct = jbinfo.losspct/1000; 04865 localdropped = jbinfo.frames_dropped; 04866 localooo = jbinfo.frames_ooo; 04867 } else { 04868 localjitter = -1; 04869 localdelay = 0; 04870 locallost = -1; 04871 locallosspct = -1; 04872 localdropped = 0; 04873 localooo = -1; 04874 } 04875 if (limit_fmt) 04876 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04877 else 04878 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04879 if (s) 04880 04881 astman_append(s, fmt, 04882 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04883 iaxs[x]->pingtime, 04884 localjitter, 04885 localdelay, 04886 locallost, 04887 locallosspct, 04888 localdropped, 04889 localooo, 04890 iaxs[x]->frames_received/1000, 04891 iaxs[x]->remote_rr.jitter, 04892 iaxs[x]->remote_rr.delay, 04893 iaxs[x]->remote_rr.losscnt, 04894 iaxs[x]->remote_rr.losspct, 04895 iaxs[x]->remote_rr.dropped, 04896 iaxs[x]->remote_rr.ooo, 04897 iaxs[x]->remote_rr.packets/1000); 04898 else 04899 ast_cli(fd, fmt, 04900 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04901 iaxs[x]->pingtime, 04902 localjitter, 04903 localdelay, 04904 locallost, 04905 locallosspct, 04906 localdropped, 04907 localooo, 04908 iaxs[x]->frames_received/1000, 04909 iaxs[x]->remote_rr.jitter, 04910 iaxs[x]->remote_rr.delay, 04911 iaxs[x]->remote_rr.losscnt, 04912 iaxs[x]->remote_rr.losspct, 04913 iaxs[x]->remote_rr.dropped, 04914 iaxs[x]->remote_rr.ooo, 04915 iaxs[x]->remote_rr.packets/1000 04916 ); 04917 numchans++; 04918 } 04919 ast_mutex_unlock(&iaxsl[x]); 04920 } 04921 return numchans; 04922 }
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 3726 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().
03727 { 03728 struct ast_channel *tmp; 03729 struct chan_iax2_pvt *i; 03730 struct ast_variable *v = NULL; 03731 03732 if (!(i = iaxs[callno])) { 03733 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03734 return NULL; 03735 } 03736 03737 /* Don't hold call lock */ 03738 ast_mutex_unlock(&iaxsl[callno]); 03739 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); 03740 ast_mutex_lock(&iaxsl[callno]); 03741 if (!iaxs[callno]) { 03742 if (tmp) { 03743 ast_channel_free(tmp); 03744 } 03745 ast_mutex_unlock(&iaxsl[callno]); 03746 return NULL; 03747 } 03748 03749 if (!tmp) 03750 return NULL; 03751 tmp->tech = &iax2_tech; 03752 /* We can support any format by default, until we get restricted */ 03753 tmp->nativeformats = capability; 03754 tmp->readformat = ast_best_codec(capability); 03755 tmp->writeformat = ast_best_codec(capability); 03756 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03757 03758 /* Don't use ast_set_callerid() here because it will 03759 * generate a NewCallerID event before the NewChannel event */ 03760 if (!ast_strlen_zero(i->ani)) 03761 tmp->cid.cid_ani = ast_strdup(i->ani); 03762 else 03763 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03764 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03765 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03766 tmp->cid.cid_pres = i->calling_pres; 03767 tmp->cid.cid_ton = i->calling_ton; 03768 tmp->cid.cid_tns = i->calling_tns; 03769 if (!ast_strlen_zero(i->language)) 03770 ast_string_field_set(tmp, language, i->language); 03771 if (!ast_strlen_zero(i->accountcode)) 03772 ast_string_field_set(tmp, accountcode, i->accountcode); 03773 if (i->amaflags) 03774 tmp->amaflags = i->amaflags; 03775 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03776 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03777 if (i->adsi) 03778 tmp->adsicpe = i->peeradsicpe; 03779 else 03780 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03781 i->owner = tmp; 03782 i->capability = capability; 03783 03784 for (v = i->vars ; v ; v = v->next) 03785 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03786 03787 if (state != AST_STATE_DOWN) { 03788 if (ast_pbx_start(tmp)) { 03789 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03790 ast_hangup(tmp); 03791 i->owner = NULL; 03792 return NULL; 03793 } 03794 } 03795 03796 ast_module_ref(ast_module_info->self); 03797 03798 return tmp; 03799 }
static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | active_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | registrations | , | |
iax2_registry | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Inter Asterisk eXchange (Ver 2)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | sched_lock | ) |
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2231 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02232 { 02233 #ifdef SCHED_MULTITHREADED 02234 if (schedule_action(__attempt_transmit, data)) 02235 #endif 02236 __attempt_transmit(data); 02237 return 0; 02238 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6427 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().
06428 { 06429 /* Schedule sending the authentication failure in one second, to prevent 06430 guessing */ 06431 if (iaxs[callno]) { 06432 iaxs[callno]->authfail = failcode; 06433 if (delayreject) { 06434 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06435 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06436 } else 06437 auth_reject((void *)(long)callno); 06438 } 06439 return 0; 06440 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6413 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().
06414 { 06415 int callno = (int)(long)(data); 06416 ast_mutex_lock(&iaxsl[callno]); 06417 if (iaxs[callno]) 06418 iaxs[callno]->authid = -1; 06419 ast_mutex_unlock(&iaxsl[callno]); 06420 #ifdef SCHED_MULTITHREADED 06421 if (schedule_action(__auth_reject, data)) 06422 #endif 06423 __auth_reject(data); 06424 return 0; 06425 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5634 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
05635 { 05636 int res = -1; 05637 int x; 05638 if (!ast_strlen_zero(keyn)) { 05639 if (!(authmethods & IAX_AUTH_RSA)) { 05640 if (ast_strlen_zero(secret)) 05641 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)); 05642 } else if (ast_strlen_zero(challenge)) { 05643 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05644 } else { 05645 char sig[256]; 05646 struct ast_key *key; 05647 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05648 if (!key) { 05649 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05650 } else { 05651 if (ast_sign(key, (char*)challenge, sig)) { 05652 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05653 res = -1; 05654 } else { 05655 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05656 res = 0; 05657 } 05658 } 05659 } 05660 } 05661 /* Fall back */ 05662 if (res && !ast_strlen_zero(secret)) { 05663 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05664 struct MD5Context md5; 05665 unsigned char digest[16]; 05666 char digres[128]; 05667 MD5Init(&md5); 05668 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05669 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05670 MD5Final(digest, &md5); 05671 /* If they support md5, authenticate with it. */ 05672 for (x=0;x<16;x++) 05673 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05674 if (ecx && dcx) 05675 build_enc_keys(digest, ecx, dcx); 05676 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05677 res = 0; 05678 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05679 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05680 res = 0; 05681 } else 05682 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05683 } 05684 return res; 05685 }
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 5691 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, iax2_registry::callno, iax_ies::challenge, chan_iax2_pvt::dcx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, iax2_peer::mask, merge_encryption(), peer_unref(), peers, iax_ie_data::pos, realtime_peer(), send_command(), and iax_ies::username.
Referenced by socket_process().
05692 { 05693 struct iax2_peer *peer = NULL; 05694 /* Start pessimistic */ 05695 int res = -1; 05696 int authmethods = 0; 05697 struct iax_ie_data ied; 05698 uint16_t callno = p->callno; 05699 05700 memset(&ied, 0, sizeof(ied)); 05701 05702 if (ies->username) 05703 ast_string_field_set(p, username, ies->username); 05704 if (ies->challenge) 05705 ast_string_field_set(p, challenge, ies->challenge); 05706 if (ies->authmethods) 05707 authmethods = ies->authmethods; 05708 if (authmethods & IAX_AUTH_MD5) 05709 merge_encryption(p, ies->encmethods); 05710 else 05711 p->encmethods = 0; 05712 05713 /* Check for override RSA authentication first */ 05714 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05715 /* Normal password authentication */ 05716 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05717 } else { 05718 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05719 while ((peer = ao2_iterator_next(&i))) { 05720 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05721 /* No peer specified at our end, or this is the peer */ 05722 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05723 /* No username specified in peer rule, or this is the right username */ 05724 && (!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))) 05725 /* No specified host, or this is our host */ 05726 ) { 05727 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05728 if (!res) { 05729 peer_unref(peer); 05730 break; 05731 } 05732 } 05733 peer_unref(peer); 05734 } 05735 if (!peer) { 05736 /* We checked our list and didn't find one. It's unlikely, but possible, 05737 that we're trying to authenticate *to* a realtime peer */ 05738 const char *peer_name = ast_strdupa(p->peer); 05739 ast_mutex_unlock(&iaxsl[callno]); 05740 if ((peer = realtime_peer(peer_name, NULL))) { 05741 ast_mutex_lock(&iaxsl[callno]); 05742 if (!(p = iaxs[callno])) { 05743 peer_unref(peer); 05744 return -1; 05745 } 05746 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05747 peer_unref(peer); 05748 } 05749 if (!peer) { 05750 ast_mutex_lock(&iaxsl[callno]); 05751 if (!(p = iaxs[callno])) 05752 return -1; 05753 } 05754 } 05755 } 05756 if (ies->encmethods) 05757 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05758 if (!res) 05759 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05760 return res; 05761 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5346 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().
05347 { 05348 struct iax_ie_data ied; 05349 int res = -1, authreq_restrict = 0; 05350 char challenge[10]; 05351 struct chan_iax2_pvt *p = iaxs[call_num]; 05352 05353 memset(&ied, 0, sizeof(ied)); 05354 05355 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05356 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05357 struct iax2_user *user, tmp_user = { 05358 .name = p->username, 05359 }; 05360 05361 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05362 if (user) { 05363 if (user->curauthreq == user->maxauthreq) 05364 authreq_restrict = 1; 05365 else 05366 user->curauthreq++; 05367 user = user_unref(user); 05368 } 05369 } 05370 05371 /* If the AUTHREQ limit test failed, send back an error */ 05372 if (authreq_restrict) { 05373 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05374 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05375 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05376 return 0; 05377 } 05378 05379 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05380 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05381 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05382 ast_string_field_set(p, challenge, challenge); 05383 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05384 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05385 } 05386 if (p->encmethods) 05387 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05388 05389 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05390 05391 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05392 05393 if (p->encmethods) 05394 ast_set_flag(p, IAX_ENCRYPTED); 05395 05396 return res; 05397 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5399 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().
05400 { 05401 char requeststr[256]; 05402 char md5secret[256] = ""; 05403 char secret[256] = ""; 05404 char rsasecret[256] = ""; 05405 int res = -1; 05406 int x; 05407 struct iax2_user *user, tmp_user = { 05408 .name = p->username, 05409 }; 05410 05411 if (p->authrej) { 05412 return res; 05413 } 05414 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05415 if (user) { 05416 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05417 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05418 ast_clear_flag(p, IAX_MAXAUTHREQ); 05419 } 05420 ast_string_field_set(p, host, user->name); 05421 user = user_unref(user); 05422 } 05423 05424 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05425 return res; 05426 if (ies->password) 05427 ast_copy_string(secret, ies->password, sizeof(secret)); 05428 if (ies->md5_result) 05429 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05430 if (ies->rsa_result) 05431 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05432 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05433 struct ast_key *key; 05434 char *keyn; 05435 char tmpkey[256]; 05436 char *stringp=NULL; 05437 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05438 stringp=tmpkey; 05439 keyn = strsep(&stringp, ":"); 05440 while(keyn) { 05441 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05442 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05443 res = 0; 05444 break; 05445 } else if (!key) 05446 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05447 keyn = strsep(&stringp, ":"); 05448 } 05449 } else if (p->authmethods & IAX_AUTH_MD5) { 05450 struct MD5Context md5; 05451 unsigned char digest[16]; 05452 char *tmppw, *stringp; 05453 05454 tmppw = ast_strdupa(p->secret); 05455 stringp = tmppw; 05456 while((tmppw = strsep(&stringp, ";"))) { 05457 MD5Init(&md5); 05458 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05459 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05460 MD5Final(digest, &md5); 05461 /* If they support md5, authenticate with it. */ 05462 for (x=0;x<16;x++) 05463 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05464 if (!strcasecmp(requeststr, md5secret)) { 05465 res = 0; 05466 break; 05467 } 05468 } 05469 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05470 if (!strcmp(secret, p->secret)) 05471 res = 0; 05472 } 05473 return res; 05474 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3118 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03119 { 03120 #ifdef SCHED_MULTITHREADED 03121 if (schedule_action(__auto_congest, data)) 03122 #endif 03123 __auto_congest(data); 03124 return 0; 03125 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6457 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().
06458 { 06459 int callno = (int)(long)(data); 06460 ast_mutex_lock(&iaxsl[callno]); 06461 if (iaxs[callno]) { 06462 iaxs[callno]->autoid = -1; 06463 } 06464 ast_mutex_unlock(&iaxsl[callno]); 06465 #ifdef SCHED_MULTITHREADED 06466 if (schedule_action(__auto_hangup, data)) 06467 #endif 06468 __auto_hangup(data); 06469 return 0; 06470 }
static struct iax2_context* build_context | ( | char * | context | ) | [static, read] |
Definition at line 9197 of file chan_iax2.c.
References ast_calloc, and iax2_context::context.
Referenced by build_user().
09198 { 09199 struct iax2_context *con; 09200 09201 if ((con = ast_calloc(1, sizeof(*con)))) 09202 ast_copy_string(con->context, context, sizeof(con->context)); 09203 09204 return con; 09205 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4106 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04107 { 04108 aes_encrypt_key128(digest, ecx); 04109 aes_decrypt_key128(digest, dcx); 04110 }
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 9343 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.
09344 { 09345 struct iax2_peer *peer = NULL; 09346 struct ast_ha *oldha = NULL; 09347 int maskfound=0; 09348 int found=0; 09349 int firstpass=1; 09350 struct iax2_peer tmp_peer = { 09351 .name = name, 09352 }; 09353 09354 if (!temponly) { 09355 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09356 if (peer && !ast_test_flag(peer, IAX_DELME)) 09357 firstpass = 0; 09358 } 09359 09360 if (peer) { 09361 found++; 09362 if (firstpass) { 09363 oldha = peer->ha; 09364 peer->ha = NULL; 09365 } 09366 unlink_peer(peer); 09367 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09368 peer->expire = -1; 09369 peer->pokeexpire = -1; 09370 peer->sockfd = defaultsockfd; 09371 if (ast_string_field_init(peer, 32)) 09372 peer = peer_unref(peer); 09373 } 09374 09375 if (peer) { 09376 if (firstpass) { 09377 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09378 peer->encmethods = iax2_encryption; 09379 peer->adsi = adsi; 09380 ast_string_field_set(peer,secret,""); 09381 if (!found) { 09382 ast_string_field_set(peer, name, name); 09383 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09384 peer->expiry = min_reg_expire; 09385 } 09386 peer->prefs = prefs; 09387 peer->capability = iax2_capability; 09388 peer->smoothing = 0; 09389 peer->pokefreqok = DEFAULT_FREQ_OK; 09390 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09391 ast_string_field_set(peer,context,""); 09392 ast_string_field_set(peer,peercontext,""); 09393 ast_clear_flag(peer, IAX_HASCALLERID); 09394 ast_string_field_set(peer, cid_name, ""); 09395 ast_string_field_set(peer, cid_num, ""); 09396 } 09397 09398 if (!v) { 09399 v = alt; 09400 alt = NULL; 09401 } 09402 while(v) { 09403 if (!strcasecmp(v->name, "secret")) { 09404 ast_string_field_set(peer, secret, v->value); 09405 } else if (!strcasecmp(v->name, "mailbox")) { 09406 ast_string_field_set(peer, mailbox, v->value); 09407 } else if (!strcasecmp(v->name, "mohinterpret")) { 09408 ast_string_field_set(peer, mohinterpret, v->value); 09409 } else if (!strcasecmp(v->name, "mohsuggest")) { 09410 ast_string_field_set(peer, mohsuggest, v->value); 09411 } else if (!strcasecmp(v->name, "dbsecret")) { 09412 ast_string_field_set(peer, dbsecret, v->value); 09413 } else if (!strcasecmp(v->name, "trunk")) { 09414 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09415 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09416 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09417 ast_clear_flag(peer, IAX_TRUNK); 09418 } 09419 } else if (!strcasecmp(v->name, "auth")) { 09420 peer->authmethods = get_auth_methods(v->value); 09421 } else if (!strcasecmp(v->name, "encryption")) { 09422 peer->encmethods = get_encrypt_methods(v->value); 09423 } else if (!strcasecmp(v->name, "notransfer")) { 09424 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09425 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09426 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09427 } else if (!strcasecmp(v->name, "transfer")) { 09428 if (!strcasecmp(v->value, "mediaonly")) { 09429 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09430 } else if (ast_true(v->value)) { 09431 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09432 } else 09433 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09434 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09435 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09436 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09437 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09438 } else if (!strcasecmp(v->name, "host")) { 09439 if (!strcasecmp(v->value, "dynamic")) { 09440 /* They'll register with us */ 09441 ast_set_flag(peer, IAX_DYNAMIC); 09442 if (!found) { 09443 /* Initialize stuff iff we're not found, otherwise 09444 we keep going with what we had */ 09445 memset(&peer->addr.sin_addr, 0, 4); 09446 if (peer->addr.sin_port) { 09447 /* If we've already got a port, make it the default rather than absolute */ 09448 peer->defaddr.sin_port = peer->addr.sin_port; 09449 peer->addr.sin_port = 0; 09450 } 09451 } 09452 } else { 09453 /* Non-dynamic. Make sure we become that way if we're not */ 09454 AST_SCHED_DEL(sched, peer->expire); 09455 ast_clear_flag(peer, IAX_DYNAMIC); 09456 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09457 return peer_unref(peer); 09458 if (!peer->addr.sin_port) 09459 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09460 } 09461 if (!maskfound) 09462 inet_aton("255.255.255.255", &peer->mask); 09463 } else if (!strcasecmp(v->name, "defaultip")) { 09464 if (ast_get_ip(&peer->defaddr, v->value)) 09465 return peer_unref(peer); 09466 } else if (!strcasecmp(v->name, "sourceaddress")) { 09467 peer_set_srcaddr(peer, v->value); 09468 } else if (!strcasecmp(v->name, "permit") || 09469 !strcasecmp(v->name, "deny")) { 09470 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09471 } else if (!strcasecmp(v->name, "mask")) { 09472 maskfound++; 09473 inet_aton(v->value, &peer->mask); 09474 } else if (!strcasecmp(v->name, "context")) { 09475 ast_string_field_set(peer, context, v->value); 09476 } else if (!strcasecmp(v->name, "regexten")) { 09477 ast_string_field_set(peer, regexten, v->value); 09478 } else if (!strcasecmp(v->name, "peercontext")) { 09479 ast_string_field_set(peer, peercontext, v->value); 09480 } else if (!strcasecmp(v->name, "port")) { 09481 if (ast_test_flag(peer, IAX_DYNAMIC)) 09482 peer->defaddr.sin_port = htons(atoi(v->value)); 09483 else 09484 peer->addr.sin_port = htons(atoi(v->value)); 09485 } else if (!strcasecmp(v->name, "username")) { 09486 ast_string_field_set(peer, username, v->value); 09487 } else if (!strcasecmp(v->name, "allow")) { 09488 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09489 } else if (!strcasecmp(v->name, "disallow")) { 09490 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09491 } else if (!strcasecmp(v->name, "callerid")) { 09492 if (!ast_strlen_zero(v->value)) { 09493 char name2[80]; 09494 char num2[80]; 09495 ast_callerid_split(v->value, name2, 80, num2, 80); 09496 ast_string_field_set(peer, cid_name, name2); 09497 ast_string_field_set(peer, cid_num, num2); 09498 ast_set_flag(peer, IAX_HASCALLERID); 09499 } else { 09500 ast_clear_flag(peer, IAX_HASCALLERID); 09501 ast_string_field_set(peer, cid_name, ""); 09502 ast_string_field_set(peer, cid_num, ""); 09503 } 09504 } else if (!strcasecmp(v->name, "fullname")) { 09505 if (!ast_strlen_zero(v->value)) { 09506 ast_string_field_set(peer, cid_name, v->value); 09507 ast_set_flag(peer, IAX_HASCALLERID); 09508 } else { 09509 ast_string_field_set(peer, cid_name, ""); 09510 if (ast_strlen_zero(peer->cid_num)) 09511 ast_clear_flag(peer, IAX_HASCALLERID); 09512 } 09513 } else if (!strcasecmp(v->name, "cid_number")) { 09514 if (!ast_strlen_zero(v->value)) { 09515 ast_string_field_set(peer, cid_num, v->value); 09516 ast_set_flag(peer, IAX_HASCALLERID); 09517 } else { 09518 ast_string_field_set(peer, cid_num, ""); 09519 if (ast_strlen_zero(peer->cid_name)) 09520 ast_clear_flag(peer, IAX_HASCALLERID); 09521 } 09522 } else if (!strcasecmp(v->name, "sendani")) { 09523 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09524 } else if (!strcasecmp(v->name, "inkeys")) { 09525 ast_string_field_set(peer, inkeys, v->value); 09526 } else if (!strcasecmp(v->name, "outkey")) { 09527 ast_string_field_set(peer, outkey, v->value); 09528 } else if (!strcasecmp(v->name, "qualify")) { 09529 if (!strcasecmp(v->value, "no")) { 09530 peer->maxms = 0; 09531 } else if (!strcasecmp(v->value, "yes")) { 09532 peer->maxms = DEFAULT_MAXMS; 09533 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09534 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); 09535 peer->maxms = 0; 09536 } 09537 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09538 peer->smoothing = ast_true(v->value); 09539 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09540 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09541 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); 09542 } 09543 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09544 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09545 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); 09546 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09547 } else if (!strcasecmp(v->name, "timezone")) { 09548 ast_string_field_set(peer, zonetag, v->value); 09549 } else if (!strcasecmp(v->name, "adsi")) { 09550 peer->adsi = ast_true(v->value); 09551 }/* else if (strcasecmp(v->name,"type")) */ 09552 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09553 v = v->next; 09554 if (!v) { 09555 v = alt; 09556 alt = NULL; 09557 } 09558 } 09559 if (!peer->authmethods) 09560 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09561 ast_clear_flag(peer, IAX_DELME); 09562 /* Make sure these are IPv4 addresses */ 09563 peer->addr.sin_family = AF_INET; 09564 } 09565 if (oldha) 09566 ast_free_ha(oldha); 09567 return peer; 09568 }
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 9584 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.
09585 { 09586 struct iax2_user *user = NULL; 09587 struct iax2_context *con, *conl = NULL; 09588 struct ast_ha *oldha = NULL; 09589 struct iax2_context *oldcon = NULL; 09590 int format; 09591 int firstpass=1; 09592 int oldcurauthreq = 0; 09593 char *varname = NULL, *varval = NULL; 09594 struct ast_variable *tmpvar = NULL; 09595 struct iax2_user tmp_user = { 09596 .name = name, 09597 }; 09598 09599 if (!temponly) { 09600 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09601 if (user && !ast_test_flag(user, IAX_DELME)) 09602 firstpass = 0; 09603 } 09604 09605 if (user) { 09606 if (firstpass) { 09607 oldcurauthreq = user->curauthreq; 09608 oldha = user->ha; 09609 oldcon = user->contexts; 09610 user->ha = NULL; 09611 user->contexts = NULL; 09612 } 09613 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09614 ao2_unlink(users, user); 09615 } else { 09616 user = ao2_alloc(sizeof(*user), user_destructor); 09617 } 09618 09619 if (user) { 09620 if (firstpass) { 09621 ast_string_field_free_memory(user); 09622 memset(user, 0, sizeof(struct iax2_user)); 09623 if (ast_string_field_init(user, 32)) { 09624 user = user_unref(user); 09625 goto cleanup; 09626 } 09627 user->maxauthreq = maxauthreq; 09628 user->curauthreq = oldcurauthreq; 09629 user->prefs = prefs; 09630 user->capability = iax2_capability; 09631 user->encmethods = iax2_encryption; 09632 user->adsi = adsi; 09633 ast_string_field_set(user, name, name); 09634 ast_string_field_set(user, language, language); 09635 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09636 ast_clear_flag(user, IAX_HASCALLERID); 09637 ast_string_field_set(user, cid_name, ""); 09638 ast_string_field_set(user, cid_num, ""); 09639 } 09640 if (!v) { 09641 v = alt; 09642 alt = NULL; 09643 } 09644 while(v) { 09645 if (!strcasecmp(v->name, "context")) { 09646 con = build_context(v->value); 09647 if (con) { 09648 if (conl) 09649 conl->next = con; 09650 else 09651 user->contexts = con; 09652 conl = con; 09653 } 09654 } else if (!strcasecmp(v->name, "permit") || 09655 !strcasecmp(v->name, "deny")) { 09656 user->ha = ast_append_ha(v->name, v->value, user->ha); 09657 } else if (!strcasecmp(v->name, "setvar")) { 09658 varname = ast_strdupa(v->value); 09659 if (varname && (varval = strchr(varname,'='))) { 09660 *varval = '\0'; 09661 varval++; 09662 if((tmpvar = ast_variable_new(varname, varval))) { 09663 tmpvar->next = user->vars; 09664 user->vars = tmpvar; 09665 } 09666 } 09667 } else if (!strcasecmp(v->name, "allow")) { 09668 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09669 } else if (!strcasecmp(v->name, "disallow")) { 09670 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09671 } else if (!strcasecmp(v->name, "trunk")) { 09672 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09673 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09674 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09675 ast_clear_flag(user, IAX_TRUNK); 09676 } 09677 } else if (!strcasecmp(v->name, "auth")) { 09678 user->authmethods = get_auth_methods(v->value); 09679 } else if (!strcasecmp(v->name, "encryption")) { 09680 user->encmethods = get_encrypt_methods(v->value); 09681 } else if (!strcasecmp(v->name, "notransfer")) { 09682 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09683 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09684 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09685 } else if (!strcasecmp(v->name, "transfer")) { 09686 if (!strcasecmp(v->value, "mediaonly")) { 09687 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09688 } else if (ast_true(v->value)) { 09689 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09690 } else 09691 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09692 } else if (!strcasecmp(v->name, "codecpriority")) { 09693 if(!strcasecmp(v->value, "caller")) 09694 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09695 else if(!strcasecmp(v->value, "disabled")) 09696 ast_set_flag(user, IAX_CODEC_NOPREFS); 09697 else if(!strcasecmp(v->value, "reqonly")) { 09698 ast_set_flag(user, IAX_CODEC_NOCAP); 09699 ast_set_flag(user, IAX_CODEC_NOPREFS); 09700 } 09701 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09702 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09703 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09704 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09705 } else if (!strcasecmp(v->name, "dbsecret")) { 09706 ast_string_field_set(user, dbsecret, v->value); 09707 } else if (!strcasecmp(v->name, "secret")) { 09708 if (!ast_strlen_zero(user->secret)) { 09709 char *old = ast_strdupa(user->secret); 09710 09711 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09712 } else 09713 ast_string_field_set(user, secret, v->value); 09714 } else if (!strcasecmp(v->name, "callerid")) { 09715 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09716 char name2[80]; 09717 char num2[80]; 09718 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09719 ast_string_field_set(user, cid_name, name2); 09720 ast_string_field_set(user, cid_num, num2); 09721 ast_set_flag(user, IAX_HASCALLERID); 09722 } else { 09723 ast_clear_flag(user, IAX_HASCALLERID); 09724 ast_string_field_set(user, cid_name, ""); 09725 ast_string_field_set(user, cid_num, ""); 09726 } 09727 } else if (!strcasecmp(v->name, "fullname")) { 09728 if (!ast_strlen_zero(v->value)) { 09729 ast_string_field_set(user, cid_name, v->value); 09730 ast_set_flag(user, IAX_HASCALLERID); 09731 } else { 09732 ast_string_field_set(user, cid_name, ""); 09733 if (ast_strlen_zero(user->cid_num)) 09734 ast_clear_flag(user, IAX_HASCALLERID); 09735 } 09736 } else if (!strcasecmp(v->name, "cid_number")) { 09737 if (!ast_strlen_zero(v->value)) { 09738 ast_string_field_set(user, cid_num, v->value); 09739 ast_set_flag(user, IAX_HASCALLERID); 09740 } else { 09741 ast_string_field_set(user, cid_num, ""); 09742 if (ast_strlen_zero(user->cid_name)) 09743 ast_clear_flag(user, IAX_HASCALLERID); 09744 } 09745 } else if (!strcasecmp(v->name, "accountcode")) { 09746 ast_string_field_set(user, accountcode, v->value); 09747 } else if (!strcasecmp(v->name, "mohinterpret")) { 09748 ast_string_field_set(user, mohinterpret, v->value); 09749 } else if (!strcasecmp(v->name, "mohsuggest")) { 09750 ast_string_field_set(user, mohsuggest, v->value); 09751 } else if (!strcasecmp(v->name, "language")) { 09752 ast_string_field_set(user, language, v->value); 09753 } else if (!strcasecmp(v->name, "amaflags")) { 09754 format = ast_cdr_amaflags2int(v->value); 09755 if (format < 0) { 09756 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09757 } else { 09758 user->amaflags = format; 09759 } 09760 } else if (!strcasecmp(v->name, "inkeys")) { 09761 ast_string_field_set(user, inkeys, v->value); 09762 } else if (!strcasecmp(v->name, "maxauthreq")) { 09763 user->maxauthreq = atoi(v->value); 09764 if (user->maxauthreq < 0) 09765 user->maxauthreq = 0; 09766 } else if (!strcasecmp(v->name, "adsi")) { 09767 user->adsi = ast_true(v->value); 09768 }/* else if (strcasecmp(v->name,"type")) */ 09769 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09770 v = v->next; 09771 if (!v) { 09772 v = alt; 09773 alt = NULL; 09774 } 09775 } 09776 if (!user->authmethods) { 09777 if (!ast_strlen_zero(user->secret)) { 09778 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09779 if (!ast_strlen_zero(user->inkeys)) 09780 user->authmethods |= IAX_AUTH_RSA; 09781 } else if (!ast_strlen_zero(user->inkeys)) { 09782 user->authmethods = IAX_AUTH_RSA; 09783 } else { 09784 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09785 } 09786 } 09787 ast_clear_flag(user, IAX_DELME); 09788 } 09789 cleanup: 09790 if (oldha) 09791 ast_free_ha(oldha); 09792 if (oldcon) 09793 free_context(oldcon); 09794 return user; 09795 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10300 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().
10301 { 10302 struct sockaddr_in sin; 10303 int x; 10304 int callno; 10305 struct iax_ie_data ied; 10306 struct create_addr_info cai; 10307 struct parsed_dial_string pds; 10308 char *tmpstr; 10309 10310 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10311 /* Look for an *exact match* call. Once a call is negotiated, it can only 10312 look up entries for a single context */ 10313 if (!ast_mutex_trylock(&iaxsl[x])) { 10314 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10315 return x; 10316 ast_mutex_unlock(&iaxsl[x]); 10317 } 10318 } 10319 10320 /* No match found, we need to create a new one */ 10321 10322 memset(&cai, 0, sizeof(cai)); 10323 memset(&ied, 0, sizeof(ied)); 10324 memset(&pds, 0, sizeof(pds)); 10325 10326 tmpstr = ast_strdupa(data); 10327 parse_dial_string(tmpstr, &pds); 10328 10329 if (ast_strlen_zero(pds.peer)) { 10330 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10331 return -1; 10332 } 10333 10334 /* Populate our address from the given */ 10335 if (create_addr(pds.peer, NULL, &sin, &cai)) 10336 return -1; 10337 10338 if (option_debug) 10339 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10340 pds.peer, pds.username, pds.password, pds.context); 10341 10342 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10343 if (callno < 1) { 10344 ast_log(LOG_WARNING, "Unable to create call\n"); 10345 return -1; 10346 } 10347 10348 ast_string_field_set(iaxs[callno], dproot, data); 10349 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10350 10351 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10352 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10353 /* the string format is slightly different from a standard dial string, 10354 because the context appears in the 'exten' position 10355 */ 10356 if (pds.exten) 10357 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10358 if (pds.username) 10359 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10360 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10361 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10362 /* Keep password handy */ 10363 if (pds.password) 10364 ast_string_field_set(iaxs[callno], secret, pds.password); 10365 if (pds.key) 10366 ast_string_field_set(iaxs[callno], outkey, pds.key); 10367 /* Start the call going */ 10368 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10369 10370 return callno; 10371 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3974 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.
03975 { 03976 /* Returns where in "receive time" we are. That is, how many ms 03977 since we received (or would have received) the frame with timestamp 0 */ 03978 int ms; 03979 #ifdef IAXTESTS 03980 int jit; 03981 #endif /* IAXTESTS */ 03982 /* Setup rxcore if necessary */ 03983 if (ast_tvzero(p->rxcore)) { 03984 p->rxcore = ast_tvnow(); 03985 if (option_debug && iaxdebug) 03986 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03987 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03988 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03989 #if 1 03990 if (option_debug && iaxdebug) 03991 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03992 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03993 #endif 03994 } 03995 03996 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03997 #ifdef IAXTESTS 03998 if (test_jit) { 03999 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04000 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04001 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04002 jit = -jit; 04003 ms += jit; 04004 } 04005 } 04006 if (test_late) { 04007 ms += test_late; 04008 test_late = 0; 04009 } 04010 #endif /* IAXTESTS */ 04011 return ms; 04012 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3845 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().
03846 { 03847 int ms; 03848 int voice = 0; 03849 int genuine = 0; 03850 int adjust; 03851 struct timeval *delivery = NULL; 03852 03853 03854 /* What sort of frame do we have?: voice is self-explanatory 03855 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03856 non-genuine frames are CONTROL frames [ringing etc], DTMF 03857 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03858 the others need a timestamp slaved to the voice frames so that they go in sequence 03859 */ 03860 if (f) { 03861 if (f->frametype == AST_FRAME_VOICE) { 03862 voice = 1; 03863 delivery = &f->delivery; 03864 } else if (f->frametype == AST_FRAME_IAX) { 03865 genuine = 1; 03866 } else if (f->frametype == AST_FRAME_CNG) { 03867 p->notsilenttx = 0; 03868 } 03869 } 03870 if (ast_tvzero(p->offset)) { 03871 gettimeofday(&p->offset, NULL); 03872 /* Round to nearest 20ms for nice looking traces */ 03873 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03874 } 03875 /* If the timestamp is specified, just send it as is */ 03876 if (ts) 03877 return ts; 03878 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03879 if (delivery && !ast_tvzero(*delivery)) { 03880 ms = ast_tvdiff_ms(*delivery, p->offset); 03881 if (option_debug > 2 && iaxdebug) 03882 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03883 } else { 03884 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03885 if (ms < 0) 03886 ms = 0; 03887 if (voice) { 03888 /* On a voice frame, use predicted values if appropriate */ 03889 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03890 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03891 /* AN EXPLANATION: 03892 When we send voice, we usually send "calculated" timestamps worked out 03893 on the basis of the number of samples sent. When we send other frames, 03894 we usually send timestamps worked out from the real clock. 03895 The problem is that they can tend to drift out of step because the 03896 source channel's clock and our clock may not be exactly at the same rate. 03897 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03898 for this call. Moving it adjusts timestamps for non-voice frames. 03899 We make the adjustment in the style of a moving average. Each time we 03900 adjust p->offset by 10% of the difference between our clock-derived 03901 timestamp and the predicted timestamp. That's why you see "10000" 03902 below even though IAX2 timestamps are in milliseconds. 03903 The use of a moving average avoids offset moving too radically. 03904 Generally, "adjust" roams back and forth around 0, with offset hardly 03905 changing at all. But if a consistent different starts to develop it 03906 will be eliminated over the course of 10 frames (200-300msecs) 03907 */ 03908 adjust = (ms - p->nextpred); 03909 if (adjust < 0) 03910 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03911 else if (adjust > 0) 03912 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03913 03914 if (!p->nextpred) { 03915 p->nextpred = ms; /*f->samples / 8;*/ 03916 if (p->nextpred <= p->lastsent) 03917 p->nextpred = p->lastsent + 3; 03918 } 03919 ms = p->nextpred; 03920 } else { 03921 /* in this case, just use the actual 03922 * time, since we're either way off 03923 * (shouldn't happen), or we're ending a 03924 * silent period -- and seed the next 03925 * predicted time. Also, round ms to the 03926 * next multiple of frame size (so our 03927 * silent periods are multiples of 03928 * frame size too) */ 03929 03930 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03931 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03932 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03933 03934 if (f->samples >= 8) /* check to make sure we dont core dump */ 03935 { 03936 int diff = ms % (f->samples / 8); 03937 if (diff) 03938 ms += f->samples/8 - diff; 03939 } 03940 03941 p->nextpred = ms; 03942 p->notsilenttx = 1; 03943 } 03944 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03945 /* 03946 * IAX2 draft 03 says that timestamps MUST be in order. 03947 * It does not say anything about several frames having the same timestamp 03948 * When transporting video, we can have a frame that spans multiple iax packets 03949 * (so called slices), so it would make sense to use the same timestamp for all of 03950 * them 03951 * We do want to make sure that frames don't go backwards though 03952 */ 03953 if ( (unsigned int)ms < p->lastsent ) 03954 ms = p->lastsent; 03955 } else { 03956 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03957 it's a genuine frame */ 03958 if (genuine) { 03959 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03960 if (ms <= p->lastsent) 03961 ms = p->lastsent + 3; 03962 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03963 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03964 ms = p->lastsent + 3; 03965 } 03966 } 03967 } 03968 p->lastsent = ms; 03969 if (voice) 03970 p->nextpred = p->nextpred + f->samples / 8; 03971 return ms; 03972 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3801 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().
03802 { 03803 unsigned long int mssincetx; /* unsigned to handle overflows */ 03804 long int ms, pred; 03805 03806 tpeer->trunkact = *tv; 03807 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03808 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03809 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03810 tpeer->txtrunktime = *tv; 03811 tpeer->lastsent = 999999; 03812 } 03813 /* Update last transmit time now */ 03814 tpeer->lasttxtime = *tv; 03815 03816 /* Calculate ms offset */ 03817 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03818 /* Predict from last value */ 03819 pred = tpeer->lastsent + sampms; 03820 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03821 ms = pred; 03822 03823 /* We never send the same timestamp twice, so fudge a little if we must */ 03824 if (ms == tpeer->lastsent) 03825 ms = tpeer->lastsent + 1; 03826 tpeer->lastsent = ms; 03827 return ms; 03828 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5085 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().
05086 { 05087 /* Start pessimistic */ 05088 int res = -1; 05089 int version = 2; 05090 struct iax2_user *user = NULL, *best = NULL; 05091 int bestscore = 0; 05092 int gotcapability = 0; 05093 struct ast_variable *v = NULL, *tmpvar = NULL; 05094 struct ao2_iterator i; 05095 05096 if (!iaxs[callno]) 05097 return res; 05098 if (ies->called_number) 05099 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05100 if (ies->calling_number) { 05101 ast_shrink_phone_number(ies->calling_number); 05102 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05103 } 05104 if (ies->calling_name) 05105 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05106 if (ies->calling_ani) 05107 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05108 if (ies->dnid) 05109 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05110 if (ies->rdnis) 05111 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05112 if (ies->called_context) 05113 ast_string_field_set(iaxs[callno], context, ies->called_context); 05114 if (ies->language) 05115 ast_string_field_set(iaxs[callno], language, ies->language); 05116 if (ies->username) 05117 ast_string_field_set(iaxs[callno], username, ies->username); 05118 if (ies->calling_ton > -1) 05119 iaxs[callno]->calling_ton = ies->calling_ton; 05120 if (ies->calling_tns > -1) 05121 iaxs[callno]->calling_tns = ies->calling_tns; 05122 if (ies->calling_pres > -1) 05123 iaxs[callno]->calling_pres = ies->calling_pres; 05124 if (ies->format) 05125 iaxs[callno]->peerformat = ies->format; 05126 if (ies->adsicpe) 05127 iaxs[callno]->peeradsicpe = ies->adsicpe; 05128 if (ies->capability) { 05129 gotcapability = 1; 05130 iaxs[callno]->peercapability = ies->capability; 05131 } 05132 if (ies->version) 05133 version = ies->version; 05134 05135 /* Use provided preferences until told otherwise for actual preferences */ 05136 if(ies->codec_prefs) { 05137 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05138 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05139 } 05140 05141 if (!gotcapability) 05142 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05143 if (version > IAX_PROTO_VERSION) { 05144 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05145 ast_inet_ntoa(sin->sin_addr), version); 05146 return res; 05147 } 05148 /* Search the userlist for a compatible entry, and fill in the rest */ 05149 i = ao2_iterator_init(users, 0); 05150 while ((user = ao2_iterator_next(&i))) { 05151 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05152 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05153 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05154 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05155 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05156 if (!ast_strlen_zero(iaxs[callno]->username)) { 05157 /* Exact match, stop right now. */ 05158 if (best) 05159 user_unref(best); 05160 best = user; 05161 break; 05162 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05163 /* No required authentication */ 05164 if (user->ha) { 05165 /* There was host authentication and we passed, bonus! */ 05166 if (bestscore < 4) { 05167 bestscore = 4; 05168 if (best) 05169 user_unref(best); 05170 best = user; 05171 continue; 05172 } 05173 } else { 05174 /* No host access, but no secret, either, not bad */ 05175 if (bestscore < 3) { 05176 bestscore = 3; 05177 if (best) 05178 user_unref(best); 05179 best = user; 05180 continue; 05181 } 05182 } 05183 } else { 05184 if (user->ha) { 05185 /* Authentication, but host access too, eh, it's something.. */ 05186 if (bestscore < 2) { 05187 bestscore = 2; 05188 if (best) 05189 user_unref(best); 05190 best = user; 05191 continue; 05192 } 05193 } else { 05194 /* Authentication and no host access... This is our baseline */ 05195 if (bestscore < 1) { 05196 bestscore = 1; 05197 if (best) 05198 user_unref(best); 05199 best = user; 05200 continue; 05201 } 05202 } 05203 } 05204 } 05205 user_unref(user); 05206 } 05207 user = best; 05208 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05209 user = realtime_user(iaxs[callno]->username, sin); 05210 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05211 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05212 user = user_unref(user); 05213 } 05214 } 05215 if (user) { 05216 /* We found our match (use the first) */ 05217 /* copy vars */ 05218 for (v = user->vars ; v ; v = v->next) { 05219 if((tmpvar = ast_variable_new(v->name, v->value))) { 05220 tmpvar->next = iaxs[callno]->vars; 05221 iaxs[callno]->vars = tmpvar; 05222 } 05223 } 05224 /* If a max AUTHREQ restriction is in place, activate it */ 05225 if (user->maxauthreq > 0) 05226 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05227 iaxs[callno]->prefs = user->prefs; 05228 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05229 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05230 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05231 iaxs[callno]->encmethods = user->encmethods; 05232 /* Store the requested username if not specified */ 05233 if (ast_strlen_zero(iaxs[callno]->username)) 05234 ast_string_field_set(iaxs[callno], username, user->name); 05235 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05236 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05237 iaxs[callno]->capability = user->capability; 05238 /* And use the default context */ 05239 if (ast_strlen_zero(iaxs[callno]->context)) { 05240 if (user->contexts) 05241 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05242 else 05243 ast_string_field_set(iaxs[callno], context, context); 05244 } 05245 /* And any input keys */ 05246 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05247 /* And the permitted authentication methods */ 05248 iaxs[callno]->authmethods = user->authmethods; 05249 iaxs[callno]->adsi = user->adsi; 05250 /* If they have callerid, override the given caller id. Always store the ANI */ 05251 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05252 if (ast_test_flag(user, IAX_HASCALLERID)) { 05253 iaxs[callno]->calling_tns = 0; 05254 iaxs[callno]->calling_ton = 0; 05255 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05256 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05257 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05258 } 05259 if (ast_strlen_zero(iaxs[callno]->ani)) 05260 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05261 } else { 05262 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05263 } 05264 if (!ast_strlen_zero(user->accountcode)) 05265 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05266 if (!ast_strlen_zero(user->mohinterpret)) 05267 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05268 if (!ast_strlen_zero(user->mohsuggest)) 05269 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05270 if (user->amaflags) 05271 iaxs[callno]->amaflags = user->amaflags; 05272 if (!ast_strlen_zero(user->language)) 05273 ast_string_field_set(iaxs[callno], language, user->language); 05274 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05275 /* Keep this check last */ 05276 if (!ast_strlen_zero(user->dbsecret)) { 05277 char *family, *key=NULL; 05278 char buf[80]; 05279 family = ast_strdupa(user->dbsecret); 05280 key = strchr(family, '/'); 05281 if (key) { 05282 *key = '\0'; 05283 key++; 05284 } 05285 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05286 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05287 else 05288 ast_string_field_set(iaxs[callno], secret, buf); 05289 } else 05290 ast_string_field_set(iaxs[callno], secret, user->secret); 05291 res = 0; 05292 user = user_unref(user); 05293 } else { 05294 /* user was not found, but we should still fake an AUTHREQ. 05295 * Set authmethods to the last known authmethod used by the system 05296 * Set a fake secret, it's not looked at, just required to attempt authentication. 05297 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 05298 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 05299 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05300 iaxs[callno]->authrej = 1; 05301 if (!ast_strlen_zero(iaxs[callno]->username)) { 05302 /* only send the AUTHREQ if a username was specified. */ 05303 res = 0; 05304 } 05305 } 05306 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05307 return res; 05308 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6815 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.
Referenced by socket_process().
06816 { 06817 unsigned int ourver; 06818 char rsi[80]; 06819 snprintf(rsi, sizeof(rsi), "si-%s", si); 06820 if (iax_provision_version(&ourver, rsi, 1)) 06821 return 0; 06822 if (option_debug) 06823 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06824 if (ourver != ver) 06825 iax2_provision(sin, sockfd, NULL, rsi, 1); 06826 return 0; 06827 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9223 of file chan_iax2.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09224 { 09225 int sd; 09226 int res; 09227 09228 sd = socket(AF_INET, SOCK_DGRAM, 0); 09229 if (sd < 0) { 09230 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09231 return -1; 09232 } 09233 09234 res = bind(sd, sa, salen); 09235 if (res < 0) { 09236 if (option_debug) 09237 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09238 close(sd); 09239 return 1; 09240 } 09241 09242 close(sd); 09243 return 0; 09244 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5810 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().
05811 { 05812 char exten[256] = ""; 05813 int status = CACHE_FLAG_UNKNOWN; 05814 int expiry = iaxdefaultdpcache; 05815 int x; 05816 int matchmore = 0; 05817 struct iax2_dpcache *dp, *prev; 05818 05819 if (ies->called_number) 05820 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05821 05822 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05823 status = CACHE_FLAG_EXISTS; 05824 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05825 status = CACHE_FLAG_CANEXIST; 05826 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05827 status = CACHE_FLAG_NONEXISTENT; 05828 05829 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05830 /* Don't really do anything with this */ 05831 } 05832 if (ies->refresh) 05833 expiry = ies->refresh; 05834 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05835 matchmore = CACHE_FLAG_MATCHMORE; 05836 ast_mutex_lock(&dpcache_lock); 05837 prev = NULL; 05838 dp = pvt->dpentries; 05839 while(dp) { 05840 if (!strcmp(dp->exten, exten)) { 05841 /* Let them go */ 05842 if (prev) 05843 prev->peer = dp->peer; 05844 else 05845 pvt->dpentries = dp->peer; 05846 dp->peer = NULL; 05847 dp->callno = 0; 05848 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05849 if (dp->flags & CACHE_FLAG_PENDING) { 05850 dp->flags &= ~CACHE_FLAG_PENDING; 05851 dp->flags |= status; 05852 dp->flags |= matchmore; 05853 } 05854 /* Wake up waiters */ 05855 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05856 if (dp->waiters[x] > -1) 05857 write(dp->waiters[x], "asdf", 4); 05858 } 05859 prev = dp; 05860 dp = dp->peer; 05861 } 05862 ast_mutex_unlock(&dpcache_lock); 05863 return 0; 05864 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2393 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02394 { 02395 int which = 0; 02396 struct iax2_peer *peer; 02397 char *res = NULL; 02398 int wordlen = strlen(word); 02399 struct ao2_iterator i; 02400 02401 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02402 if (pos != 3) 02403 return NULL; 02404 02405 i = ao2_iterator_init(peers, 0); 02406 while ((peer = ao2_iterator_next(&i))) { 02407 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02408 res = ast_strdup(peer->name); 02409 peer_unref(peer); 02410 break; 02411 } 02412 peer_unref(peer); 02413 } 02414 02415 return res; 02416 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5866 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().
05867 { 05868 int peercallno = 0; 05869 struct chan_iax2_pvt *pvt = iaxs[callno]; 05870 struct iax_frame *cur; 05871 jb_frame frame; 05872 05873 if (ies->callno) 05874 peercallno = ies->callno; 05875 05876 if (peercallno < 1) { 05877 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05878 return -1; 05879 } 05880 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05881 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05882 /* Reset sequence numbers */ 05883 pvt->oseqno = 0; 05884 pvt->rseqno = 0; 05885 pvt->iseqno = 0; 05886 pvt->aseqno = 0; 05887 05888 if (pvt->peercallno) { 05889 remove_by_peercallno(pvt); 05890 } 05891 pvt->peercallno = peercallno; 05892 store_by_peercallno(pvt); 05893 05894 pvt->transferring = TRANSFER_NONE; 05895 pvt->svoiceformat = -1; 05896 pvt->voiceformat = 0; 05897 pvt->svideoformat = -1; 05898 pvt->videoformat = 0; 05899 pvt->transfercallno = -1; 05900 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05901 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05902 /* reset jitterbuffer */ 05903 while(jb_getall(pvt->jb,&frame) == JB_OK) 05904 iax2_frame_free(frame.data); 05905 jb_reset(pvt->jb); 05906 pvt->lag = 0; 05907 pvt->last = 0; 05908 pvt->lastsent = 0; 05909 pvt->nextpred = 0; 05910 pvt->pingtime = DEFAULT_RETRY_TIME; 05911 AST_LIST_LOCK(&iaxq.queue); 05912 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05913 /* We must cancel any packets that would have been transmitted 05914 because now we're talking to someone new. It's okay, they 05915 were transmitted to someone that didn't care anyway. */ 05916 if (callno == cur->callno) 05917 cur->retries = -1; 05918 } 05919 AST_LIST_UNLOCK(&iaxq.queue); 05920 return 0; 05921 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1065 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01066 { 01067 int x; 01068 int power=-1; 01069 /* If it's 128 or smaller, just return it */ 01070 if (subclass < IAX_FLAG_SC_LOG) 01071 return subclass; 01072 /* Otherwise find its power */ 01073 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01074 if (subclass & (1 << x)) { 01075 if (power > -1) { 01076 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01077 return 0; 01078 } else 01079 power = x; 01080 } 01081 } 01082 return power | IAX_FLAG_SC_LOG; 01083 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6829 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().
06830 { 06831 jb_info stats; 06832 jb_getinfo(pvt->jb, &stats); 06833 06834 memset(iep, 0, sizeof(*iep)); 06835 06836 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06837 if(stats.frames_in == 0) stats.frames_in = 1; 06838 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06839 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06840 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06841 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06842 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06843 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3010 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_DEBUG, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
03011 { 03012 struct ast_hostent ahp; 03013 struct hostent *hp; 03014 struct iax2_peer *peer; 03015 int res = -1; 03016 struct ast_codec_pref ourprefs; 03017 03018 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03019 cai->sockfd = defaultsockfd; 03020 cai->maxtime = 0; 03021 sin->sin_family = AF_INET; 03022 03023 if (!(peer = find_peer(peername, 1))) { 03024 cai->found = 0; 03025 03026 hp = ast_gethostbyname(peername, &ahp); 03027 if (hp) { 03028 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03029 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03030 /* use global iax prefs for unknown peer/user */ 03031 /* But move the calling channel's native codec to the top of the preference list */ 03032 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03033 if (c) 03034 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03035 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03036 return 0; 03037 } else { 03038 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03039 return -1; 03040 } 03041 } 03042 03043 cai->found = 1; 03044 03045 /* if the peer has no address (current or default), return failure */ 03046 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03047 goto return_unref; 03048 03049 /* if the peer is being monitored and is currently unreachable, return failure */ 03050 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03051 goto return_unref; 03052 03053 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03054 cai->maxtime = peer->maxms; 03055 cai->capability = peer->capability; 03056 cai->encmethods = peer->encmethods; 03057 cai->sockfd = peer->sockfd; 03058 cai->adsi = peer->adsi; 03059 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03060 /* Move the calling channel's native codec to the top of the preference list */ 03061 if (c) { 03062 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03063 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03064 } 03065 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03066 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03067 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03068 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03069 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03070 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03071 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03072 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03073 if (ast_strlen_zero(peer->dbsecret)) { 03074 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03075 } else { 03076 char *family; 03077 char *key = NULL; 03078 03079 family = ast_strdupa(peer->dbsecret); 03080 key = strchr(family, '/'); 03081 if (key) 03082 *key++ = '\0'; 03083 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03084 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03085 goto return_unref; 03086 } 03087 } 03088 03089 if (peer->addr.sin_addr.s_addr) { 03090 sin->sin_addr = peer->addr.sin_addr; 03091 sin->sin_port = peer->addr.sin_port; 03092 } else { 03093 sin->sin_addr = peer->defaddr.sin_addr; 03094 sin->sin_port = peer->defaddr.sin_port; 03095 } 03096 03097 res = 0; 03098 03099 return_unref: 03100 peer_unref(peer); 03101 03102 return res; 03103 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4160 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().
04161 { 04162 int padding; 04163 unsigned char *workspace; 04164 04165 workspace = alloca(*datalen); 04166 memset(f, 0, sizeof(*f)); 04167 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04168 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04169 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04170 return -1; 04171 /* Decrypt */ 04172 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04173 04174 padding = 16 + (workspace[15] & 0xf); 04175 if (option_debug && iaxdebug) 04176 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04177 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04178 return -1; 04179 04180 *datalen -= padding; 04181 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04182 f->frametype = fh->type; 04183 if (f->frametype == AST_FRAME_VIDEO) { 04184 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04185 } else { 04186 f->subclass = uncompress_subclass(fh->csub); 04187 } 04188 } else { 04189 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04190 if (option_debug && iaxdebug) 04191 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04192 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04193 return -1; 04194 /* Decrypt */ 04195 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04196 padding = 16 + (workspace[15] & 0x0f); 04197 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04198 return -1; 04199 *datalen -= padding; 04200 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04201 } 04202 return 0; 04203 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4246 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), iax2_registry::secret, and strsep().
Referenced by socket_process().
04247 { 04248 int res=-1; 04249 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04250 /* Search for possible keys, given secrets */ 04251 struct MD5Context md5; 04252 unsigned char digest[16]; 04253 char *tmppw, *stringp; 04254 04255 tmppw = ast_strdupa(iaxs[callno]->secret); 04256 stringp = tmppw; 04257 while ((tmppw = strsep(&stringp, ";"))) { 04258 MD5Init(&md5); 04259 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04260 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04261 MD5Final(digest, &md5); 04262 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04263 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04264 if (!res) { 04265 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04266 break; 04267 } 04268 } 04269 } else 04270 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04271 return res; 04272 }
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 6891 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().
06892 { 06893 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06894 struct ast_iax2_full_hdr *fh, *cur_fh; 06895 06896 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06897 return; 06898 06899 pkt_buf->len = from_here->buf_len; 06900 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06901 06902 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06903 ast_mutex_lock(&to_here->lock); 06904 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06905 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06906 if (fh->oseqno < cur_fh->oseqno) { 06907 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06908 break; 06909 } 06910 } 06911 AST_LIST_TRAVERSE_SAFE_END 06912 06913 if (!cur_pkt_buf) 06914 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06915 06916 ast_mutex_unlock(&to_here->lock); 06917 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9815 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.
09816 { 09817 struct iax2_registry *reg; 09818 09819 ao2_callback(users, 0, user_delme_cb, NULL); 09820 09821 AST_LIST_LOCK(®istrations); 09822 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09823 ast_sched_del(sched, reg->expire); 09824 if (reg->callno) { 09825 ast_mutex_lock(&iaxsl[reg->callno]); 09826 if (iaxs[reg->callno]) { 09827 iaxs[reg->callno]->reg = NULL; 09828 iax2_destroy(reg->callno); 09829 } 09830 ast_mutex_unlock(&iaxsl[reg->callno]); 09831 } 09832 if (reg->dnsmgr) 09833 ast_dnsmgr_release(reg->dnsmgr); 09834 free(reg); 09835 } 09836 AST_LIST_UNLOCK(®istrations); 09837 09838 ao2_callback(peers, 0, peer_delme_cb, NULL); 09839 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1744 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01745 { 01746 /* Close firmware */ 01747 if (cur->fwh) { 01748 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01749 } 01750 close(cur->fd); 01751 free(cur); 01752 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6663 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().
06664 { 06665 unsigned short dpstatus = 0; 06666 struct iax_ie_data ied1; 06667 int mm; 06668 06669 memset(&ied1, 0, sizeof(ied1)); 06670 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06671 /* Must be started */ 06672 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06673 dpstatus = IAX_DPSTATUS_EXISTS; 06674 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06675 dpstatus = IAX_DPSTATUS_CANEXIST; 06676 } else { 06677 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06678 } 06679 if (ast_ignore_pattern(context, callednum)) 06680 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06681 if (mm) 06682 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06683 if (!skiplock) 06684 ast_mutex_lock(&iaxsl[callno]); 06685 if (iaxs[callno]) { 06686 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06687 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06688 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06689 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06690 } 06691 if (!skiplock) 06692 ast_mutex_unlock(&iaxsl[callno]); 06693 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6695 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().
06696 { 06697 /* Look up for dpreq */ 06698 struct dpreq_data *dpr = data; 06699 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06700 if (dpr->callerid) 06701 free(dpr->callerid); 06702 free(dpr); 06703 return NULL; 06704 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4205 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().
04206 { 04207 int padding; 04208 unsigned char *workspace; 04209 workspace = alloca(*datalen + 32); 04210 if (!workspace) 04211 return -1; 04212 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04213 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04214 if (option_debug && iaxdebug) 04215 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04216 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04217 padding = 16 + (padding & 0xf); 04218 memcpy(workspace, poo, padding); 04219 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04220 workspace[15] &= 0xf0; 04221 workspace[15] |= (padding & 0xf); 04222 if (option_debug && iaxdebug) 04223 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]); 04224 *datalen += padding; 04225 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04226 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04227 memcpy(poo, workspace + *datalen - 32, 32); 04228 } else { 04229 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04230 if (option_debug && iaxdebug) 04231 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04232 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04233 padding = 16 + (padding & 0xf); 04234 memcpy(workspace, poo, padding); 04235 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04236 workspace[15] &= 0xf0; 04237 workspace[15] |= (padding & 0x0f); 04238 *datalen += padding; 04239 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04240 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04241 memcpy(poo, workspace + *datalen - 32, 32); 04242 } 04243 return 0; 04244 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6103 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
06104 { 06105 #ifdef SCHED_MULTITHREADED 06106 if (schedule_action(__expire_registry, data)) 06107 #endif 06108 __expire_registry(data); 06109 return 0; 06110 }
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 10373 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().
10374 { 10375 struct iax2_dpcache *dp, *prev = NULL, *next; 10376 struct timeval tv; 10377 int x; 10378 int com[2]; 10379 int timeout; 10380 int old=0; 10381 int outfd; 10382 int abort; 10383 int callno; 10384 struct ast_channel *c; 10385 struct ast_frame *f; 10386 gettimeofday(&tv, NULL); 10387 dp = dpcache; 10388 while(dp) { 10389 next = dp->next; 10390 /* Expire old caches */ 10391 if (ast_tvcmp(tv, dp->expiry) > 0) { 10392 /* It's expired, let it disappear */ 10393 if (prev) 10394 prev->next = dp->next; 10395 else 10396 dpcache = dp->next; 10397 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10398 /* Free memory and go again */ 10399 free(dp); 10400 } else { 10401 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); 10402 } 10403 dp = next; 10404 continue; 10405 } 10406 /* We found an entry that matches us! */ 10407 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10408 break; 10409 prev = dp; 10410 dp = next; 10411 } 10412 if (!dp) { 10413 /* No matching entry. Create a new one. */ 10414 /* First, can we make a callno? */ 10415 callno = cache_get_callno_locked(data); 10416 if (callno < 0) { 10417 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10418 return NULL; 10419 } 10420 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10421 ast_mutex_unlock(&iaxsl[callno]); 10422 return NULL; 10423 } 10424 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10425 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10426 gettimeofday(&dp->expiry, NULL); 10427 dp->orig = dp->expiry; 10428 /* Expires in 30 mins by default */ 10429 dp->expiry.tv_sec += iaxdefaultdpcache; 10430 dp->next = dpcache; 10431 dp->flags = CACHE_FLAG_PENDING; 10432 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10433 dp->waiters[x] = -1; 10434 dpcache = dp; 10435 dp->peer = iaxs[callno]->dpentries; 10436 iaxs[callno]->dpentries = dp; 10437 /* Send the request if we're already up */ 10438 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10439 iax2_dprequest(dp, callno); 10440 ast_mutex_unlock(&iaxsl[callno]); 10441 } 10442 /* By here we must have a dp */ 10443 if (dp->flags & CACHE_FLAG_PENDING) { 10444 /* Okay, here it starts to get nasty. We need a pipe now to wait 10445 for a reply to come back so long as it's pending */ 10446 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10447 /* Find an empty slot */ 10448 if (dp->waiters[x] < 0) 10449 break; 10450 } 10451 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10452 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10453 return NULL; 10454 } 10455 if (pipe(com)) { 10456 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10457 return NULL; 10458 } 10459 dp->waiters[x] = com[1]; 10460 /* Okay, now we wait */ 10461 timeout = iaxdefaulttimeout * 1000; 10462 /* Temporarily unlock */ 10463 ast_mutex_unlock(&dpcache_lock); 10464 /* Defer any dtmf */ 10465 if (chan) 10466 old = ast_channel_defer_dtmf(chan); 10467 abort = 0; 10468 while(timeout) { 10469 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10470 if (outfd > -1) { 10471 break; 10472 } 10473 if (c) { 10474 f = ast_read(c); 10475 if (f) 10476 ast_frfree(f); 10477 else { 10478 /* Got hung up on, abort! */ 10479 break; 10480 abort = 1; 10481 } 10482 } 10483 } 10484 if (!timeout) { 10485 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10486 } 10487 ast_mutex_lock(&dpcache_lock); 10488 dp->waiters[x] = -1; 10489 close(com[1]); 10490 close(com[0]); 10491 if (abort) { 10492 /* Don't interpret anything, just abort. Not sure what th epoint 10493 of undeferring dtmf on a hung up channel is but hey whatever */ 10494 if (!old && chan) 10495 ast_channel_undefer_dtmf(chan); 10496 return NULL; 10497 } 10498 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10499 /* Now to do non-independent analysis the results of our wait */ 10500 if (dp->flags & CACHE_FLAG_PENDING) { 10501 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10502 pending. Don't let it take as long to timeout. */ 10503 dp->flags &= ~CACHE_FLAG_PENDING; 10504 dp->flags |= CACHE_FLAG_TIMEOUT; 10505 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10506 systems without leaving it unavailable once the server comes back online */ 10507 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10508 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10509 if (dp->waiters[x] > -1) 10510 write(dp->waiters[x], "asdf", 4); 10511 } 10512 } 10513 /* Our caller will obtain the rest */ 10514 if (!old && chan) 10515 ast_channel_undefer_dtmf(chan); 10516 } 10517 return dp; 10518 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1644 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01644 { 01645 01646 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01647 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1649 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01649 { 01650 01651 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01652 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 910 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, iax2_thread::ffinfo, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00911 { 00912 pthread_attr_t attr; 00913 struct iax2_thread *thread = NULL; 00914 00915 /* Pop the head of the list off */ 00916 AST_LIST_LOCK(&idle_list); 00917 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00918 AST_LIST_UNLOCK(&idle_list); 00919 00920 /* If no idle thread is available from the regular list, try dynamic */ 00921 if (thread == NULL) { 00922 AST_LIST_LOCK(&dynamic_list); 00923 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00924 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00925 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00926 /* We need to MAKE a thread! */ 00927 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00928 thread->threadnum = iaxdynamicthreadcount; 00929 thread->type = IAX_TYPE_DYNAMIC; 00930 ast_mutex_init(&thread->lock); 00931 ast_cond_init(&thread->cond, NULL); 00932 pthread_attr_init(&attr); 00933 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00934 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00935 free(thread); 00936 thread = NULL; 00937 } else { 00938 /* All went well and the thread is up, so increment our count */ 00939 iaxdynamicthreadcount++; 00940 00941 /* Wait for the thread to be ready before returning it to the caller */ 00942 while (!thread->ready_for_signal) 00943 usleep(1); 00944 } 00945 } 00946 } 00947 AST_LIST_UNLOCK(&dynamic_list); 00948 } 00949 00950 /* this thread is not processing a full frame (since it is idle), 00951 so ensure that the field for the full frame call number is empty */ 00952 if (thread) 00953 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00954 00955 return thread; 00956 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1143 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01144 { 01145 struct iax2_peer *peer = NULL; 01146 struct iax2_peer tmp_peer = { 01147 .name = name, 01148 }; 01149 01150 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01151 01152 /* Now go for realtime if applicable */ 01153 if(!peer && realtime) 01154 peer = realtime_peer(name, NULL); 01155 01156 return peer; 01157 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 4014 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().
04015 { 04016 struct iax2_trunk_peer *tpeer; 04017 04018 /* Finds and locks trunk peer */ 04019 ast_mutex_lock(&tpeerlock); 04020 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04021 /* We don't lock here because tpeer->addr *never* changes */ 04022 if (!inaddrcmp(&tpeer->addr, sin)) { 04023 ast_mutex_lock(&tpeer->lock); 04024 break; 04025 } 04026 } 04027 if (!tpeer) { 04028 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04029 ast_mutex_init(&tpeer->lock); 04030 tpeer->lastsent = 9999; 04031 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04032 tpeer->trunkact = ast_tvnow(); 04033 ast_mutex_lock(&tpeer->lock); 04034 tpeer->next = tpeers; 04035 tpeer->sockfd = fd; 04036 tpeers = tpeer; 04037 #ifdef SO_NO_CHECK 04038 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04039 #endif 04040 if (option_debug) 04041 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04042 } 04043 } 04044 ast_mutex_unlock(&tpeerlock); 04045 return tpeer; 04046 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3830 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03831 { 03832 long ms; /* NOT unsigned */ 03833 if (ast_tvzero(iaxs[callno]->rxcore)) { 03834 /* Initialize rxcore time if appropriate */ 03835 gettimeofday(&iaxs[callno]->rxcore, NULL); 03836 /* Round to nearest 20ms so traces look pretty */ 03837 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03838 } 03839 /* Calculate difference between trunk and channel */ 03840 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03841 /* Return as the sum of trunk time and the difference between trunk and real time */ 03842 return ms + ts; 03843 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8982 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08983 { 08984 struct iax2_context *conl; 08985 while(con) { 08986 conl = con; 08987 con = con->next; 08988 free(conl); 08989 } 08990 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10642 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.
10643 { 10644 struct iax2_peer *peer; 10645 char *peername, *colname; 10646 10647 peername = ast_strdupa(data); 10648 10649 /* if our channel, return the IP address of the endpoint of current channel */ 10650 if (!strcmp(peername,"CURRENTCHANNEL")) { 10651 unsigned short callno; 10652 if (chan->tech != &iax2_tech) 10653 return -1; 10654 callno = PTR_TO_CALLNO(chan->tech_pvt); 10655 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10656 return 0; 10657 } 10658 10659 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10660 *colname++ = '\0'; 10661 else if ((colname = strchr(peername, '|'))) 10662 *colname++ = '\0'; 10663 else 10664 colname = "ip"; 10665 10666 if (!(peer = find_peer(peername, 1))) 10667 return -1; 10668 10669 if (!strcasecmp(colname, "ip")) { 10670 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10671 } else if (!strcasecmp(colname, "status")) { 10672 peer_status(peer, buf, len); 10673 } else if (!strcasecmp(colname, "mailbox")) { 10674 ast_copy_string(buf, peer->mailbox, len); 10675 } else if (!strcasecmp(colname, "context")) { 10676 ast_copy_string(buf, peer->context, len); 10677 } else if (!strcasecmp(colname, "expire")) { 10678 snprintf(buf, len, "%d", peer->expire); 10679 } else if (!strcasecmp(colname, "dynamic")) { 10680 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10681 } else if (!strcasecmp(colname, "callerid_name")) { 10682 ast_copy_string(buf, peer->cid_name, len); 10683 } else if (!strcasecmp(colname, "callerid_num")) { 10684 ast_copy_string(buf, peer->cid_num, len); 10685 } else if (!strcasecmp(colname, "codecs")) { 10686 ast_getformatname_multiple(buf, len -1, peer->capability); 10687 } else if (!strncasecmp(colname, "codec[", 6)) { 10688 char *codecnum, *ptr; 10689 int index = 0, codec = 0; 10690 10691 codecnum = strchr(colname, '['); 10692 *codecnum = '\0'; 10693 codecnum++; 10694 if ((ptr = strchr(codecnum, ']'))) { 10695 *ptr = '\0'; 10696 } 10697 index = atoi(codecnum); 10698 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10699 ast_copy_string(buf, ast_getformatname(codec), len); 10700 } 10701 } 10702 10703 peer_unref(peer); 10704 10705 return 0; 10706 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9207 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09208 { 09209 int methods = 0; 09210 if (strstr(value, "rsa")) 09211 methods |= IAX_AUTH_RSA; 09212 if (strstr(value, "md5")) 09213 methods |= IAX_AUTH_MD5; 09214 if (strstr(value, "plaintext")) 09215 methods |= IAX_AUTH_PLAINTEXT; 09216 return methods; 09217 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1025 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01026 { 01027 int e; 01028 if (!strcasecmp(s, "aes128")) 01029 e = IAX_ENCRYPT_AES128; 01030 else if (ast_true(s)) 01031 e = IAX_ENCRYPT_AES128; 01032 else 01033 e = 0; 01034 return e; 01035 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2624 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02625 { 02626 #ifdef SCHED_MULTITHREADED 02627 if (schedule_action(__get_from_jb, data)) 02628 #endif 02629 __get_from_jb(data); 02630 return 0; 02631 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6861 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().
06862 { 06863 struct iax2_pkt_buf *pkt_buf; 06864 06865 ast_mutex_lock(&thread->lock); 06866 06867 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06868 ast_mutex_unlock(&thread->lock); 06869 06870 thread->buf = pkt_buf->buf; 06871 thread->buf_len = pkt_buf->len; 06872 thread->buf_size = pkt_buf->len + 1; 06873 06874 socket_process(thread); 06875 06876 thread->buf = NULL; 06877 ast_free(pkt_buf); 06878 06879 ast_mutex_lock(&thread->lock); 06880 } 06881 06882 ast_mutex_unlock(&thread->lock); 06883 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2032 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
02033 { 02034 /* XXX Ideally we should figure out why an error occured and then abort those 02035 rather than continuing to try. Unfortunately, the published interface does 02036 not seem to work XXX */ 02037 #if 0 02038 struct sockaddr_in *sin; 02039 int res; 02040 struct msghdr m; 02041 struct sock_extended_err e; 02042 m.msg_name = NULL; 02043 m.msg_namelen = 0; 02044 m.msg_iov = NULL; 02045 m.msg_control = &e; 02046 m.msg_controllen = sizeof(e); 02047 m.msg_flags = 0; 02048 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02049 if (res < 0) 02050 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02051 else { 02052 if (m.msg_controllen) { 02053 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02054 if (sin) 02055 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02056 else 02057 ast_log(LOG_WARNING, "No address detected??\n"); 02058 } else { 02059 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02060 } 02061 } 02062 #endif 02063 return 0; 02064 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5924 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().
05925 { 05926 struct iax2_registry *reg; 05927 /* Start pessimistic */ 05928 char peer[256] = ""; 05929 char msgstatus[60]; 05930 int refresh = 60; 05931 char ourip[256] = "<Unspecified>"; 05932 struct sockaddr_in oldus; 05933 struct sockaddr_in us; 05934 int oldmsgs; 05935 05936 memset(&us, 0, sizeof(us)); 05937 if (ies->apparent_addr) 05938 bcopy(ies->apparent_addr, &us, sizeof(us)); 05939 if (ies->username) 05940 ast_copy_string(peer, ies->username, sizeof(peer)); 05941 if (ies->refresh) 05942 refresh = ies->refresh; 05943 if (ies->calling_number) { 05944 /* We don't do anything with it really, but maybe we should */ 05945 } 05946 reg = iaxs[callno]->reg; 05947 if (!reg) { 05948 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05949 return -1; 05950 } 05951 memcpy(&oldus, ®->us, sizeof(oldus)); 05952 oldmsgs = reg->messages; 05953 if (inaddrcmp(®->addr, sin)) { 05954 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05955 return -1; 05956 } 05957 memcpy(®->us, &us, sizeof(reg->us)); 05958 if (ies->msgcount >= 0) 05959 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05960 /* always refresh the registration at the interval requested by the server 05961 we are registering to 05962 */ 05963 reg->refresh = refresh; 05964 AST_SCHED_DEL(sched, reg->expire); 05965 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05966 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05967 if (option_verbose > 2) { 05968 if (reg->messages > 255) 05969 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05970 else if (reg->messages > 1) 05971 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05972 else if (reg->messages > 0) 05973 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05974 else 05975 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05976 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05977 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05978 } 05979 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05980 } 05981 reg->regstate = REG_STATE_REGISTERED; 05982 return 0; 05983 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3630 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.
03631 { 03632 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03633 if (option_debug) 03634 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03635 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03636 }
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 3480 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.
03481 { 03482 struct ast_channel *cs[3]; 03483 struct ast_channel *who, *other; 03484 int to = -1; 03485 int res = -1; 03486 int transferstarted=0; 03487 struct ast_frame *f; 03488 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03489 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03490 struct timeval waittimer = {0, 0}, tv; 03491 03492 lock_both(callno0, callno1); 03493 if (!iaxs[callno0] || !iaxs[callno1]) { 03494 unlock_both(callno0, callno1); 03495 return AST_BRIDGE_FAILED; 03496 } 03497 /* Put them in native bridge mode */ 03498 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03499 iaxs[callno0]->bridgecallno = callno1; 03500 iaxs[callno1]->bridgecallno = callno0; 03501 } 03502 unlock_both(callno0, callno1); 03503 03504 /* If not, try to bridge until we can execute a transfer, if we can */ 03505 cs[0] = c0; 03506 cs[1] = c1; 03507 for (/* ever */;;) { 03508 /* Check in case we got masqueraded into */ 03509 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03510 if (option_verbose > 2) 03511 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03512 /* Remove from native mode */ 03513 if (c0->tech == &iax2_tech) { 03514 ast_mutex_lock(&iaxsl[callno0]); 03515 iaxs[callno0]->bridgecallno = 0; 03516 ast_mutex_unlock(&iaxsl[callno0]); 03517 } 03518 if (c1->tech == &iax2_tech) { 03519 ast_mutex_lock(&iaxsl[callno1]); 03520 iaxs[callno1]->bridgecallno = 0; 03521 ast_mutex_unlock(&iaxsl[callno1]); 03522 } 03523 return AST_BRIDGE_FAILED_NOWARN; 03524 } 03525 if (c0->nativeformats != c1->nativeformats) { 03526 if (option_verbose > 2) { 03527 char buf0[255]; 03528 char buf1[255]; 03529 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03530 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03531 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03532 } 03533 /* Remove from native mode */ 03534 lock_both(callno0, callno1); 03535 if (iaxs[callno0]) 03536 iaxs[callno0]->bridgecallno = 0; 03537 if (iaxs[callno1]) 03538 iaxs[callno1]->bridgecallno = 0; 03539 unlock_both(callno0, callno1); 03540 return AST_BRIDGE_FAILED_NOWARN; 03541 } 03542 /* check if transfered and if we really want native bridging */ 03543 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03544 /* Try the transfer */ 03545 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03546 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03547 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03548 transferstarted = 1; 03549 } 03550 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03551 /* Call has been transferred. We're no longer involved */ 03552 gettimeofday(&tv, NULL); 03553 if (ast_tvzero(waittimer)) { 03554 waittimer = tv; 03555 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03556 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03557 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03558 *fo = NULL; 03559 *rc = c0; 03560 res = AST_BRIDGE_COMPLETE; 03561 break; 03562 } 03563 } 03564 to = 1000; 03565 who = ast_waitfor_n(cs, 2, &to); 03566 if (timeoutms > -1) { 03567 timeoutms -= (1000 - to); 03568 if (timeoutms < 0) 03569 timeoutms = 0; 03570 } 03571 if (!who) { 03572 if (!timeoutms) { 03573 res = AST_BRIDGE_RETRY; 03574 break; 03575 } 03576 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03577 res = AST_BRIDGE_FAILED; 03578 break; 03579 } 03580 continue; 03581 } 03582 f = ast_read(who); 03583 if (!f) { 03584 *fo = NULL; 03585 *rc = who; 03586 res = AST_BRIDGE_COMPLETE; 03587 break; 03588 } 03589 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03590 *fo = f; 03591 *rc = who; 03592 res = AST_BRIDGE_COMPLETE; 03593 break; 03594 } 03595 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03596 if ((f->frametype == AST_FRAME_VOICE) || 03597 (f->frametype == AST_FRAME_TEXT) || 03598 (f->frametype == AST_FRAME_VIDEO) || 03599 (f->frametype == AST_FRAME_IMAGE) || 03600 (f->frametype == AST_FRAME_DTMF)) { 03601 /* monitored dtmf take out of the bridge. 03602 * check if we monitor the specific source. 03603 */ 03604 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03605 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03606 *rc = who; 03607 *fo = f; 03608 res = AST_BRIDGE_COMPLETE; 03609 /* Remove from native mode */ 03610 break; 03611 } 03612 /* everything else goes to the other side */ 03613 ast_write(other, f); 03614 } 03615 ast_frfree(f); 03616 /* Swap who gets priority */ 03617 cs[2] = cs[0]; 03618 cs[0] = cs[1]; 03619 cs[1] = cs[2]; 03620 } 03621 lock_both(callno0, callno1); 03622 if(iaxs[callno0]) 03623 iaxs[callno0]->bridgecallno = 0; 03624 if(iaxs[callno1]) 03625 iaxs[callno1]->bridgecallno = 0; 03626 unlock_both(callno0, callno1); 03627 return res; 03628 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3224 of file chan_iax2.c.
References ast_channel::_state, create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), iax_ie_data::buf, iax2_registry::callno, CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, iax2_registry::secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, and parsed_dial_string::username.
03225 { 03226 struct sockaddr_in sin; 03227 char *l=NULL, *n=NULL, *tmpstr; 03228 struct iax_ie_data ied; 03229 char *defaultrdest = "s"; 03230 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03231 struct parsed_dial_string pds; 03232 struct create_addr_info cai; 03233 03234 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03235 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03236 return -1; 03237 } 03238 03239 memset(&cai, 0, sizeof(cai)); 03240 cai.encmethods = iax2_encryption; 03241 03242 memset(&pds, 0, sizeof(pds)); 03243 tmpstr = ast_strdupa(dest); 03244 parse_dial_string(tmpstr, &pds); 03245 03246 if (ast_strlen_zero(pds.peer)) { 03247 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03248 return -1; 03249 } 03250 03251 if (!pds.exten) { 03252 pds.exten = defaultrdest; 03253 } 03254 03255 if (create_addr(pds.peer, c, &sin, &cai)) { 03256 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03257 return -1; 03258 } 03259 03260 if (!pds.username && !ast_strlen_zero(cai.username)) 03261 pds.username = cai.username; 03262 if (!pds.password && !ast_strlen_zero(cai.secret)) 03263 pds.password = cai.secret; 03264 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03265 pds.key = cai.outkey; 03266 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03267 pds.context = cai.peercontext; 03268 03269 /* Keep track of the context for outgoing calls too */ 03270 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03271 03272 if (pds.port) 03273 sin.sin_port = htons(atoi(pds.port)); 03274 03275 l = c->cid.cid_num; 03276 n = c->cid.cid_name; 03277 03278 /* Now build request */ 03279 memset(&ied, 0, sizeof(ied)); 03280 03281 /* On new call, first IE MUST be IAX version of caller */ 03282 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03283 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03284 if (pds.options && strchr(pds.options, 'a')) { 03285 /* Request auto answer */ 03286 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03287 } 03288 03289 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03290 03291 if (l) { 03292 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03293 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03294 } else { 03295 if (n) 03296 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03297 else 03298 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03299 } 03300 03301 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03302 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03303 03304 if (n) 03305 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03306 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03307 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03308 03309 if (!ast_strlen_zero(c->language)) 03310 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03311 if (!ast_strlen_zero(c->cid.cid_dnid)) 03312 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03313 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03314 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03315 03316 if (pds.context) 03317 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03318 03319 if (pds.username) 03320 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03321 03322 if (cai.encmethods) 03323 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03324 03325 ast_mutex_lock(&iaxsl[callno]); 03326 03327 if (!ast_strlen_zero(c->context)) 03328 ast_string_field_set(iaxs[callno], context, c->context); 03329 03330 if (pds.username) 03331 ast_string_field_set(iaxs[callno], username, pds.username); 03332 03333 iaxs[callno]->encmethods = cai.encmethods; 03334 03335 iaxs[callno]->adsi = cai.adsi; 03336 03337 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03338 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03339 03340 if (pds.key) 03341 ast_string_field_set(iaxs[callno], outkey, pds.key); 03342 if (pds.password) 03343 ast_string_field_set(iaxs[callno], secret, pds.password); 03344 03345 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03346 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03347 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03348 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03349 03350 if (iaxs[callno]->maxtime) { 03351 /* Initialize pingtime and auto-congest time */ 03352 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03353 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03354 } else if (autokill) { 03355 iaxs[callno]->pingtime = autokill / 2; 03356 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03357 } 03358 03359 /* send the command using the appropriate socket for this peer */ 03360 iaxs[callno]->sockfd = cai.sockfd; 03361 03362 /* Transmit the string in a "NEW" request */ 03363 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03364 03365 ast_mutex_unlock(&iaxsl[callno]); 03366 ast_setstate(c, AST_STATE_RINGING); 03367 03368 return 0; 03369 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 10544 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.
10545 { 10546 int res = 0; 10547 struct iax2_dpcache *dp; 10548 #if 0 10549 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10550 #endif 10551 if ((priority != 1) && (priority != 2)) 10552 return 0; 10553 ast_mutex_lock(&dpcache_lock); 10554 dp = find_cache(chan, data, context, exten, priority); 10555 if (dp) { 10556 if (dp->flags & CACHE_FLAG_CANEXIST) 10557 res= 1; 10558 } 10559 ast_mutex_unlock(&dpcache_lock); 10560 if (!dp) { 10561 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10562 } 10563 return res; 10564 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3127 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03128 { 03129 time_t t; 03130 struct tm tm; 03131 unsigned int tmp; 03132 time(&t); 03133 if (!ast_strlen_zero(tz)) 03134 ast_localtime(&t, &tm, tz); 03135 else 03136 ast_localtime(&t, &tm, NULL); 03137 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03138 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03139 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03140 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03141 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03142 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03143 return tmp; 03144 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1283 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, lastused, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), and update_max_trunk().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01284 { 01285 struct chan_iax2_pvt *pvt; 01286 struct ast_channel *owner; 01287 01288 retry: 01289 pvt = iaxs[callno]; 01290 gettimeofday(&lastused[callno], NULL); 01291 01292 owner = pvt ? pvt->owner : NULL; 01293 01294 if (owner) { 01295 if (ast_mutex_trylock(&owner->lock)) { 01296 if (option_debug > 2) 01297 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01298 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01299 goto retry; 01300 } 01301 } 01302 if (!owner) { 01303 iaxs[callno] = NULL; 01304 } 01305 01306 if (pvt) { 01307 if (!owner) { 01308 pvt->owner = NULL; 01309 } else { 01310 /* If there's an owner, prod it to give up */ 01311 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01312 * because we already hold the owner channel lock. */ 01313 ast_queue_hangup(owner); 01314 } 01315 01316 if (pvt->peercallno) { 01317 remove_by_peercallno(pvt); 01318 } 01319 01320 if (!owner) { 01321 ao2_ref(pvt, -1); 01322 pvt = NULL; 01323 } 01324 } 01325 01326 if (owner) { 01327 ast_mutex_unlock(&owner->lock); 01328 } 01329 01330 if (callno & 0x4000) { 01331 update_max_trunk(); 01332 } 01333 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1213 of file chan_iax2.c.
References ao2_find(), ast_clear_flag, AST_SCHED_DEL, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, chan_iax2_pvt::pingid, user_unref(), and users.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01214 { 01215 /* Decrement AUTHREQ count if needed */ 01216 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01217 struct iax2_user *user; 01218 struct iax2_user tmp_user = { 01219 .name = pvt->username, 01220 }; 01221 01222 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01223 if (user) { 01224 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01225 user = user_unref(user); 01226 } 01227 01228 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01229 } 01230 01231 /* No more pings or lagrq's */ 01232 AST_SCHED_DEL(sched, pvt->pingid); 01233 AST_SCHED_DEL(sched, pvt->lagid); 01234 AST_SCHED_DEL(sched, pvt->autoid); 01235 AST_SCHED_DEL(sched, pvt->authid); 01236 AST_SCHED_DEL(sched, pvt->initid); 01237 AST_SCHED_DEL(sched, pvt->jbid); 01238 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10731 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().
10732 { 10733 struct parsed_dial_string pds; 10734 char *tmp = ast_strdupa(data); 10735 struct iax2_peer *p; 10736 int res = AST_DEVICE_INVALID; 10737 10738 memset(&pds, 0, sizeof(pds)); 10739 parse_dial_string(tmp, &pds); 10740 10741 if (ast_strlen_zero(pds.peer)) { 10742 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10743 return res; 10744 } 10745 10746 if (option_debug > 2) 10747 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10748 10749 /* SLD: FIXME: second call to find_peer during registration */ 10750 if (!(p = find_peer(pds.peer, 1))) 10751 return res; 10752 10753 res = AST_DEVICE_UNAVAILABLE; 10754 if (option_debug > 2) 10755 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10756 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10757 10758 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10759 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10760 /* Peer is registered, or have default IP address 10761 and a valid registration */ 10762 if (p->historicms == 0 || p->historicms <= p->maxms) 10763 /* let the core figure out whether it is in use or not */ 10764 res = AST_DEVICE_UNKNOWN; 10765 } 10766 10767 peer_unref(p); 10768 10769 return res; 10770 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2743 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02744 { 02745 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02746 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2748 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02749 { 02750 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02751 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4936 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04937 { 04938 if (argc < 2 || argc > 3) 04939 return RESULT_SHOWUSAGE; 04940 iaxdebug = 1; 04941 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04942 return RESULT_SUCCESS; 04943 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4954 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04955 { 04956 if (argc < 3 || argc > 4) 04957 return RESULT_SHOWUSAGE; 04958 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04959 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04960 return RESULT_SUCCESS; 04961 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8701 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().
08702 { 08703 struct iax_ie_data ied; 08704 if (option_debug && iaxdebug) 08705 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08706 08707 if (reg->dnsmgr && 08708 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08709 /* Maybe the IP has changed, force DNS refresh */ 08710 ast_dnsmgr_refresh(reg->dnsmgr); 08711 } 08712 08713 /* 08714 * if IP has Changed, free allocated call to create a new one with new IP 08715 * call has the pointer to IP and must be updated to the new one 08716 */ 08717 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08718 ast_mutex_lock(&iaxsl[reg->callno]); 08719 iax2_destroy(reg->callno); 08720 ast_mutex_unlock(&iaxsl[reg->callno]); 08721 reg->callno = 0; 08722 } 08723 if (!reg->addr.sin_addr.s_addr) { 08724 if (option_debug && iaxdebug) 08725 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08726 /* Setup the next registration attempt */ 08727 AST_SCHED_DEL(sched, reg->expire); 08728 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08729 return -1; 08730 } 08731 08732 if (!reg->callno) { 08733 if (option_debug) 08734 ast_log(LOG_DEBUG, "Allocate call number\n"); 08735 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08736 if (reg->callno < 1) { 08737 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08738 return -1; 08739 } else if (option_debug) 08740 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08741 iaxs[reg->callno]->reg = reg; 08742 ast_mutex_unlock(&iaxsl[reg->callno]); 08743 } 08744 /* Schedule the next registration attempt */ 08745 AST_SCHED_DEL(sched, reg->expire); 08746 /* Setup the next registration a little early */ 08747 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08748 /* Send the request */ 08749 memset(&ied, 0, sizeof(ied)); 08750 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08751 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08752 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08753 reg->regstate = REG_STATE_REGSENT; 08754 return 0; 08755 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5772 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05773 { 05774 #ifdef SCHED_MULTITHREADED 05775 if (schedule_action(__iax2_do_register_s, data)) 05776 #endif 05777 __iax2_do_register_s(data); 05778 return 0; 05779 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4945 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04946 { 04947 if (argc < 3 || argc > 4) 04948 return RESULT_SHOWUSAGE; 04949 iaxtrunkdebug = 1; 04950 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04951 return RESULT_SUCCESS; 04952 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6472 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().
06473 { 06474 struct iax_ie_data ied; 06475 /* Auto-hangup with 30 seconds of inactivity */ 06476 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06477 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06478 memset(&ied, 0, sizeof(ied)); 06479 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06480 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06481 dp->flags |= CACHE_FLAG_TRANSMITTED; 06482 }
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 10590 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.
10591 { 10592 char odata[256]; 10593 char req[256]; 10594 char *ncontext; 10595 struct iax2_dpcache *dp; 10596 struct ast_app *dial; 10597 #if 0 10598 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); 10599 #endif 10600 if (priority == 2) { 10601 /* Indicate status, can be overridden in dialplan */ 10602 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10603 if (dialstatus) { 10604 dial = pbx_findapp(dialstatus); 10605 if (dial) 10606 pbx_exec(chan, dial, ""); 10607 } 10608 return -1; 10609 } else if (priority != 1) 10610 return -1; 10611 ast_mutex_lock(&dpcache_lock); 10612 dp = find_cache(chan, data, context, exten, priority); 10613 if (dp) { 10614 if (dp->flags & CACHE_FLAG_EXISTS) { 10615 ast_copy_string(odata, data, sizeof(odata)); 10616 ncontext = strchr(odata, '/'); 10617 if (ncontext) { 10618 *ncontext = '\0'; 10619 ncontext++; 10620 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10621 } else { 10622 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10623 } 10624 if (option_verbose > 2) 10625 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10626 } else { 10627 ast_mutex_unlock(&dpcache_lock); 10628 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10629 return -1; 10630 } 10631 } 10632 ast_mutex_unlock(&dpcache_lock); 10633 dial = pbx_findapp("Dial"); 10634 if (dial) { 10635 return pbx_exec(chan, dial, req); 10636 } else { 10637 ast_log(LOG_WARNING, "No dial application registered\n"); 10638 } 10639 return -1; 10640 }
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 10521 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.
10522 { 10523 struct iax2_dpcache *dp; 10524 int res = 0; 10525 #if 0 10526 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10527 #endif 10528 if ((priority != 1) && (priority != 2)) 10529 return 0; 10530 ast_mutex_lock(&dpcache_lock); 10531 dp = find_cache(chan, data, context, exten, priority); 10532 if (dp) { 10533 if (dp->flags & CACHE_FLAG_EXISTS) 10534 res= 1; 10535 } 10536 ast_mutex_unlock(&dpcache_lock); 10537 if (!dp) { 10538 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10539 } 10540 return res; 10541 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2770 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02771 { 02772 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02773 ast_mutex_lock(&iaxsl[callno]); 02774 if (iaxs[callno]) 02775 iaxs[callno]->owner = newchan; 02776 else 02777 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02778 ast_mutex_unlock(&iaxsl[callno]); 02779 return 0; 02780 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1277 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), and schedule_delivery().
01278 { 01279 AST_SCHED_DEL(sched, fr->retrans); 01280 iax_frame_free(fr); 01281 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1183 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), peer_unref(), peers, and realtime_peer().
Referenced by __find_callno().
01184 { 01185 struct iax2_peer *peer = NULL; 01186 int res = 0; 01187 struct ao2_iterator i; 01188 01189 i = ao2_iterator_init(peers, 0); 01190 while ((peer = ao2_iterator_next(&i))) { 01191 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01192 (peer->addr.sin_port == sin.sin_port)) { 01193 ast_copy_string(host, peer->name, len); 01194 peer_unref(peer); 01195 res = 1; 01196 break; 01197 } 01198 peer_unref(peer); 01199 } 01200 01201 if (!peer) { 01202 peer = realtime_peer(NULL, &sin); 01203 if (peer) { 01204 ast_copy_string(host, peer->name, len); 01205 peer_unref(peer); 01206 res = 1; 01207 } 01208 } 01209 01210 return res; 01211 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3705 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().
03706 { 03707 struct iax2_peer *peer; 03708 int res = 0; 03709 struct ao2_iterator i; 03710 03711 i = ao2_iterator_init(peers, 0); 03712 while ((peer = ao2_iterator_next(&i))) { 03713 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03714 (peer->addr.sin_port == sin.sin_port)) { 03715 res = ast_test_flag(peer, IAX_TRUNK); 03716 peer_unref(peer); 03717 break; 03718 } 03719 peer_unref(peer); 03720 } 03721 03722 return res; 03723 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3371 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), iax_ie_data::buf, iax2_registry::callno, error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_DEBUG, option_debug, option_verbose, iax_ie_data::pos, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03372 { 03373 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03374 int alreadygone; 03375 struct iax_ie_data ied; 03376 memset(&ied, 0, sizeof(ied)); 03377 ast_mutex_lock(&iaxsl[callno]); 03378 if (callno && iaxs[callno]) { 03379 if (option_debug) 03380 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03381 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03382 /* Send the hangup unless we have had a transmission error or are already gone */ 03383 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03384 if (!iaxs[callno]->error && !alreadygone) { 03385 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03386 if (!iaxs[callno]) { 03387 ast_mutex_unlock(&iaxsl[callno]); 03388 return 0; 03389 } 03390 } 03391 /* Explicitly predestroy it */ 03392 iax2_predestroy(callno); 03393 /* If we were already gone to begin with, destroy us now */ 03394 if (alreadygone && iaxs[callno]) { 03395 if (option_debug) 03396 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03397 iax2_destroy(callno); 03398 } 03399 } 03400 ast_mutex_unlock(&iaxsl[callno]); 03401 if (option_verbose > 2) 03402 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03403 return 0; 03404 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3638 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.
03639 { 03640 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03641 struct chan_iax2_pvt *pvt; 03642 int res = 0; 03643 03644 if (option_debug && iaxdebug) 03645 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03646 03647 ast_mutex_lock(&iaxsl[callno]); 03648 pvt = iaxs[callno]; 03649 03650 if (!pvt->peercallno) { 03651 /* We don't know the remote side's call number, yet. :( */ 03652 int count = 10; 03653 while (count-- && pvt && !pvt->peercallno) { 03654 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03655 pvt = iaxs[callno]; 03656 } 03657 if (!pvt->peercallno) { 03658 res = -1; 03659 goto done; 03660 } 03661 } 03662 03663 switch (condition) { 03664 case AST_CONTROL_HOLD: 03665 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03666 ast_moh_start(c, data, pvt->mohinterpret); 03667 goto done; 03668 } 03669 break; 03670 case AST_CONTROL_UNHOLD: 03671 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03672 ast_moh_stop(c); 03673 goto done; 03674 } 03675 } 03676 03677 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03678 03679 done: 03680 ast_mutex_unlock(&iaxsl[callno]); 03681 03682 return res; 03683 }
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 10567 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.
10568 { 10569 int res = 0; 10570 struct iax2_dpcache *dp; 10571 #if 0 10572 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10573 #endif 10574 if ((priority != 1) && (priority != 2)) 10575 return 0; 10576 ast_mutex_lock(&dpcache_lock); 10577 dp = find_cache(chan, data, context, exten, priority); 10578 if (dp) { 10579 if (dp->flags & CACHE_FLAG_MATCHMORE) 10580 res= 1; 10581 } 10582 ast_mutex_unlock(&dpcache_lock); 10583 if (!dp) { 10584 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10585 } 10586 return res; 10587 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4963 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04964 { 04965 if (argc < 3 || argc > 4) 04966 return RESULT_SHOWUSAGE; 04967 iaxdebug = 0; 04968 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04969 return RESULT_SUCCESS; 04970 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4981 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04982 { 04983 if (argc < 4 || argc > 5) 04984 return RESULT_SHOWUSAGE; 04985 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04986 jb_debug_output("\n"); 04987 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04988 return RESULT_SUCCESS; 04989 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4972 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04973 { 04974 if (argc < 4 || argc > 5) 04975 return RESULT_SHOWUSAGE; 04976 iaxtrunkdebug = 0; 04977 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04978 return RESULT_SUCCESS; 04979 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8899 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08900 { 08901 struct iax2_peer *peer = (struct iax2_peer *)data; 08902 peer->pokeexpire = -1; 08903 #ifdef SCHED_MULTITHREADED 08904 if (schedule_action(__iax2_poke_noanswer, data)) 08905 #endif 08906 __iax2_poke_noanswer(data); 08907 peer_unref(peer); 08908 return 0; 08909 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8920 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().
08921 { 08922 int callno; 08923 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08924 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08925 immediately after clearing things out */ 08926 peer->lastms = 0; 08927 peer->historicms = 0; 08928 peer->pokeexpire = -1; 08929 peer->callno = 0; 08930 return 0; 08931 } 08932 08933 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 08934 if ((callno = peer->callno) > 0) { 08935 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08936 ast_mutex_lock(&iaxsl[callno]); 08937 iax2_destroy(callno); 08938 ast_mutex_unlock(&iaxsl[callno]); 08939 } 08940 if (heldcall) 08941 ast_mutex_unlock(&iaxsl[heldcall]); 08942 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08943 if (heldcall) 08944 ast_mutex_lock(&iaxsl[heldcall]); 08945 if (peer->callno < 1) { 08946 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08947 return -1; 08948 } 08949 08950 /* Speed up retransmission times for this qualify call */ 08951 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08952 iaxs[peer->callno]->peerpoke = peer; 08953 08954 /* Remove any pending pokeexpire task */ 08955 if (peer->pokeexpire > -1) { 08956 if (!ast_sched_del(sched, peer->pokeexpire)) { 08957 peer->pokeexpire = -1; 08958 peer_unref(peer); 08959 } 08960 } 08961 08962 /* Queue up a new task to handle no reply */ 08963 /* If the host is already unreachable then use the unreachable interval instead */ 08964 if (peer->lastms < 0) { 08965 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08966 } else 08967 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08968 08969 if (peer->pokeexpire == -1) 08970 peer_unref(peer); 08971 08972 /* And send the poke */ 08973 ast_mutex_lock(&iaxsl[callno]); 08974 if (iaxs[callno]) { 08975 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08976 } 08977 ast_mutex_unlock(&iaxsl[callno]); 08978 08979 return 0; 08980 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8911 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08912 { 08913 struct iax2_peer *peer = obj; 08914 08915 iax2_poke_peer(peer, 0); 08916 08917 return 0; 08918 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6512 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06513 { 06514 struct iax2_peer *peer = (struct iax2_peer *)data; 06515 peer->pokeexpire = -1; 06516 #ifdef SCHED_MULTITHREADED 06517 if (schedule_action(__iax2_poke_peer_s, data)) 06518 #endif 06519 __iax2_poke_peer_s(data); 06520 return 0; 06521 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2116 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag, ast_test_flag, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
02117 { 02118 struct ast_channel *c; 02119 struct chan_iax2_pvt *pvt = iaxs[callno]; 02120 02121 if (!pvt) 02122 return -1; 02123 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02124 iax2_destroy_helper(pvt); 02125 ast_set_flag(pvt, IAX_ALREADYGONE); 02126 } 02127 c = pvt->owner; 02128 if (c) { 02129 c->tech_pvt = NULL; 02130 iax2_queue_hangup(callno); 02131 pvt->owner = NULL; 02132 ast_module_unref(ast_module_info->self); 02133 } 02134 return 0; 02135 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8576 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().
08577 { 08578 struct iax2_thread *thread = data; 08579 struct timeval tv; 08580 struct timespec ts; 08581 int put_into_idle = 0; 08582 08583 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08584 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08585 for(;;) { 08586 /* Wait for something to signal us to be awake */ 08587 ast_mutex_lock(&thread->lock); 08588 08589 /* Flag that we're ready to accept signals */ 08590 thread->ready_for_signal = 1; 08591 08592 /* Put into idle list if applicable */ 08593 if (put_into_idle) 08594 insert_idle_thread(thread); 08595 08596 if (thread->type == IAX_TYPE_DYNAMIC) { 08597 struct iax2_thread *t = NULL; 08598 /* Wait to be signalled or time out */ 08599 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08600 ts.tv_sec = tv.tv_sec; 08601 ts.tv_nsec = tv.tv_usec * 1000; 08602 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08603 /* This thread was never put back into the available dynamic 08604 * thread list, so just go away. */ 08605 if (!put_into_idle) { 08606 ast_mutex_unlock(&thread->lock); 08607 break; 08608 } 08609 AST_LIST_LOCK(&dynamic_list); 08610 /* Account for the case where this thread is acquired *right* after a timeout */ 08611 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08612 iaxdynamicthreadcount--; 08613 AST_LIST_UNLOCK(&dynamic_list); 08614 if (t) { 08615 /* This dynamic thread timed out waiting for a task and was 08616 * not acquired immediately after the timeout, 08617 * so it's time to go away. */ 08618 ast_mutex_unlock(&thread->lock); 08619 break; 08620 } 08621 /* Someone grabbed our thread *right* after we timed out. 08622 * Wait for them to set us up with something to do and signal 08623 * us to continue. */ 08624 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08625 ts.tv_sec = tv.tv_sec; 08626 ts.tv_nsec = tv.tv_usec * 1000; 08627 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08628 { 08629 ast_mutex_unlock(&thread->lock); 08630 break; 08631 } 08632 } 08633 } else { 08634 ast_cond_wait(&thread->cond, &thread->lock); 08635 } 08636 08637 /* Go back into our respective list */ 08638 put_into_idle = 1; 08639 08640 ast_mutex_unlock(&thread->lock); 08641 08642 if (thread->iostate == IAX_IOSTATE_IDLE) 08643 continue; 08644 08645 /* Add ourselves to the active list now */ 08646 AST_LIST_LOCK(&active_list); 08647 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08648 AST_LIST_UNLOCK(&active_list); 08649 08650 /* See what we need to do */ 08651 switch(thread->iostate) { 08652 case IAX_IOSTATE_READY: 08653 thread->actions++; 08654 thread->iostate = IAX_IOSTATE_PROCESSING; 08655 socket_process(thread); 08656 handle_deferred_full_frames(thread); 08657 break; 08658 case IAX_IOSTATE_SCHEDREADY: 08659 thread->actions++; 08660 thread->iostate = IAX_IOSTATE_PROCESSING; 08661 #ifdef SCHED_MULTITHREADED 08662 thread->schedfunc(thread->scheddata); 08663 #endif 08664 break; 08665 } 08666 time(&thread->checktime); 08667 thread->iostate = IAX_IOSTATE_IDLE; 08668 #ifdef DEBUG_SCHED_MULTITHREAD 08669 thread->curfunc[0]='\0'; 08670 #endif 08671 08672 /* Now... remove ourselves from the active list, and return to the idle list */ 08673 AST_LIST_LOCK(&active_list); 08674 AST_LIST_REMOVE(&active_list, thread, list); 08675 AST_LIST_UNLOCK(&active_list); 08676 08677 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08678 handle_deferred_full_frames(thread); 08679 } 08680 08681 /*!\note For some reason, idle threads are exiting without being removed 08682 * from an idle list, which is causing memory corruption. Forcibly remove 08683 * it from the list, if it's there. 08684 */ 08685 AST_LIST_LOCK(&idle_list); 08686 AST_LIST_REMOVE(&idle_list, thread, list); 08687 AST_LIST_UNLOCK(&idle_list); 08688 08689 AST_LIST_LOCK(&dynamic_list); 08690 AST_LIST_REMOVE(&dynamic_list, thread, list); 08691 AST_LIST_UNLOCK(&dynamic_list); 08692 08693 /* I am exiting here on my own volition, I need to clean up my own data structures 08694 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08695 */ 08696 pthread_cleanup_pop(1); 08697 08698 return NULL; 08699 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8567 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08568 { 08569 struct iax2_thread *thread = data; 08570 ast_mutex_destroy(&thread->lock); 08571 ast_cond_destroy(&thread->cond); 08572 free(thread); 08573 ast_atomic_dec_and_test(&iaxactivethreadcount); 08574 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8854 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08855 { 08856 int force = 0; 08857 int res; 08858 if (argc < 4) 08859 return RESULT_SHOWUSAGE; 08860 if ((argc > 4)) { 08861 if (!strcasecmp(argv[4], "forced")) 08862 force = 1; 08863 else 08864 return RESULT_SHOWUSAGE; 08865 } 08866 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08867 if (res < 0) 08868 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08869 else if (res < 1) 08870 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08871 else 08872 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08873 return RESULT_SUCCESS; 08874 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8757 of file chan_iax2.c.
References iax_prov_complete_template().
08758 { 08759 if (pos != 3) 08760 return NULL; 08761 return iax_prov_complete_template(line, word, pos, state); 08762 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8764 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().
08765 { 08766 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08767 is found for template */ 08768 struct iax_ie_data provdata; 08769 struct iax_ie_data ied; 08770 unsigned int sig; 08771 struct sockaddr_in sin; 08772 int callno; 08773 struct create_addr_info cai; 08774 08775 memset(&cai, 0, sizeof(cai)); 08776 08777 if (option_debug) 08778 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08779 08780 if (iax_provision_build(&provdata, &sig, template, force)) { 08781 if (option_debug) 08782 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08783 return 0; 08784 } 08785 08786 if (end) { 08787 memcpy(&sin, end, sizeof(sin)); 08788 cai.sockfd = sockfd; 08789 } else if (create_addr(dest, NULL, &sin, &cai)) 08790 return -1; 08791 08792 /* Build the rest of the message */ 08793 memset(&ied, 0, sizeof(ied)); 08794 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08795 08796 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08797 if (!callno) 08798 return -1; 08799 08800 if (iaxs[callno]) { 08801 /* Schedule autodestruct in case they don't ever give us anything back */ 08802 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08803 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08804 ast_set_flag(iaxs[callno], IAX_PROVISION); 08805 /* Got a call number now, so go ahead and send the provisioning information */ 08806 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08807 } 08808 ast_mutex_unlock(&iaxsl[callno]); 08809 08810 return 1; 08811 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2240 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02241 { 02242 struct iax2_peer *peer; 02243 02244 if (argc != 4) 02245 return RESULT_SHOWUSAGE; 02246 if (!strcmp(argv[3],"all")) { 02247 reload_config(); 02248 ast_cli(fd, "OK cache is flushed.\n"); 02249 } else if ((peer = find_peer(argv[3], 0))) { 02250 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02251 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02252 expire_registry(peer_ref(peer)); 02253 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02254 } else { 02255 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02256 } 02257 peer_unref(peer); 02258 } else { 02259 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02260 } 02261 02262 return RESULT_SUCCESS; 02263 }
static int iax2_queue_control_data | ( | int | callno, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1726 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01728 { 01729 for (;;) { 01730 if (iaxs[callno] && iaxs[callno]->owner) { 01731 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01732 /* Avoid deadlock by pausing and trying again */ 01733 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01734 } else { 01735 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01736 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01737 break; 01738 } 01739 } else 01740 break; 01741 } 01742 return 0; 01743 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 1664 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01665 { 01666 for (;;) { 01667 if (iaxs[callno] && iaxs[callno]->owner) { 01668 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01669 /* Avoid deadlock by pausing and trying again */ 01670 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01671 } else { 01672 ast_queue_frame(iaxs[callno]->owner, f); 01673 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01674 break; 01675 } 01676 } else 01677 break; 01678 } 01679 return 0; 01680 }
static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1695 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01696 { 01697 for (;;) { 01698 if (iaxs[callno] && iaxs[callno]->owner) { 01699 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01700 /* Avoid deadlock by pausing and trying again */ 01701 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01702 } else { 01703 ast_queue_hangup(iaxs[callno]->owner); 01704 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01705 break; 01706 } 01707 } else 01708 break; 01709 } 01710 return 0; 01711 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 3432 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03433 { 03434 if (option_verbose > 3) 03435 ast_log(LOG_NOTICE, "I should never be called!\n"); 03436 return &ast_null_frame; 03437 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5985 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().
05986 { 05987 struct iax2_registry *reg; 05988 char copy[256]; 05989 char *username, *hostname, *secret; 05990 char *porta; 05991 char *stringp=NULL; 05992 05993 if (!value) 05994 return -1; 05995 ast_copy_string(copy, value, sizeof(copy)); 05996 stringp=copy; 05997 username = strsep(&stringp, "@"); 05998 hostname = strsep(&stringp, "@"); 05999 if (!hostname) { 06000 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06001 return -1; 06002 } 06003 stringp=username; 06004 username = strsep(&stringp, ":"); 06005 secret = strsep(&stringp, ":"); 06006 stringp=hostname; 06007 hostname = strsep(&stringp, ":"); 06008 porta = strsep(&stringp, ":"); 06009 06010 if (porta && !atoi(porta)) { 06011 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06012 return -1; 06013 } 06014 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06015 return -1; 06016 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06017 free(reg); 06018 return -1; 06019 } 06020 ast_copy_string(reg->username, username, sizeof(reg->username)); 06021 if (secret) 06022 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06023 reg->expire = -1; 06024 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06025 reg->addr.sin_family = AF_INET; 06026 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06027 AST_LIST_LOCK(®istrations); 06028 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06029 AST_LIST_UNLOCK(®istrations); 06030 06031 return 0; 06032 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10290 of file chan_iax2.c.
References reload_config().
10291 { 10292 return reload_config(); 10293 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 8992 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.
08993 { 08994 int callno; 08995 int res; 08996 int fmt, native; 08997 struct sockaddr_in sin; 08998 struct ast_channel *c; 08999 struct parsed_dial_string pds; 09000 struct create_addr_info cai; 09001 char *tmpstr; 09002 09003 memset(&pds, 0, sizeof(pds)); 09004 tmpstr = ast_strdupa(data); 09005 parse_dial_string(tmpstr, &pds); 09006 09007 if (ast_strlen_zero(pds.peer)) { 09008 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09009 return NULL; 09010 } 09011 09012 memset(&cai, 0, sizeof(cai)); 09013 cai.capability = iax2_capability; 09014 09015 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09016 09017 /* Populate our address from the given */ 09018 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09019 *cause = AST_CAUSE_UNREGISTERED; 09020 return NULL; 09021 } 09022 09023 if (pds.port) 09024 sin.sin_port = htons(atoi(pds.port)); 09025 09026 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09027 if (callno < 1) { 09028 ast_log(LOG_WARNING, "Unable to create call\n"); 09029 *cause = AST_CAUSE_CONGESTION; 09030 return NULL; 09031 } 09032 09033 /* If this is a trunk, update it now */ 09034 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09035 if (ast_test_flag(&cai, IAX_TRUNK)) { 09036 int new_callno; 09037 if ((new_callno = make_trunk(callno, 1)) != -1) 09038 callno = new_callno; 09039 } 09040 iaxs[callno]->maxtime = cai.maxtime; 09041 if (cai.found) 09042 ast_string_field_set(iaxs[callno], host, pds.peer); 09043 09044 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09045 09046 ast_mutex_unlock(&iaxsl[callno]); 09047 09048 if (c) { 09049 /* Choose a format we can live with */ 09050 if (c->nativeformats & format) 09051 c->nativeformats &= format; 09052 else { 09053 native = c->nativeformats; 09054 fmt = format; 09055 res = ast_translator_best_choice(&fmt, &native); 09056 if (res < 0) { 09057 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09058 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09059 ast_hangup(c); 09060 return NULL; 09061 } 09062 c->nativeformats = native; 09063 } 09064 c->readformat = ast_best_codec(c->nativeformats); 09065 c->writeformat = c->readformat; 09066 } 09067 09068 return c; 09069 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 987 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00988 { 00989 int res; 00990 00991 res = ast_sched_add(con, when, callback, data); 00992 signal_condition(&sched_lock, &sched_cond); 00993 00994 return res; 00995 }
static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f, | |||
unsigned int | ts, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 4274 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, chan_iax2_pvt::ecx, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04275 { 04276 /* Queue a packet for delivery on a given private structure. Use "ts" for 04277 timestamp, or calculate if ts is 0. Send immediately without retransmission 04278 or delayed, with retransmission */ 04279 struct ast_iax2_full_hdr *fh; 04280 struct ast_iax2_mini_hdr *mh; 04281 struct ast_iax2_video_hdr *vh; 04282 struct { 04283 struct iax_frame fr2; 04284 unsigned char buffer[4096]; 04285 } frb; 04286 struct iax_frame *fr; 04287 int res; 04288 int sendmini=0; 04289 unsigned int lastsent; 04290 unsigned int fts; 04291 04292 frb.fr2.afdatalen = sizeof(frb.buffer); 04293 04294 if (!pvt) { 04295 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04296 return -1; 04297 } 04298 04299 lastsent = pvt->lastsent; 04300 04301 /* Calculate actual timestamp */ 04302 fts = calc_timestamp(pvt, ts, f); 04303 04304 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04305 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04306 * increment the "predicted timestamps" for voice, if we're predecting */ 04307 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04308 return 0; 04309 04310 04311 if ((ast_test_flag(pvt, IAX_TRUNK) || 04312 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04313 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04314 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04315 (f->frametype == AST_FRAME_VOICE) 04316 /* is a voice frame */ && 04317 (f->subclass == pvt->svoiceformat) 04318 /* is the same type */ ) { 04319 /* Force immediate rather than delayed transmission */ 04320 now = 1; 04321 /* Mark that mini-style frame is appropriate */ 04322 sendmini = 1; 04323 } 04324 if ( f->frametype == AST_FRAME_VIDEO ) { 04325 /* 04326 * If the lower 15 bits of the timestamp roll over, or if 04327 * the video format changed then send a full frame. 04328 * Otherwise send a mini video frame 04329 */ 04330 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04331 ((f->subclass & ~0x1) == pvt->svideoformat) 04332 ) { 04333 now = 1; 04334 sendmini = 1; 04335 } else { 04336 now = 0; 04337 sendmini = 0; 04338 } 04339 pvt->lastvsent = fts; 04340 } 04341 /* Allocate an iax_frame */ 04342 if (now) { 04343 fr = &frb.fr2; 04344 } else 04345 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)); 04346 if (!fr) { 04347 ast_log(LOG_WARNING, "Out of memory\n"); 04348 return -1; 04349 } 04350 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04351 iax_frame_wrap(fr, f); 04352 04353 fr->ts = fts; 04354 fr->callno = pvt->callno; 04355 fr->transfer = transfer; 04356 fr->final = final; 04357 if (!sendmini) { 04358 /* We need a full frame */ 04359 if (seqno > -1) 04360 fr->oseqno = seqno; 04361 else 04362 fr->oseqno = pvt->oseqno++; 04363 fr->iseqno = pvt->iseqno; 04364 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04365 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04366 fh->ts = htonl(fr->ts); 04367 fh->oseqno = fr->oseqno; 04368 if (transfer) { 04369 fh->iseqno = 0; 04370 } else 04371 fh->iseqno = fr->iseqno; 04372 /* Keep track of the last thing we've acknowledged */ 04373 if (!transfer) 04374 pvt->aseqno = fr->iseqno; 04375 fh->type = fr->af.frametype & 0xFF; 04376 if (fr->af.frametype == AST_FRAME_VIDEO) 04377 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04378 else 04379 fh->csub = compress_subclass(fr->af.subclass); 04380 if (transfer) { 04381 fr->dcallno = pvt->transfercallno; 04382 } else 04383 fr->dcallno = pvt->peercallno; 04384 fh->dcallno = htons(fr->dcallno); 04385 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04386 fr->data = fh; 04387 fr->retries = 0; 04388 /* Retry after 2x the ping time has passed */ 04389 fr->retrytime = pvt->pingtime * 2; 04390 if (fr->retrytime < MIN_RETRY_TIME) 04391 fr->retrytime = MIN_RETRY_TIME; 04392 if (fr->retrytime > MAX_RETRY_TIME) 04393 fr->retrytime = MAX_RETRY_TIME; 04394 /* Acks' don't get retried */ 04395 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04396 fr->retries = -1; 04397 else if (f->frametype == AST_FRAME_VOICE) 04398 pvt->svoiceformat = f->subclass; 04399 else if (f->frametype == AST_FRAME_VIDEO) 04400 pvt->svideoformat = f->subclass & ~0x1; 04401 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04402 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04403 if (iaxdebug) { 04404 if (fr->transfer) 04405 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04406 else 04407 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04408 } 04409 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04410 } else 04411 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04412 } 04413 04414 if (now) { 04415 res = send_packet(fr); 04416 } else 04417 res = iax2_transmit(fr); 04418 } else { 04419 if (ast_test_flag(pvt, IAX_TRUNK)) { 04420 iax2_trunk_queue(pvt, fr); 04421 res = 0; 04422 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04423 /* Video frame have no sequence number */ 04424 fr->oseqno = -1; 04425 fr->iseqno = -1; 04426 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04427 vh->zeros = 0; 04428 vh->callno = htons(0x8000 | fr->callno); 04429 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04430 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04431 fr->data = vh; 04432 fr->retries = -1; 04433 res = send_packet(fr); 04434 } else { 04435 /* Mini-frames have no sequence number */ 04436 fr->oseqno = -1; 04437 fr->iseqno = -1; 04438 /* Mini frame will do */ 04439 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04440 mh->callno = htons(fr->callno); 04441 mh->ts = htons(fr->ts & 0xFFFF); 04442 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04443 fr->data = mh; 04444 fr->retries = -1; 04445 if (pvt->transferring == TRANSFER_MEDIAPASS) 04446 fr->transfer = 1; 04447 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04448 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04449 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04450 } else 04451 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04452 } 04453 res = send_packet(fr); 04454 } 04455 } 04456 return res; 04457 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2765 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02766 { 02767 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02768 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2760 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
02761 { 02762 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02763 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2753 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02754 { 02755 02756 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02757 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02758 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3406 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_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.
03407 { 03408 struct ast_option_header *h; 03409 int res; 03410 03411 switch (option) { 03412 case AST_OPTION_TXGAIN: 03413 case AST_OPTION_RXGAIN: 03414 /* these two cannot be sent, because they require a result */ 03415 errno = ENOSYS; 03416 return -1; 03417 default: 03418 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03419 return -1; 03420 03421 h->flag = AST_OPTION_FLAG_REQUEST; 03422 h->option = htons(option); 03423 memcpy(h->data, data, datalen); 03424 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03425 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03426 datalen + sizeof(*h), -1); 03427 free(h); 03428 return res; 03429 } 03430 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2444 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02445 { 02446 struct iax2_dpcache *dp; 02447 char tmp[1024], *pc; 02448 int s; 02449 int x,y; 02450 struct timeval tv; 02451 gettimeofday(&tv, NULL); 02452 ast_mutex_lock(&dpcache_lock); 02453 dp = dpcache; 02454 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02455 while(dp) { 02456 s = dp->expiry.tv_sec - tv.tv_sec; 02457 tmp[0] = '\0'; 02458 if (dp->flags & CACHE_FLAG_EXISTS) 02459 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02460 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02461 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02462 if (dp->flags & CACHE_FLAG_CANEXIST) 02463 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02464 if (dp->flags & CACHE_FLAG_PENDING) 02465 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02466 if (dp->flags & CACHE_FLAG_TIMEOUT) 02467 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02468 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02469 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02470 if (dp->flags & CACHE_FLAG_MATCHMORE) 02471 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02472 if (dp->flags & CACHE_FLAG_UNKNOWN) 02473 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02474 /* Trim trailing pipe */ 02475 if (!ast_strlen_zero(tmp)) 02476 tmp[strlen(tmp) - 1] = '\0'; 02477 else 02478 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02479 y=0; 02480 pc = strchr(dp->peercontext, '@'); 02481 if (!pc) 02482 pc = dp->peercontext; 02483 else 02484 pc++; 02485 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02486 if (dp->waiters[x] > -1) 02487 y++; 02488 if (s > 0) 02489 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02490 else 02491 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02492 dp = dp->next; 02493 } 02494 ast_mutex_unlock(&dpcache_lock); 02495 return RESULT_SUCCESS; 02496 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4801 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.
04802 { 04803 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04804 #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" 04805 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04806 int x; 04807 int numchans = 0; 04808 04809 if (argc != 3) 04810 return RESULT_SHOWUSAGE; 04811 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04812 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04813 ast_mutex_lock(&iaxsl[x]); 04814 if (iaxs[x]) { 04815 int lag, jitter, localdelay; 04816 jb_info jbinfo; 04817 04818 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04819 jb_getinfo(iaxs[x]->jb, &jbinfo); 04820 jitter = jbinfo.jitter; 04821 localdelay = jbinfo.current - jbinfo.min; 04822 } else { 04823 jitter = -1; 04824 localdelay = 0; 04825 } 04826 lag = iaxs[x]->remote_rr.delay; 04827 ast_cli(fd, FORMAT, 04828 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04829 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04830 S_OR(iaxs[x]->username, "(None)"), 04831 iaxs[x]->callno, iaxs[x]->peercallno, 04832 iaxs[x]->oseqno, iaxs[x]->iseqno, 04833 lag, 04834 jitter, 04835 localdelay, 04836 ast_getformatname(iaxs[x]->voiceformat) ); 04837 numchans++; 04838 } 04839 ast_mutex_unlock(&iaxsl[x]); 04840 } 04841 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04842 return RESULT_SUCCESS; 04843 #undef FORMAT 04844 #undef FORMAT2 04845 #undef FORMATB 04846 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4712 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.
04713 { 04714 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04715 #if !defined(__FreeBSD__) 04716 #define FORMAT "%-15.15s %-15d %-15d\n" 04717 #else /* __FreeBSD__ */ 04718 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04719 #endif /* __FreeBSD__ */ 04720 struct iax_firmware *cur; 04721 if ((argc != 3) && (argc != 4)) 04722 return RESULT_SHOWUSAGE; 04723 ast_mutex_lock(&waresl.lock); 04724 04725 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04726 for (cur = waresl.wares;cur;cur = cur->next) { 04727 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04728 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04729 (int)ntohl(cur->fwh->datalen)); 04730 } 04731 ast_mutex_unlock(&waresl.lock); 04732 return RESULT_SUCCESS; 04733 #undef FORMAT 04734 #undef FORMAT2 04735 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4924 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04925 { 04926 int numchans = 0; 04927 if (argc != 3) 04928 return RESULT_SHOWUSAGE; 04929 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04930 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04931 numchans = ast_cli_netstats(NULL, fd, 1); 04932 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04933 return RESULT_SUCCESS; 04934 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2334 of file chan_iax2.c.
References iax2_peer::addr, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, iax2_peer::capability, iax2_peer::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02335 { 02336 char status[30]; 02337 char cbuf[256]; 02338 struct iax2_peer *peer; 02339 char codec_buf[512]; 02340 int x = 0, codec = 0, load_realtime = 0; 02341 02342 if (argc < 4) 02343 return RESULT_SHOWUSAGE; 02344 02345 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02346 02347 peer = find_peer(argv[3], load_realtime); 02348 if (peer) { 02349 ast_cli(fd,"\n\n"); 02350 ast_cli(fd, " * Name : %s\n", peer->name); 02351 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02352 ast_cli(fd, " Context : %s\n", peer->context); 02353 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02354 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02355 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02356 ast_cli(fd, " Expire : %d\n", peer->expire); 02357 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02358 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 02359 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02360 ast_cli(fd, " Username : %s\n", peer->username); 02361 ast_cli(fd, " Codecs : "); 02362 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02363 ast_cli(fd, "%s\n", codec_buf); 02364 02365 ast_cli(fd, " Codec Order : ("); 02366 for(x = 0; x < 32 ; x++) { 02367 codec = ast_codec_pref_index(&peer->prefs,x); 02368 if(!codec) 02369 break; 02370 ast_cli(fd, "%s", ast_getformatname(codec)); 02371 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02372 ast_cli(fd, "|"); 02373 } 02374 02375 if (!x) 02376 ast_cli(fd, "none"); 02377 ast_cli(fd, ")\n"); 02378 02379 ast_cli(fd, " Status : "); 02380 peer_status(peer, status, sizeof(status)); 02381 ast_cli(fd, "%s\n",status); 02382 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02383 ast_cli(fd,"\n"); 02384 peer_unref(peer); 02385 } else { 02386 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02387 ast_cli(fd,"\n"); 02388 } 02389 02390 return RESULT_SUCCESS; 02391 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4701 of file chan_iax2.c.
References __iax2_show_peers().
04702 { 04703 return __iax2_show_peers(0, fd, NULL, argc, argv); 04704 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4773 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.
04774 { 04775 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04776 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04777 struct iax2_registry *reg = NULL; 04778 04779 char host[80]; 04780 char perceived[80]; 04781 if (argc != 3) 04782 return RESULT_SHOWUSAGE; 04783 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04784 AST_LIST_LOCK(®istrations); 04785 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04786 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04787 if (reg->us.sin_addr.s_addr) 04788 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04789 else 04790 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04791 ast_cli(fd, FORMAT, host, 04792 (reg->dnsmgr) ? "Y" : "N", 04793 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04794 } 04795 AST_LIST_UNLOCK(®istrations); 04796 return RESULT_SUCCESS; 04797 #undef FORMAT 04798 #undef FORMAT2 04799 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2418 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02419 { 02420 struct iax_frame *cur; 02421 int cnt = 0, dead=0, final=0; 02422 02423 if (argc != 3) 02424 return RESULT_SHOWUSAGE; 02425 02426 AST_LIST_LOCK(&iaxq.queue); 02427 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02428 if (cur->retries < 0) 02429 dead++; 02430 if (cur->final) 02431 final++; 02432 cnt++; 02433 } 02434 AST_LIST_UNLOCK(&iaxq.queue); 02435 02436 ast_cli(fd, " IAX Statistics\n"); 02437 ast_cli(fd, "---------------------\n"); 02438 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02439 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02440 02441 return RESULT_SUCCESS; 02442 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4642 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.
04643 { 04644 struct iax2_thread *thread = NULL; 04645 time_t t; 04646 int threadcount = 0, dynamiccount = 0; 04647 char type; 04648 04649 if (argc != 3) 04650 return RESULT_SHOWUSAGE; 04651 04652 ast_cli(fd, "IAX2 Thread Information\n"); 04653 time(&t); 04654 ast_cli(fd, "Idle Threads:\n"); 04655 AST_LIST_LOCK(&idle_list); 04656 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04657 #ifdef DEBUG_SCHED_MULTITHREAD 04658 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04659 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04660 #else 04661 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04662 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04663 #endif 04664 threadcount++; 04665 } 04666 AST_LIST_UNLOCK(&idle_list); 04667 ast_cli(fd, "Active Threads:\n"); 04668 AST_LIST_LOCK(&active_list); 04669 AST_LIST_TRAVERSE(&active_list, thread, list) { 04670 if (thread->type == IAX_TYPE_DYNAMIC) 04671 type = 'D'; 04672 else 04673 type = 'P'; 04674 #ifdef DEBUG_SCHED_MULTITHREAD 04675 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04676 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04677 #else 04678 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04679 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04680 #endif 04681 threadcount++; 04682 } 04683 AST_LIST_UNLOCK(&active_list); 04684 ast_cli(fd, "Dynamic Threads:\n"); 04685 AST_LIST_LOCK(&dynamic_list); 04686 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04687 #ifdef DEBUG_SCHED_MULTITHREAD 04688 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04689 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04690 #else 04691 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04692 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04693 #endif 04694 dynamiccount++; 04695 } 04696 AST_LIST_UNLOCK(&dynamic_list); 04697 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04698 return RESULT_SUCCESS; 04699 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4459 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.
04460 { 04461 regex_t regexbuf; 04462 int havepattern = 0; 04463 04464 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04465 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04466 04467 struct iax2_user *user = NULL; 04468 char auth[90]; 04469 char *pstr = ""; 04470 struct ao2_iterator i; 04471 04472 switch (argc) { 04473 case 5: 04474 if (!strcasecmp(argv[3], "like")) { 04475 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04476 return RESULT_SHOWUSAGE; 04477 havepattern = 1; 04478 } else 04479 return RESULT_SHOWUSAGE; 04480 case 3: 04481 break; 04482 default: 04483 return RESULT_SHOWUSAGE; 04484 } 04485 04486 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04487 i = ao2_iterator_init(users, 0); 04488 for (user = ao2_iterator_next(&i); user; 04489 user_unref(user), user = ao2_iterator_next(&i)) { 04490 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04491 continue; 04492 04493 if (!ast_strlen_zero(user->secret)) { 04494 ast_copy_string(auth,user->secret,sizeof(auth)); 04495 } else if (!ast_strlen_zero(user->inkeys)) { 04496 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04497 } else 04498 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04499 04500 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04501 pstr = "REQ Only"; 04502 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04503 pstr = "Disabled"; 04504 else 04505 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04506 04507 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04508 user->contexts ? user->contexts->context : context, 04509 user->ha ? "Yes" : "No", pstr); 04510 } 04511 04512 if (havepattern) 04513 regfree(®exbuf); 04514 04515 return RESULT_SUCCESS; 04516 #undef FORMAT 04517 #undef FORMAT2 04518 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3439 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().
03440 { 03441 int res; 03442 struct iax_ie_data ied0; 03443 struct iax_ie_data ied1; 03444 unsigned int transferid = (unsigned int)ast_random(); 03445 memset(&ied0, 0, sizeof(ied0)); 03446 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03447 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03448 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03449 03450 memset(&ied1, 0, sizeof(ied1)); 03451 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03452 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03453 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03454 03455 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03456 if (res) 03457 return -1; 03458 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03459 if (res) 03460 return -1; 03461 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03462 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03463 return 0; 03464 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2265 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02266 { 02267 if (argc != 4) 02268 return RESULT_SHOWUSAGE; 02269 02270 test_losspct = atoi(argv[3]); 02271 02272 return RESULT_SUCCESS; 02273 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3685 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.
03686 { 03687 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03688 struct iax_ie_data ied; 03689 char tmp[256], *context; 03690 ast_copy_string(tmp, dest, sizeof(tmp)); 03691 context = strchr(tmp, '@'); 03692 if (context) { 03693 *context = '\0'; 03694 context++; 03695 } 03696 memset(&ied, 0, sizeof(ied)); 03697 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03698 if (context) 03699 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03700 if (option_debug) 03701 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03702 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03703 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2724 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iaxq, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02725 { 02726 /* Lock the queue and place this packet at the end */ 02727 /* By setting this to 0, the network thread will send it for us, and 02728 queue retransmission if necessary */ 02729 fr->sentyet = 0; 02730 AST_LIST_LOCK(&iaxq.queue); 02731 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02732 iaxq.count++; 02733 AST_LIST_UNLOCK(&iaxq.queue); 02734 /* Wake up the network and scheduler thread */ 02735 if (netthreadid != AST_PTHREADT_NULL) 02736 pthread_kill(netthreadid, SIGURG); 02737 signal_condition(&sched_lock, &sched_cond); 02738 return 0; 02739 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6567 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06568 { 06569 /* Drop when trunk is about 5 seconds idle */ 06570 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06571 return 1; 06572 return 0; 06573 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4048 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().
04049 { 04050 struct ast_frame *f; 04051 struct iax2_trunk_peer *tpeer; 04052 void *tmp, *ptr; 04053 struct ast_iax2_meta_trunk_entry *met; 04054 struct ast_iax2_meta_trunk_mini *mtm; 04055 04056 f = &fr->af; 04057 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04058 if (tpeer) { 04059 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04060 /* Need to reallocate space */ 04061 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04062 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04063 ast_mutex_unlock(&tpeer->lock); 04064 return -1; 04065 } 04066 04067 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04068 tpeer->trunkdata = tmp; 04069 if (option_debug) 04070 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); 04071 } else { 04072 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)); 04073 ast_mutex_unlock(&tpeer->lock); 04074 return -1; 04075 } 04076 } 04077 04078 /* Append to meta frame */ 04079 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04080 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04081 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04082 mtm->len = htons(f->datalen); 04083 mtm->mini.callno = htons(pvt->callno); 04084 mtm->mini.ts = htons(0xffff & fr->ts); 04085 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04086 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04087 } else { 04088 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04089 /* Store call number and length in meta header */ 04090 met->callno = htons(pvt->callno); 04091 met->len = htons(f->datalen); 04092 /* Advance pointers/decrease length past trunk entry header */ 04093 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04094 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04095 } 04096 /* Copy actual trunk data */ 04097 memcpy(ptr, f->data, f->datalen); 04098 tpeer->trunkdatalen += f->datalen; 04099 04100 tpeer->calls++; 04101 ast_mutex_unlock(&tpeer->lock); 04102 } 04103 return 0; 04104 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6484 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06485 { 06486 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06487 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4991 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.
04992 { 04993 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04994 int res = -1; 04995 ast_mutex_lock(&iaxsl[callno]); 04996 if (iaxs[callno]) { 04997 /* If there's an outstanding error, return failure now */ 04998 if (!iaxs[callno]->error) { 04999 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05000 res = 0; 05001 /* Don't waste bandwidth sending null frames */ 05002 else if (f->frametype == AST_FRAME_NULL) 05003 res = 0; 05004 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05005 res = 0; 05006 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05007 res = 0; 05008 else 05009 /* Simple, just queue for transmission */ 05010 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05011 } else { 05012 if (option_debug) 05013 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05014 } 05015 } 05016 /* If it's already gone, just return */ 05017 ast_mutex_unlock(&iaxsl[callno]); 05018 return res; 05019 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1899 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by update_registry().
01900 { 01901 int res = 0; 01902 struct iax_firmware *cur; 01903 if (!ast_strlen_zero(dev)) { 01904 ast_mutex_lock(&waresl.lock); 01905 cur = waresl.wares; 01906 while(cur) { 01907 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01908 res = ntohs(cur->fwh->version); 01909 break; 01910 } 01911 cur = cur->next; 01912 } 01913 ast_mutex_unlock(&waresl.lock); 01914 } 01915 return res; 01916 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 765 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00766 { 00767 if (iaxdebug) 00768 ast_verbose("%s", data); 00769 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 771 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00772 { 00773 ast_log(LOG_WARNING, "%s", data); 00774 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1918 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.
Referenced by socket_process().
01919 { 01920 int res = -1; 01921 unsigned int bs = desc & 0xff; 01922 unsigned int start = (desc >> 8) & 0xffffff; 01923 unsigned int bytes; 01924 struct iax_firmware *cur; 01925 if (!ast_strlen_zero((char *)dev) && bs) { 01926 start *= bs; 01927 ast_mutex_lock(&waresl.lock); 01928 cur = waresl.wares; 01929 while(cur) { 01930 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01931 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01932 if (start < ntohl(cur->fwh->datalen)) { 01933 bytes = ntohl(cur->fwh->datalen) - start; 01934 if (bytes > bs) 01935 bytes = bs; 01936 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01937 } else { 01938 bytes = 0; 01939 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01940 } 01941 if (bytes == bs) 01942 res = 0; 01943 else 01944 res = 1; 01945 break; 01946 } 01947 cur = cur->next; 01948 } 01949 ast_mutex_unlock(&waresl.lock); 01950 } 01951 return res; 01952 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6755 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().
06756 { 06757 struct iax_dual *d; 06758 struct ast_channel *chan1m, *chan2m; 06759 pthread_t th; 06760 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06761 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06762 if (chan2m && chan1m) { 06763 /* Make formats okay */ 06764 chan1m->readformat = chan1->readformat; 06765 chan1m->writeformat = chan1->writeformat; 06766 ast_channel_masquerade(chan1m, chan1); 06767 /* Setup the extensions and such */ 06768 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06769 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06770 chan1m->priority = chan1->priority; 06771 06772 /* We make a clone of the peer channel too, so we can play 06773 back the announcement */ 06774 /* Make formats okay */ 06775 chan2m->readformat = chan2->readformat; 06776 chan2m->writeformat = chan2->writeformat; 06777 ast_channel_masquerade(chan2m, chan2); 06778 /* Setup the extensions and such */ 06779 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06780 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06781 chan2m->priority = chan2->priority; 06782 if (ast_do_masquerade(chan2m)) { 06783 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06784 ast_hangup(chan2m); 06785 return -1; 06786 } 06787 } else { 06788 if (chan1m) 06789 ast_hangup(chan1m); 06790 if (chan2m) 06791 ast_hangup(chan2m); 06792 return -1; 06793 } 06794 if ((d = ast_calloc(1, sizeof(*d)))) { 06795 pthread_attr_t attr; 06796 06797 pthread_attr_init(&attr); 06798 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06799 06800 d->chan1 = chan1m; 06801 d->chan2 = chan2m; 06802 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06803 pthread_attr_destroy(&attr); 06804 return 0; 06805 } 06806 pthread_attr_destroy(&attr); 06807 free(d); 06808 } 06809 return -1; 06810 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6735 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().
06736 { 06737 struct ast_channel *chan1, *chan2; 06738 struct iax_dual *d; 06739 struct ast_frame *f; 06740 int ext; 06741 int res; 06742 d = stuff; 06743 chan1 = d->chan1; 06744 chan2 = d->chan2; 06745 free(d); 06746 f = ast_read(chan1); 06747 if (f) 06748 ast_frfree(f); 06749 res = ast_park_call(chan1, chan2, 0, &ext); 06750 ast_hangup(chan2); 06751 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06752 return NULL; 06753 }
Definition at line 1413 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process().
01414 { 01415 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01416 if (new) { 01417 size_t afdatalen = new->afdatalen; 01418 memcpy(new, fr, sizeof(*new)); 01419 iax_frame_wrap(new, &fr->af); 01420 new->afdatalen = afdatalen; 01421 new->data = NULL; 01422 new->datalen = 0; 01423 new->direction = DIRECTION_INGRESS; 01424 new->retrans = -1; 01425 } 01426 return new; 01427 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 895 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
00896 { 00897 if (thread->type == IAX_TYPE_DYNAMIC) { 00898 AST_LIST_LOCK(&dynamic_list); 00899 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00900 AST_LIST_UNLOCK(&dynamic_list); 00901 } else { 00902 AST_LIST_LOCK(&idle_list); 00903 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00904 AST_LIST_UNLOCK(&idle_list); 00905 } 00906 00907 return; 00908 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 800 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00801 { 00802 va_list args; 00803 char buf[1024]; 00804 00805 va_start(args, fmt); 00806 vsnprintf(buf, 1024, fmt, args); 00807 va_end(args); 00808 00809 ast_verbose(buf); 00810 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 776 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00777 { 00778 va_list args; 00779 char buf[1024]; 00780 00781 va_start(args, fmt); 00782 vsnprintf(buf, 1024, fmt, args); 00783 va_end(args); 00784 00785 ast_log(LOG_ERROR, buf); 00786 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 788 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00789 { 00790 va_list args; 00791 char buf[1024]; 00792 00793 va_start(args, fmt); 00794 vsnprintf(buf, 1024, fmt, args); 00795 va_end(args); 00796 00797 ast_log(LOG_WARNING, buf); 00798 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11126 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.
11127 { 11128 char *config = "iax.conf"; 11129 int res = 0; 11130 int x; 11131 struct iax2_registry *reg = NULL; 11132 11133 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11134 if (!peers) 11135 return AST_MODULE_LOAD_FAILURE; 11136 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11137 if (!users) { 11138 ao2_ref(peers, -1); 11139 return AST_MODULE_LOAD_FAILURE; 11140 } 11141 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11142 if (!iax_peercallno_pvts) { 11143 ao2_ref(peers, -1); 11144 ao2_ref(users, -1); 11145 return AST_MODULE_LOAD_FAILURE; 11146 } 11147 11148 ast_custom_function_register(&iaxpeer_function); 11149 11150 iax_set_output(iax_debug_output); 11151 iax_set_error(iax_error_output); 11152 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11153 11154 #ifdef HAVE_ZAPTEL 11155 #ifdef ZT_TIMERACK 11156 timingfd = open("/dev/zap/timer", O_RDWR); 11157 if (timingfd < 0) 11158 #endif 11159 timingfd = open("/dev/zap/pseudo", O_RDWR); 11160 if (timingfd < 0) 11161 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11162 #endif 11163 11164 memset(iaxs, 0, sizeof(iaxs)); 11165 11166 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11167 ast_mutex_init(&iaxsl[x]); 11168 } 11169 11170 ast_cond_init(&sched_cond, NULL); 11171 11172 io = io_context_create(); 11173 sched = sched_context_create(); 11174 11175 if (!io || !sched) { 11176 ast_log(LOG_ERROR, "Out of memory\n"); 11177 return -1; 11178 } 11179 11180 netsock = ast_netsock_list_alloc(); 11181 if (!netsock) { 11182 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11183 return -1; 11184 } 11185 ast_netsock_init(netsock); 11186 11187 outsock = ast_netsock_list_alloc(); 11188 if (!outsock) { 11189 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11190 return -1; 11191 } 11192 ast_netsock_init(outsock); 11193 11194 ast_mutex_init(&waresl.lock); 11195 11196 AST_LIST_HEAD_INIT(&iaxq.queue); 11197 11198 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11199 11200 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11201 11202 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11203 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11204 11205 if(set_config(config, 0) == -1) 11206 return AST_MODULE_LOAD_DECLINE; 11207 11208 if (ast_channel_register(&iax2_tech)) { 11209 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11210 __unload_module(); 11211 return -1; 11212 } 11213 11214 if (ast_register_switch(&iax2_switch)) 11215 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11216 11217 res = start_network_thread(); 11218 if (!res) { 11219 if (option_verbose > 1) 11220 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11221 } else { 11222 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11223 ast_netsock_release(netsock); 11224 ast_netsock_release(outsock); 11225 } 11226 11227 AST_LIST_LOCK(®istrations); 11228 AST_LIST_TRAVERSE(®istrations, reg, entry) 11229 iax2_do_register(reg); 11230 AST_LIST_UNLOCK(®istrations); 11231 11232 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11233 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11234 11235 reload_firmware(0); 11236 iax_provision_reload(); 11237 return res; 11238 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3466 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03467 { 03468 ast_mutex_lock(&iaxsl[callno0]); 03469 while (ast_mutex_trylock(&iaxsl[callno1])) { 03470 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03471 } 03472 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1467 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, chan_iax2_pvt::callno, iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01468 { 01469 int x; 01470 int res= 0; 01471 struct timeval now; 01472 if (iaxs[callno]->oseqno) { 01473 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01474 return -1; 01475 } 01476 if (callno & TRUNK_CALL_START) { 01477 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01478 return -1; 01479 } 01480 gettimeofday(&now, NULL); 01481 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01482 ast_mutex_lock(&iaxsl[x]); 01483 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01484 iaxs[x] = iaxs[callno]; 01485 iaxs[x]->callno = x; 01486 iaxs[callno] = NULL; 01487 /* Update the two timers that should have been started */ 01488 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01489 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01490 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01491 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01492 if (locked) 01493 ast_mutex_unlock(&iaxsl[callno]); 01494 res = x; 01495 if (!locked) 01496 ast_mutex_unlock(&iaxsl[x]); 01497 break; 01498 } 01499 ast_mutex_unlock(&iaxsl[x]); 01500 } 01501 if (x >= ARRAY_LEN(iaxs) - 1) { 01502 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01503 return -1; 01504 } 01505 if (option_debug) 01506 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01507 /* We move this call from a non-trunked to a trunked call */ 01508 update_max_trunk(); 01509 update_max_nontrunk(); 01510 return res; 01511 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4705 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
04706 { 04707 ast_cli_netstats(s, -1, 0); 04708 astman_append(s, "\r\n"); 04709 return RESULT_SUCCESS; 04710 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4738 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by load_module().
04739 { 04740 char *a[] = { "iax2", "show", "users" }; 04741 int ret; 04742 const char *id = astman_get_header(m,"ActionID"); 04743 04744 if (!ast_strlen_zero(id)) 04745 astman_append(s, "ActionID: %s\r\n",id); 04746 ret = __iax2_show_peers(1, -1, s, 3, a ); 04747 astman_append(s, "\r\n\r\n" ); 04748 return ret; 04749 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1433 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and softhangup_exec().
01434 { 01435 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01436 (cur->addr.sin_port == sin->sin_port)) { 01437 /* This is the main host */ 01438 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01439 (check_dcallno ? dcallno == cur->callno : 1) ) { 01440 /* That's us. Be sure we keep track of the peer call number */ 01441 return 1; 01442 } 01443 } 01444 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01445 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01446 /* We're transferring */ 01447 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01448 return 1; 01449 } 01450 return 0; 01451 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4112 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04113 { 04114 #if 0 04115 /* Debug with "fake encryption" */ 04116 int x; 04117 if (len % 16) 04118 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04119 for (x=0;x<len;x++) 04120 dst[x] = src[x] ^ 0xff; 04121 #else 04122 unsigned char lastblock[16] = { 0 }; 04123 int x; 04124 while(len > 0) { 04125 aes_decrypt(src, dst, dcx); 04126 for (x=0;x<16;x++) 04127 dst[x] ^= lastblock[x]; 04128 memcpy(lastblock, src, sizeof(lastblock)); 04129 dst += 16; 04130 src += 16; 04131 len -= 16; 04132 } 04133 #endif 04134 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4136 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04137 { 04138 #if 0 04139 /* Debug with "fake encryption" */ 04140 int x; 04141 if (len % 16) 04142 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04143 for (x=0;x<len;x++) 04144 dst[x] = src[x] ^ 0xff; 04145 #else 04146 unsigned char curblock[16] = { 0 }; 04147 int x; 04148 while(len > 0) { 04149 for (x=0;x<16;x++) 04150 curblock[x] ^= src[x]; 04151 aes_encrypt(curblock, dst, ecx); 04152 memcpy(curblock, dst, sizeof(curblock)); 04153 dst += 16; 04154 src += 16; 04155 len -= 16; 04156 } 04157 #endif 04158 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5328 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05329 { 05330 /* Select exactly one common encryption if there are any */ 05331 p->encmethods &= enc; 05332 if (p->encmethods) { 05333 if (p->encmethods & IAX_ENCRYPT_AES128) 05334 p->encmethods = IAX_ENCRYPT_AES128; 05335 else 05336 p->encmethods = 0; 05337 } 05338 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9099 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().
09100 { 09101 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09102 from the network, and queue them for delivery to the channels */ 09103 int res, count, wakeup; 09104 struct iax_frame *f; 09105 09106 if (timingfd > -1) 09107 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09108 09109 for(;;) { 09110 pthread_testcancel(); 09111 09112 /* Go through the queue, sending messages which have not yet been 09113 sent, and scheduling retransmissions if appropriate */ 09114 AST_LIST_LOCK(&iaxq.queue); 09115 count = 0; 09116 wakeup = -1; 09117 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09118 if (f->sentyet) 09119 continue; 09120 09121 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09122 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09123 wakeup = 1; 09124 continue; 09125 } 09126 09127 f->sentyet++; 09128 09129 if (iaxs[f->callno]) { 09130 send_packet(f); 09131 count++; 09132 } 09133 09134 ast_mutex_unlock(&iaxsl[f->callno]); 09135 09136 if (f->retries < 0) { 09137 /* This is not supposed to be retransmitted */ 09138 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09139 iaxq.count--; 09140 /* Free the iax frame */ 09141 iax_frame_free(f); 09142 } else { 09143 /* We need reliable delivery. Schedule a retransmission */ 09144 f->retries++; 09145 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09146 } 09147 } 09148 AST_LIST_TRAVERSE_SAFE_END 09149 AST_LIST_UNLOCK(&iaxq.queue); 09150 09151 pthread_testcancel(); 09152 09153 if (option_debug && count >= 20) 09154 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09155 09156 /* Now do the IO, and run scheduled tasks */ 09157 res = ast_io_wait(io, wakeup); 09158 if (res >= 0) { 09159 if (option_debug && res >= 20) 09160 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09161 } 09162 } 09163 return NULL; 09164 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1374 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, exten, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno.
Referenced by __find_callno().
01375 { 01376 struct chan_iax2_pvt *tmp; 01377 jb_conf jbconf; 01378 01379 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01380 return NULL; 01381 } 01382 01383 if (ast_string_field_init(tmp, 32)) { 01384 ao2_ref(tmp, -1); 01385 tmp = NULL; 01386 return NULL; 01387 } 01388 01389 tmp->prefs = prefs; 01390 tmp->callno = 0; 01391 tmp->peercallno = 0; 01392 tmp->transfercallno = 0; 01393 tmp->bridgecallno = 0; 01394 tmp->pingid = -1; 01395 tmp->lagid = -1; 01396 tmp->autoid = -1; 01397 tmp->authid = -1; 01398 tmp->initid = -1; 01399 01400 ast_string_field_set(tmp,exten, "s"); 01401 ast_string_field_set(tmp,host, host); 01402 01403 tmp->jb = jb_new(); 01404 tmp->jbid = -1; 01405 jbconf.max_jitterbuf = maxjitterbuffer; 01406 jbconf.resync_threshold = resyncthreshold; 01407 jbconf.max_contig_interp = maxjitterinterps; 01408 jb_setconf(tmp->jb,&jbconf); 01409 01410 return tmp; 01411 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 3184 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
03185 { 03186 if (ast_strlen_zero(data)) 03187 return; 03188 03189 pds->peer = strsep(&data, "/"); 03190 pds->exten = strsep(&data, "/"); 03191 pds->options = data; 03192 03193 if (pds->exten) { 03194 data = pds->exten; 03195 pds->exten = strsep(&data, "@"); 03196 pds->context = data; 03197 } 03198 03199 if (strchr(pds->peer, '@')) { 03200 data = pds->peer; 03201 pds->username = strsep(&data, "@"); 03202 pds->peer = data; 03203 } 03204 03205 if (pds->username) { 03206 data = pds->username; 03207 pds->username = strsep(&data, ":"); 03208 pds->password = data; 03209 } 03210 03211 data = pds->peer; 03212 pds->peer = strsep(&data, ":"); 03213 pds->port = data; 03214 03215 /* check for a key name wrapped in [] in the secret position, if found, 03216 move it to the key field instead 03217 */ 03218 if (pds->password && (pds->password[0] == '[')) { 03219 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03220 pds->password = NULL; 03221 } 03222 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1112 of file chan_iax2.c.
Referenced by load_module().
01113 { 01114 struct iax2_peer *peer = obj, *peer2 = arg; 01115 01116 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01117 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9797 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09798 { 09799 struct iax2_peer *peer = obj; 09800 09801 ast_set_flag(peer, IAX_DELME); 09802 09803 return 0; 09804 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9322 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().
09323 { 09324 struct iax2_peer *peer = obj; 09325 09326 ast_free_ha(peer->ha); 09327 09328 if (peer->callno > 0) { 09329 ast_mutex_lock(&iaxsl[peer->callno]); 09330 iax2_destroy(peer->callno); 09331 ast_mutex_unlock(&iaxsl[peer->callno]); 09332 } 09333 09334 register_peer_exten(peer, 0); 09335 09336 if (peer->dnsmgr) 09337 ast_dnsmgr_release(peer->dnsmgr); 09338 09339 ast_string_field_free_memory(peer); 09340 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1102 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01103 { 01104 const struct iax2_peer *peer = obj; 01105 01106 return ast_str_hash(peer->name); 01107 }
Definition at line 1159 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01160 { 01161 ao2_ref(peer, +1); 01162 return peer; 01163 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11097 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11098 { 11099 struct iax2_peer *peer = obj; 11100 11101 if (peer->sockfd < 0) 11102 peer->sockfd = defaultsockfd; 11103 11104 return 0; 11105 }
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 9249 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().
09250 { 09251 struct sockaddr_in sin; 09252 int nonlocal = 1; 09253 int port = IAX_DEFAULT_PORTNO; 09254 int sockfd = defaultsockfd; 09255 char *tmp; 09256 char *addr; 09257 char *portstr; 09258 09259 if (!(tmp = ast_strdupa(srcaddr))) 09260 return -1; 09261 09262 addr = strsep(&tmp, ":"); 09263 portstr = tmp; 09264 09265 if (portstr) { 09266 port = atoi(portstr); 09267 if (port < 1) 09268 port = IAX_DEFAULT_PORTNO; 09269 } 09270 09271 if (!ast_get_ip(&sin, addr)) { 09272 struct ast_netsock *sock; 09273 int res; 09274 09275 sin.sin_port = 0; 09276 sin.sin_family = AF_INET; 09277 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09278 if (res == 0) { 09279 /* ip address valid. */ 09280 sin.sin_port = htons(port); 09281 if (!(sock = ast_netsock_find(netsock, &sin))) 09282 sock = ast_netsock_find(outsock, &sin); 09283 if (sock) { 09284 sockfd = ast_netsock_sockfd(sock); 09285 nonlocal = 0; 09286 } else { 09287 unsigned int orig_saddr = sin.sin_addr.s_addr; 09288 /* INADDR_ANY matches anyway! */ 09289 sin.sin_addr.s_addr = INADDR_ANY; 09290 if (ast_netsock_find(netsock, &sin)) { 09291 sin.sin_addr.s_addr = orig_saddr; 09292 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09293 if (sock) { 09294 sockfd = ast_netsock_sockfd(sock); 09295 ast_netsock_unref(sock); 09296 nonlocal = 0; 09297 } else { 09298 nonlocal = 2; 09299 } 09300 } 09301 } 09302 } 09303 } 09304 09305 peer->sockfd = sockfd; 09306 09307 if (nonlocal == 1) { 09308 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09309 srcaddr, peer->name); 09310 return -1; 09311 } else if (nonlocal == 2) { 09312 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09313 srcaddr, peer->name); 09314 return -1; 09315 } else { 09316 if (option_debug) 09317 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09318 return 0; 09319 } 09320 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2311 of file chan_iax2.c.
References iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer().
02312 { 02313 int res = 0; 02314 if (peer->maxms) { 02315 if (peer->lastms < 0) { 02316 ast_copy_string(status, "UNREACHABLE", statuslen); 02317 } else if (peer->lastms > peer->maxms) { 02318 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02319 res = 1; 02320 } else if (peer->lastms) { 02321 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02322 res = 1; 02323 } else { 02324 ast_copy_string(status, "UNKNOWN", statuslen); 02325 } 02326 } else { 02327 ast_copy_string(status, "Unmonitored", statuslen); 02328 res = -1; 02329 } 02330 return res; 02331 }
Definition at line 1165 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01166 { 01167 ao2_ref(peer, -1); 01168 return NULL; 01169 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10258 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10259 { 10260 struct ao2_iterator i; 10261 struct iax2_peer *peer; 10262 10263 i = ao2_iterator_init(peers, 0); 10264 while ((peer = ao2_iterator_next(&i))) { 10265 iax2_poke_peer(peer, 0); 10266 peer_unref(peer); 10267 } 10268 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9855 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09856 { 09857 struct iax2_peer *peer; 09858 struct ao2_iterator i; 09859 09860 i = ao2_iterator_init(peers, 0); 09861 while ((peer = ao2_iterator_next(&i))) { 09862 if (ast_test_flag(peer, IAX_DELME)) 09863 unlink_peer(peer); 09864 peer_unref(peer); 09865 } 09866 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9841 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().
09842 { 09843 struct iax2_user *user; 09844 struct ao2_iterator i; 09845 09846 i = ao2_iterator_init(users, 0); 09847 while ((user = ao2_iterator_next(&i))) { 09848 if (ast_test_flag(user, IAX_DELME)) 09849 ao2_unlink(users, user); 09850 user_unref(user); 09851 } 09852 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11114 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11115 { 11116 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11117 11118 /* The frames_received field is used to hold whether we're matching 11119 * against a full frame or not ... */ 11120 11121 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11122 pvt2->frames_received) ? CMP_MATCH : 0; 11123 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1335 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and chan_iax2_pvt::vars.
Referenced by new_iax().
01336 { 01337 struct chan_iax2_pvt *pvt = obj; 01338 struct iax_frame *cur = NULL; 01339 01340 iax2_destroy_helper(pvt); 01341 01342 /* Already gone */ 01343 ast_set_flag(pvt, IAX_ALREADYGONE); 01344 01345 AST_LIST_LOCK(&iaxq.queue); 01346 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01347 /* Cancel any pending transmissions */ 01348 if (cur->callno == pvt->callno) { 01349 cur->retries = -1; 01350 } 01351 } 01352 AST_LIST_UNLOCK(&iaxq.queue); 01353 01354 if (pvt->reg) { 01355 pvt->reg->callno = 0; 01356 } 01357 01358 if (!pvt->owner) { 01359 jb_frame frame; 01360 if (pvt->vars) { 01361 ast_variables_destroy(pvt->vars); 01362 pvt->vars = NULL; 01363 } 01364 01365 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01366 iax2_frame_free(frame.data); 01367 } 01368 01369 jb_destroy(pvt->jb); 01370 ast_string_field_free_memory(pvt); 01371 } 01372 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11107 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11108 { 11109 const struct chan_iax2_pvt *pvt = obj; 11110 11111 return pvt->peercallno; 11112 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5310 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().
05311 { 05312 struct ast_iax2_full_hdr fh; 05313 fh.scallno = htons(src | IAX_FLAG_FULL); 05314 fh.dcallno = htons(dst); 05315 fh.ts = 0; 05316 fh.oseqno = 0; 05317 fh.iseqno = 0; 05318 fh.type = AST_FRAME_IAX; 05319 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05320 if (iaxdebug) 05321 iax_showframe(NULL, &fh, 0, sin, 0); 05322 if (option_debug) 05323 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05324 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05325 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05326 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2786 of file chan_iax2.c.
References iax2_peer::addr, ast_copy_flags, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_DEBUG, ast_variable::name, ast_variable::next, option_debug, peer_ref(), peer_unref(), peers, realtime_update_peer(), reg_source_db(), ast_variable::value, and var.
02787 { 02788 struct ast_variable *var = NULL; 02789 struct ast_variable *tmp; 02790 struct iax2_peer *peer=NULL; 02791 time_t regseconds = 0, nowtime; 02792 int dynamic=0; 02793 02794 if (peername) { 02795 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02796 if (!var && sin) 02797 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02798 } else if (sin) { 02799 char porta[25]; 02800 sprintf(porta, "%d", ntohs(sin->sin_port)); 02801 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02802 if (var) { 02803 /* We'll need the peer name in order to build the structure! */ 02804 for (tmp = var; tmp; tmp = tmp->next) { 02805 if (!strcasecmp(tmp->name, "name")) 02806 peername = tmp->value; 02807 } 02808 } 02809 } 02810 if (!var && peername) { /* Last ditch effort */ 02811 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02812 /*!\note 02813 * If this one loaded something, then we need to ensure that the host 02814 * field matched. The only reason why we can't have this as a criteria 02815 * is because we only have the IP address and the host field might be 02816 * set as a name (and the reverse PTR might not match). 02817 */ 02818 if (var && sin) { 02819 for (tmp = var; tmp; tmp = tmp->next) { 02820 if (!strcasecmp(tmp->name, "host")) { 02821 struct ast_hostent ahp; 02822 struct hostent *hp; 02823 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02824 /* No match */ 02825 ast_variables_destroy(var); 02826 var = NULL; 02827 } 02828 break; 02829 } 02830 } 02831 } 02832 } 02833 if (!var) 02834 return NULL; 02835 02836 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02837 02838 if (!peer) { 02839 ast_variables_destroy(var); 02840 return NULL; 02841 } 02842 02843 for (tmp = var; tmp; tmp = tmp->next) { 02844 /* Make sure it's not a user only... */ 02845 if (!strcasecmp(tmp->name, "type")) { 02846 if (strcasecmp(tmp->value, "friend") && 02847 strcasecmp(tmp->value, "peer")) { 02848 /* Whoops, we weren't supposed to exist! */ 02849 peer = peer_unref(peer); 02850 break; 02851 } 02852 } else if (!strcasecmp(tmp->name, "regseconds")) { 02853 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02854 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02855 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02856 } else if (!strcasecmp(tmp->name, "port")) { 02857 peer->addr.sin_port = htons(atoi(tmp->value)); 02858 } else if (!strcasecmp(tmp->name, "host")) { 02859 if (!strcasecmp(tmp->value, "dynamic")) 02860 dynamic = 1; 02861 } 02862 } 02863 02864 ast_variables_destroy(var); 02865 02866 if (!peer) 02867 return NULL; 02868 02869 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02870 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02871 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02872 if (peer->expire > -1) { 02873 if (!ast_sched_del(sched, peer->expire)) { 02874 peer->expire = -1; 02875 peer_unref(peer); 02876 } 02877 } 02878 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02879 if (peer->expire == -1) 02880 peer_unref(peer); 02881 } 02882 ao2_link(peers, peer); 02883 if (ast_test_flag(peer, IAX_DYNAMIC)) 02884 reg_source_db(peer); 02885 } else { 02886 ast_set_flag(peer, IAX_TEMPONLY); 02887 } 02888 02889 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02890 time(&nowtime); 02891 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02892 memset(&peer->addr, 0, sizeof(peer->addr)); 02893 realtime_update_peer(peer->name, &peer->addr, 0); 02894 if (option_debug) 02895 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02896 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02897 } 02898 else { 02899 if (option_debug) 02900 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02901 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02902 } 02903 } 02904 02905 return peer; 02906 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2979 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
02980 { 02981 char port[10]; 02982 char regseconds[20]; 02983 02984 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02985 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02986 ast_update_realtime("iaxpeers", "name", peername, 02987 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02988 "regseconds", regseconds, NULL); 02989 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2908 of file chan_iax2.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, users, ast_variable::value, and var.
02909 { 02910 struct ast_variable *var; 02911 struct ast_variable *tmp; 02912 struct iax2_user *user=NULL; 02913 02914 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02915 if (!var) 02916 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02917 if (!var && sin) { 02918 char porta[6]; 02919 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02920 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02921 if (!var) 02922 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02923 } 02924 if (!var) { /* Last ditch effort */ 02925 var = ast_load_realtime("iaxusers", "name", username, NULL); 02926 /*!\note 02927 * If this one loaded something, then we need to ensure that the host 02928 * field matched. The only reason why we can't have this as a criteria 02929 * is because we only have the IP address and the host field might be 02930 * set as a name (and the reverse PTR might not match). 02931 */ 02932 if (var) { 02933 for (tmp = var; tmp; tmp = tmp->next) { 02934 if (!strcasecmp(tmp->name, "host")) { 02935 struct ast_hostent ahp; 02936 struct hostent *hp; 02937 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02938 /* No match */ 02939 ast_variables_destroy(var); 02940 var = NULL; 02941 } 02942 break; 02943 } 02944 } 02945 } 02946 } 02947 if (!var) 02948 return NULL; 02949 02950 tmp = var; 02951 while(tmp) { 02952 /* Make sure it's not a peer only... */ 02953 if (!strcasecmp(tmp->name, "type")) { 02954 if (strcasecmp(tmp->value, "friend") && 02955 strcasecmp(tmp->value, "user")) { 02956 return NULL; 02957 } 02958 } 02959 tmp = tmp->next; 02960 } 02961 02962 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02963 02964 ast_variables_destroy(var); 02965 02966 if (!user) 02967 return NULL; 02968 02969 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02970 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02971 ao2_link(users, user); 02972 } else { 02973 ast_set_flag(user, IAX_TEMPONLY); 02974 } 02975 02976 return user; 02977 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6114 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().
06115 { 06116 char data[80]; 06117 struct in_addr in; 06118 char *c, *d; 06119 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06120 c = strchr(data, ':'); 06121 if (c) { 06122 *c = '\0'; 06123 c++; 06124 if (inet_aton(data, &in)) { 06125 d = strchr(c, ':'); 06126 if (d) { 06127 *d = '\0'; 06128 d++; 06129 if (option_verbose > 2) 06130 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06131 ast_inet_ntoa(in), atoi(c), atoi(d)); 06132 iax2_poke_peer(p, 0); 06133 p->expiry = atoi(d); 06134 memset(&p->addr, 0, sizeof(p->addr)); 06135 p->addr.sin_family = AF_INET; 06136 p->addr.sin_addr = in; 06137 p->addr.sin_port = htons(atoi(c)); 06138 if (p->expire > -1) { 06139 if (!ast_sched_del(sched, p->expire)) { 06140 p->expire = -1; 06141 peer_unref(p); 06142 } 06143 } 06144 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06145 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06146 if (p->expire == -1) 06147 peer_unref(p); 06148 if (iax2_regfunk) 06149 iax2_regfunk(p->name, 1); 06150 register_peer_exten(p, 1); 06151 } 06152 06153 } 06154 } 06155 } 06156 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6034 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().
06035 { 06036 char multi[256]; 06037 char *stringp, *ext; 06038 if (!ast_strlen_zero(regcontext)) { 06039 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06040 stringp = multi; 06041 while((ext = strsep(&stringp, "&"))) { 06042 if (onoff) { 06043 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06044 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06045 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06046 } else 06047 ast_context_remove_extension(regcontext, ext, 1, NULL); 06048 } 06049 } 06050 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5477 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().
05478 { 05479 char requeststr[256] = ""; 05480 char peer[256] = ""; 05481 char md5secret[256] = ""; 05482 char rsasecret[256] = ""; 05483 char secret[256] = ""; 05484 struct iax2_peer *p = NULL; 05485 struct ast_key *key; 05486 char *keyn; 05487 int x; 05488 int expire = 0; 05489 int res = -1; 05490 05491 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05492 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05493 if (ies->username) 05494 ast_copy_string(peer, ies->username, sizeof(peer)); 05495 if (ies->password) 05496 ast_copy_string(secret, ies->password, sizeof(secret)); 05497 if (ies->md5_result) 05498 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05499 if (ies->rsa_result) 05500 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05501 if (ies->refresh) 05502 expire = ies->refresh; 05503 05504 if (ast_strlen_zero(peer)) { 05505 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05506 return -1; 05507 } 05508 05509 /* SLD: first call to lookup peer during registration */ 05510 ast_mutex_unlock(&iaxsl[callno]); 05511 p = find_peer(peer, 1); 05512 ast_mutex_lock(&iaxsl[callno]); 05513 if (!p || !iaxs[callno]) { 05514 if (iaxs[callno]) { 05515 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 05516 05517 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05518 05519 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 05520 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 05521 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 05522 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 05523 * to be plaintext, indicating it is an authmethod used by other peers on the system. 05524 * 05525 * If none of these cases exist, res will be returned as 0 without authentication indicating 05526 * an AUTHREQ needs to be sent out. */ 05527 05528 if (ast_strlen_zero(iaxs[callno]->challenge) && 05529 !(!ast_strlen_zero(secret) && plaintext)) { 05530 /* by setting res to 0, an REGAUTH will be sent */ 05531 res = 0; 05532 } 05533 } 05534 if (authdebug && !p) 05535 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05536 05537 goto return_unref; 05538 } 05539 05540 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05541 if (authdebug) 05542 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05543 goto return_unref; 05544 } 05545 05546 if (!ast_apply_ha(p->ha, sin)) { 05547 if (authdebug) 05548 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05549 goto return_unref; 05550 } 05551 ast_string_field_set(iaxs[callno], secret, p->secret); 05552 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05553 /* Check secret against what we have on file */ 05554 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05555 if (!ast_strlen_zero(p->inkeys)) { 05556 char tmpkeys[256]; 05557 char *stringp=NULL; 05558 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05559 stringp=tmpkeys; 05560 keyn = strsep(&stringp, ":"); 05561 while(keyn) { 05562 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05563 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05564 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05565 break; 05566 } else if (!key) 05567 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05568 keyn = strsep(&stringp, ":"); 05569 } 05570 if (!keyn) { 05571 if (authdebug) 05572 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05573 goto return_unref; 05574 } 05575 } else { 05576 if (authdebug) 05577 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05578 goto return_unref; 05579 } 05580 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05581 struct MD5Context md5; 05582 unsigned char digest[16]; 05583 char *tmppw, *stringp; 05584 05585 tmppw = ast_strdupa(p->secret); 05586 stringp = tmppw; 05587 while((tmppw = strsep(&stringp, ";"))) { 05588 MD5Init(&md5); 05589 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05590 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05591 MD5Final(digest, &md5); 05592 for (x=0;x<16;x++) 05593 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05594 if (!strcasecmp(requeststr, md5secret)) 05595 break; 05596 } 05597 if (tmppw) { 05598 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05599 } else { 05600 if (authdebug) 05601 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05602 goto return_unref; 05603 } 05604 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05605 /* They've provided a plain text password and we support that */ 05606 if (strcmp(secret, p->secret)) { 05607 if (authdebug) 05608 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05609 goto return_unref; 05610 } else 05611 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05612 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 05613 /* if challenge has been sent, but no challenge response if given, reject. */ 05614 goto return_unref; 05615 } 05616 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05617 05618 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 05619 res = 0; 05620 return_unref: 05621 if (iaxs[callno]) { 05622 ast_string_field_set(iaxs[callno], peer, peer); 05623 } 05624 /* Choose lowest expiry number */ 05625 if (expire && (expire < iaxs[callno]->expiry)) { 05626 iaxs[callno]->expiry = expire; 05627 } 05628 05629 if (p) 05630 peer_unref(p); 05631 return res; 05632 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6293 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().
06294 { 06295 struct iax_ie_data ied; 06296 struct iax2_peer *p; 06297 char challenge[10]; 06298 const char *peer_name; 06299 int sentauthmethod; 06300 06301 peer_name = ast_strdupa(iaxs[callno]->peer); 06302 06303 /* SLD: third call to find_peer in registration */ 06304 ast_mutex_unlock(&iaxsl[callno]); 06305 if ((p = find_peer(peer_name, 1))) { 06306 last_authmethod = p->authmethods; 06307 } 06308 06309 ast_mutex_lock(&iaxsl[callno]); 06310 if (!iaxs[callno]) 06311 goto return_unref; 06312 06313 memset(&ied, 0, sizeof(ied)); 06314 /* The selection of which delayed reject is sent may leak information, 06315 * if it sets a static response. For example, if a host is known to only 06316 * use MD5 authentication, then an RSA response would indicate that the 06317 * peer does not exist, and vice-versa. 06318 * Therefore, we use whatever the last peer used (which may vary over the 06319 * course of a server, which should leak minimal information). */ 06320 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06321 if (!p) { 06322 iaxs[callno]->authmethods = sentauthmethod; 06323 } 06324 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06325 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06326 /* Build the challenge */ 06327 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06328 ast_string_field_set(iaxs[callno], challenge, challenge); 06329 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06330 } 06331 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06332 06333 return_unref: 06334 if (p) { 06335 peer_unref(p); 06336 } 06337 06338 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06339 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6341 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().
06342 { 06343 struct iax2_registry *reg; 06344 /* Start pessimistic */ 06345 struct iax_ie_data ied; 06346 char peer[256] = ""; 06347 char challenge[256] = ""; 06348 int res; 06349 int authmethods = 0; 06350 if (ies->authmethods) 06351 authmethods = ies->authmethods; 06352 if (ies->username) 06353 ast_copy_string(peer, ies->username, sizeof(peer)); 06354 if (ies->challenge) 06355 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06356 memset(&ied, 0, sizeof(ied)); 06357 reg = iaxs[callno]->reg; 06358 if (reg) { 06359 if (inaddrcmp(®->addr, sin)) { 06360 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06361 return -1; 06362 } 06363 if (ast_strlen_zero(reg->secret)) { 06364 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06365 reg->regstate = REG_STATE_NOAUTH; 06366 return -1; 06367 } 06368 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06369 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06370 if (reg->secret[0] == '[') { 06371 char tmpkey[256]; 06372 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06373 tmpkey[strlen(tmpkey) - 1] = '\0'; 06374 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06375 } else 06376 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06377 if (!res) { 06378 reg->regstate = REG_STATE_AUTHSENT; 06379 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06380 } else 06381 return -1; 06382 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06383 } else 06384 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06385 return -1; 06386 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4751 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().
04752 { 04753 switch(regstate) { 04754 case REG_STATE_UNREGISTERED: 04755 return "Unregistered"; 04756 case REG_STATE_REGSENT: 04757 return "Request Sent"; 04758 case REG_STATE_AUTHSENT: 04759 return "Auth. Sent"; 04760 case REG_STATE_REGISTERED: 04761 return "Registered"; 04762 case REG_STATE_REJECTED: 04763 return "Rejected"; 04764 case REG_STATE_TIMEOUT: 04765 return "Timeout"; 04766 case REG_STATE_NOAUTH: 04767 return "No Authentication"; 04768 default: 04769 return "Unknown"; 04770 } 04771 }
static int reload | ( | void | ) | [static] |
Definition at line 10295 of file chan_iax2.c.
References reload_config().
10296 { 10297 return reload_config(); 10298 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10269 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().
10270 { 10271 char *config = "iax.conf"; 10272 struct iax2_registry *reg; 10273 10274 if (set_config(config, 1) > 0) { 10275 prune_peers(); 10276 prune_users(); 10277 AST_LIST_LOCK(®istrations); 10278 AST_LIST_TRAVERSE(®istrations, reg, entry) 10279 iax2_do_register(reg); 10280 AST_LIST_UNLOCK(®istrations); 10281 /* Qualify hosts, too */ 10282 poke_all_peers(); 10283 } 10284 reload_firmware(0); 10285 iax_provision_reload(); 10286 10287 return 0; 10288 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1955 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), errno, ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by __unload_module(), load_module(), and reload_config().
01956 { 01957 struct iax_firmware *cur, *curl, *curp; 01958 DIR *fwd; 01959 struct dirent *de; 01960 char dir[256]; 01961 char fn[256]; 01962 /* Mark all as dead */ 01963 ast_mutex_lock(&waresl.lock); 01964 cur = waresl.wares; 01965 while(cur) { 01966 cur->dead = 1; 01967 cur = cur->next; 01968 } 01969 01970 /* Now that we've freed them, load the new ones */ 01971 if (!unload) { 01972 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01973 fwd = opendir(dir); 01974 if (fwd) { 01975 while((de = readdir(fwd))) { 01976 if (de->d_name[0] != '.') { 01977 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01978 if (!try_firmware(fn)) { 01979 if (option_verbose > 1) 01980 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01981 } 01982 } 01983 } 01984 closedir(fwd); 01985 } else 01986 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01987 } 01988 01989 /* Clean up leftovers */ 01990 cur = waresl.wares; 01991 curp = NULL; 01992 while(cur) { 01993 curl = cur; 01994 cur = cur->next; 01995 if (curl->dead) { 01996 if (curp) { 01997 curp->next = cur; 01998 } else { 01999 waresl.wares = cur; 02000 } 02001 destroy_firmware(curl); 02002 } else { 02003 curp = cur; 02004 } 02005 } 02006 ast_mutex_unlock(&waresl.lock); 02007 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1250 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), and socket_process().
01251 { 01252 if (!pvt->peercallno) { 01253 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01254 return; 01255 } 01256 01257 ao2_unlink(iax_peercallno_pvts, pvt); 01258 }
Definition at line 6845 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().
06846 { 06847 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06848 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06849 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06850 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06851 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06852 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06853 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06854 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9071 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().
09072 { 09073 int count; 09074 int res; 09075 struct timeval tv; 09076 struct timespec ts; 09077 09078 for (;;) { 09079 res = ast_sched_wait(sched); 09080 if ((res > 1000) || (res < 0)) 09081 res = 1000; 09082 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09083 ts.tv_sec = tv.tv_sec; 09084 ts.tv_nsec = tv.tv_usec * 1000; 09085 09086 pthread_testcancel(); 09087 ast_mutex_lock(&sched_lock); 09088 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09089 ast_mutex_unlock(&sched_lock); 09090 pthread_testcancel(); 09091 09092 count = ast_sched_runq(sched); 09093 if (option_debug && count >= 20) 09094 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09095 } 09096 return NULL; 09097 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 2639 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), AST_SCHED_DEL, ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02640 { 02641 int type, len; 02642 int ret; 02643 int needfree = 0; 02644 struct ast_channel *owner = NULL; 02645 struct ast_channel *bridge = NULL; 02646 02647 /* Attempt to recover wrapped timestamps */ 02648 unwrap_timestamp(fr); 02649 02650 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02651 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02652 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02653 else { 02654 #if 0 02655 if (option_debug) 02656 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02657 #endif 02658 fr->af.delivery = ast_tv(0,0); 02659 } 02660 02661 type = JB_TYPE_CONTROL; 02662 len = 0; 02663 02664 if(fr->af.frametype == AST_FRAME_VOICE) { 02665 type = JB_TYPE_VOICE; 02666 len = ast_codec_get_samples(&fr->af) / 8; 02667 } else if(fr->af.frametype == AST_FRAME_CNG) { 02668 type = JB_TYPE_SILENCE; 02669 } 02670 02671 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02672 if (tsout) 02673 *tsout = fr->ts; 02674 __do_deliver(fr); 02675 return -1; 02676 } 02677 02678 if ((owner = iaxs[fr->callno]->owner)) 02679 bridge = ast_bridged_channel(owner); 02680 02681 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02682 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02683 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02684 jb_frame frame; 02685 02686 /* deliver any frames in the jb */ 02687 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02688 __do_deliver(frame.data); 02689 /* __do_deliver() can make the call disappear */ 02690 if (!iaxs[fr->callno]) 02691 return -1; 02692 } 02693 02694 jb_reset(iaxs[fr->callno]->jb); 02695 02696 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02697 02698 /* deliver this frame now */ 02699 if (tsout) 02700 *tsout = fr->ts; 02701 __do_deliver(fr); 02702 return -1; 02703 } 02704 02705 /* insert into jitterbuffer */ 02706 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02707 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02708 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02709 if (ret == JB_DROP) { 02710 needfree++; 02711 } else if (ret == JB_SCHED) { 02712 update_jbsched(iaxs[fr->callno]); 02713 } 02714 if (tsout) 02715 *tsout = fr->ts; 02716 if (needfree) { 02717 /* Free our iax frame */ 02718 iax2_frame_free(fr); 02719 return -1; 02720 } 02721 return 0; 02722 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno | |||
) | [static] |
Definition at line 3157 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and ast_iax2_full_hdr::scallno.
Referenced by socket_process().
03158 { 03159 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03160 .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX, 03161 .csub = compress_subclass(command) }; 03162 03163 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03164 }
static int send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 5035 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().
05036 { 05037 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05038 }
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 5054 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().
05055 { 05056 int call_num = i->callno; 05057 /* It is assumed that the callno has already been locked */ 05058 iax2_predestroy(i->callno); 05059 if (!iaxs[call_num]) 05060 return -1; 05061 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05062 }
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 5064 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05065 { 05066 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05067 }
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 5040 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().
05041 { 05042 int res; 05043 ast_mutex_lock(&iaxsl[callno]); 05044 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05045 ast_mutex_unlock(&iaxsl[callno]); 05046 return res; 05047 }
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 5069 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05070 { 05071 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05072 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1056 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01057 { 01058 #ifdef SCHED_MULTITHREADED 01059 if (schedule_action(__send_lagrq, data)) 01060 #endif 01061 __send_lagrq(data); 01062 return 0; 01063 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2080 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_registry::addr, ast_inet_ntoa(), ast_log(), iax_frame::callno, iax2_registry::callno, iax_frame::data, iax_frame::datalen, errno, error(), handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02081 { 02082 int res; 02083 int callno = f->callno; 02084 02085 /* Don't send if there was an error, but return error instead */ 02086 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02087 return -1; 02088 02089 /* Called with iaxsl held */ 02090 if (option_debug > 2 && iaxdebug) 02091 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 02092 if (f->transfer) { 02093 if (iaxdebug) 02094 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02095 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02096 sizeof(iaxs[callno]->transfer)); 02097 } else { 02098 if (iaxdebug) 02099 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02100 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02101 sizeof(iaxs[callno]->addr)); 02102 } 02103 if (res < 0) { 02104 if (option_debug && iaxdebug) 02105 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02106 handle_error(); 02107 } else 02108 res = 0; 02109 return res; 02110 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1016 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01017 { 01018 #ifdef SCHED_MULTITHREADED 01019 if (schedule_action(__send_ping, data)) 01020 #endif 01021 __send_ping(data); 01022 return 0; 01023 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6523 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().
06524 { 06525 int res = 0; 06526 struct iax_frame *fr; 06527 struct ast_iax2_meta_hdr *meta; 06528 struct ast_iax2_meta_trunk_hdr *mth; 06529 int calls = 0; 06530 06531 /* Point to frame */ 06532 fr = (struct iax_frame *)tpeer->trunkdata; 06533 /* Point to meta data */ 06534 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06535 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06536 if (tpeer->trunkdatalen) { 06537 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06538 meta->zeros = 0; 06539 meta->metacmd = IAX_META_TRUNK; 06540 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06541 meta->cmddata = IAX_META_TRUNK_MINI; 06542 else 06543 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06544 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06545 /* And the rest of the ast_iax2 header */ 06546 fr->direction = DIRECTION_OUTGRESS; 06547 fr->retrans = -1; 06548 fr->transfer = 0; 06549 /* Any appropriate call will do */ 06550 fr->data = fr->afdata; 06551 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06552 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06553 calls = tpeer->calls; 06554 #if 0 06555 if (option_debug) 06556 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)); 06557 #endif 06558 /* Reset transmit trunk side data */ 06559 tpeer->trunkdatalen = 0; 06560 tpeer->calls = 0; 06561 } 06562 if (res < 0) 06563 return res; 06564 return calls; 06565 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9899 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().
09900 { 09901 struct ast_config *cfg, *ucfg; 09902 int capability=iax2_capability; 09903 struct ast_variable *v; 09904 char *cat; 09905 const char *utype; 09906 const char *tosval; 09907 int format; 09908 int portno = IAX_DEFAULT_PORTNO; 09909 int x; 09910 struct iax2_user *user; 09911 struct iax2_peer *peer; 09912 struct ast_netsock *ns; 09913 #if 0 09914 static unsigned short int last_port=0; 09915 #endif 09916 09917 cfg = ast_config_load(config_file); 09918 09919 if (!cfg) { 09920 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09921 return -1; 09922 } 09923 09924 if (reload) { 09925 set_config_destroy(); 09926 } 09927 09928 /* Reset global codec prefs */ 09929 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09930 09931 /* Reset Global Flags */ 09932 memset(&globalflags, 0, sizeof(globalflags)); 09933 ast_set_flag(&globalflags, IAX_RTUPDATE); 09934 09935 #ifdef SO_NO_CHECK 09936 nochecksums = 0; 09937 #endif 09938 09939 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09940 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09941 09942 maxauthreq = 3; 09943 09944 v = ast_variable_browse(cfg, "general"); 09945 09946 /* Seed initial tos value */ 09947 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09948 if (tosval) { 09949 if (ast_str2tos(tosval, &tos)) 09950 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09951 } 09952 while(v) { 09953 if (!strcasecmp(v->name, "bindport")){ 09954 if (reload) 09955 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09956 else 09957 portno = atoi(v->value); 09958 } else if (!strcasecmp(v->name, "pingtime")) 09959 ping_time = atoi(v->value); 09960 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09961 if (reload) { 09962 if (atoi(v->value) != iaxthreadcount) 09963 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09964 } else { 09965 iaxthreadcount = atoi(v->value); 09966 if (iaxthreadcount < 1) { 09967 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09968 iaxthreadcount = 1; 09969 } else if (iaxthreadcount > 256) { 09970 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09971 iaxthreadcount = 256; 09972 } 09973 } 09974 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09975 if (reload) { 09976 AST_LIST_LOCK(&dynamic_list); 09977 iaxmaxthreadcount = atoi(v->value); 09978 AST_LIST_UNLOCK(&dynamic_list); 09979 } else { 09980 iaxmaxthreadcount = atoi(v->value); 09981 if (iaxmaxthreadcount < 0) { 09982 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09983 iaxmaxthreadcount = 0; 09984 } else if (iaxmaxthreadcount > 256) { 09985 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09986 iaxmaxthreadcount = 256; 09987 } 09988 } 09989 } else if (!strcasecmp(v->name, "nochecksums")) { 09990 #ifdef SO_NO_CHECK 09991 if (ast_true(v->value)) 09992 nochecksums = 1; 09993 else 09994 nochecksums = 0; 09995 #else 09996 if (ast_true(v->value)) 09997 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09998 #endif 09999 } 10000 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10001 maxjitterbuffer = atoi(v->value); 10002 else if (!strcasecmp(v->name, "resyncthreshold")) 10003 resyncthreshold = atoi(v->value); 10004 else if (!strcasecmp(v->name, "maxjitterinterps")) 10005 maxjitterinterps = atoi(v->value); 10006 else if (!strcasecmp(v->name, "lagrqtime")) 10007 lagrq_time = atoi(v->value); 10008 else if (!strcasecmp(v->name, "maxregexpire")) 10009 max_reg_expire = atoi(v->value); 10010 else if (!strcasecmp(v->name, "minregexpire")) 10011 min_reg_expire = atoi(v->value); 10012 else if (!strcasecmp(v->name, "bindaddr")) { 10013 if (reload) { 10014 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10015 } else { 10016 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10017 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10018 } else { 10019 if (option_verbose > 1) { 10020 if (strchr(v->value, ':')) 10021 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10022 else 10023 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10024 } 10025 if (defaultsockfd < 0) 10026 defaultsockfd = ast_netsock_sockfd(ns); 10027 ast_netsock_unref(ns); 10028 } 10029 } 10030 } else if (!strcasecmp(v->name, "authdebug")) 10031 authdebug = ast_true(v->value); 10032 else if (!strcasecmp(v->name, "encryption")) 10033 iax2_encryption = get_encrypt_methods(v->value); 10034 else if (!strcasecmp(v->name, "notransfer")) { 10035 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10036 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10037 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10038 } else if (!strcasecmp(v->name, "transfer")) { 10039 if (!strcasecmp(v->value, "mediaonly")) { 10040 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10041 } else if (ast_true(v->value)) { 10042 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10043 } else 10044 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10045 } else if (!strcasecmp(v->name, "codecpriority")) { 10046 if(!strcasecmp(v->value, "caller")) 10047 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10048 else if(!strcasecmp(v->value, "disabled")) 10049 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10050 else if(!strcasecmp(v->value, "reqonly")) { 10051 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10052 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10053 } 10054 } else if (!strcasecmp(v->name, "jitterbuffer")) 10055 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10056 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10057 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10058 else if (!strcasecmp(v->name, "delayreject")) 10059 delayreject = ast_true(v->value); 10060 else if (!strcasecmp(v->name, "allowfwdownload")) 10061 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10062 else if (!strcasecmp(v->name, "rtcachefriends")) 10063 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10064 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10065 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10066 else if (!strcasecmp(v->name, "rtupdate")) 10067 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10068 else if (!strcasecmp(v->name, "trunktimestamps")) 10069 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10070 else if (!strcasecmp(v->name, "rtautoclear")) { 10071 int i = atoi(v->value); 10072 if(i > 0) 10073 global_rtautoclear = i; 10074 else 10075 i = 0; 10076 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10077 } else if (!strcasecmp(v->name, "trunkfreq")) { 10078 trunkfreq = atoi(v->value); 10079 if (trunkfreq < 10) 10080 trunkfreq = 10; 10081 } else if (!strcasecmp(v->name, "autokill")) { 10082 if (sscanf(v->value, "%d", &x) == 1) { 10083 if (x >= 0) 10084 autokill = x; 10085 else 10086 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10087 } else if (ast_true(v->value)) { 10088 autokill = DEFAULT_MAXMS; 10089 } else { 10090 autokill = 0; 10091 } 10092 } else if (!strcasecmp(v->name, "bandwidth")) { 10093 if (!strcasecmp(v->value, "low")) { 10094 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10095 } else if (!strcasecmp(v->value, "medium")) { 10096 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10097 } else if (!strcasecmp(v->value, "high")) { 10098 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10099 } else 10100 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10101 } else if (!strcasecmp(v->name, "allow")) { 10102 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10103 } else if (!strcasecmp(v->name, "disallow")) { 10104 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10105 } else if (!strcasecmp(v->name, "register")) { 10106 iax2_register(v->value, v->lineno); 10107 } else if (!strcasecmp(v->name, "iaxcompat")) { 10108 iaxcompat = ast_true(v->value); 10109 } else if (!strcasecmp(v->name, "regcontext")) { 10110 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10111 /* Create context if it doesn't exist already */ 10112 if (!ast_context_find(regcontext)) 10113 ast_context_create(NULL, regcontext, "IAX2"); 10114 } else if (!strcasecmp(v->name, "tos")) { 10115 if (ast_str2tos(v->value, &tos)) 10116 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10117 } else if (!strcasecmp(v->name, "accountcode")) { 10118 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10119 } else if (!strcasecmp(v->name, "mohinterpret")) { 10120 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 10121 } else if (!strcasecmp(v->name, "mohsuggest")) { 10122 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 10123 } else if (!strcasecmp(v->name, "amaflags")) { 10124 format = ast_cdr_amaflags2int(v->value); 10125 if (format < 0) { 10126 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10127 } else { 10128 amaflags = format; 10129 } 10130 } else if (!strcasecmp(v->name, "language")) { 10131 ast_copy_string(language, v->value, sizeof(language)); 10132 } else if (!strcasecmp(v->name, "maxauthreq")) { 10133 maxauthreq = atoi(v->value); 10134 if (maxauthreq < 0) 10135 maxauthreq = 0; 10136 } else if (!strcasecmp(v->name, "adsi")) { 10137 adsi = ast_true(v->value); 10138 } /*else if (strcasecmp(v->name,"type")) */ 10139 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10140 v = v->next; 10141 } 10142 10143 if (defaultsockfd < 0) { 10144 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10145 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10146 } else { 10147 if (option_verbose > 1) 10148 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10149 defaultsockfd = ast_netsock_sockfd(ns); 10150 ast_netsock_unref(ns); 10151 } 10152 } 10153 if (reload) { 10154 ast_netsock_release(outsock); 10155 outsock = ast_netsock_list_alloc(); 10156 if (!outsock) { 10157 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10158 return -1; 10159 } 10160 ast_netsock_init(outsock); 10161 } 10162 10163 if (min_reg_expire > max_reg_expire) { 10164 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10165 min_reg_expire, max_reg_expire, max_reg_expire); 10166 min_reg_expire = max_reg_expire; 10167 } 10168 iax2_capability = capability; 10169 10170 ucfg = ast_config_load("users.conf"); 10171 if (ucfg) { 10172 struct ast_variable *gen; 10173 int genhasiax; 10174 int genregisteriax; 10175 const char *hasiax, *registeriax; 10176 10177 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10178 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10179 gen = ast_variable_browse(ucfg, "general"); 10180 cat = ast_category_browse(ucfg, NULL); 10181 while (cat) { 10182 if (strcasecmp(cat, "general")) { 10183 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10184 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10185 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10186 /* Start with general parameters, then specific parameters, user and peer */ 10187 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10188 if (user) { 10189 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10190 user = user_unref(user); 10191 } 10192 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10193 if (peer) { 10194 if (ast_test_flag(peer, IAX_DYNAMIC)) 10195 reg_source_db(peer); 10196 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10197 peer = peer_unref(peer); 10198 } 10199 } 10200 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10201 char tmp[256]; 10202 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10203 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10204 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10205 if (!host) 10206 host = ast_variable_retrieve(ucfg, "general", "host"); 10207 if (!username) 10208 username = ast_variable_retrieve(ucfg, "general", "username"); 10209 if (!secret) 10210 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10211 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10212 if (!ast_strlen_zero(secret)) 10213 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10214 else 10215 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10216 iax2_register(tmp, 0); 10217 } 10218 } 10219 } 10220 cat = ast_category_browse(ucfg, cat); 10221 } 10222 ast_config_destroy(ucfg); 10223 } 10224 10225 cat = ast_category_browse(cfg, NULL); 10226 while(cat) { 10227 if (strcasecmp(cat, "general")) { 10228 utype = ast_variable_retrieve(cfg, cat, "type"); 10229 if (utype) { 10230 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10231 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10232 if (user) { 10233 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10234 user = user_unref(user); 10235 } 10236 } 10237 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10238 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10239 if (peer) { 10240 if (ast_test_flag(peer, IAX_DYNAMIC)) 10241 reg_source_db(peer); 10242 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10243 peer = peer_unref(peer); 10244 } 10245 } else if (strcasecmp(utype, "user")) { 10246 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10247 } 10248 } else 10249 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10250 } 10251 cat = ast_category_browse(cfg, cat); 10252 } 10253 ast_config_destroy(cfg); 10254 set_timing(); 10255 return 1; 10256 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9883 of file chan_iax2.c.
References ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09884 { 09885 strcpy(accountcode, ""); 09886 strcpy(language, ""); 09887 strcpy(mohinterpret, "default"); 09888 strcpy(mohsuggest, ""); 09889 amaflags = 0; 09890 delayreject = 0; 09891 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09892 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09893 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09894 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09895 delete_users(); 09896 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9868 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09869 { 09870 #ifdef HAVE_ZAPTEL 09871 int bs = trunkfreq * 8; 09872 if (timingfd > -1) { 09873 if ( 09874 #ifdef ZT_TIMERACK 09875 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09876 #endif 09877 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09878 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09879 } 09880 #endif 09881 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 758 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_sched_add(), iax2_transmit(), and socket_read().
00759 { 00760 ast_mutex_lock(lock); 00761 ast_cond_signal(cond); 00762 ast_mutex_unlock(lock); 00763 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6997 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().
06998 { 06999 struct sockaddr_in sin; 07000 int res; 07001 int updatehistory=1; 07002 int new = NEW_PREVENT; 07003 void *ptr; 07004 int dcallno = 0; 07005 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07006 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07007 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07008 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07009 struct ast_iax2_meta_trunk_hdr *mth; 07010 struct ast_iax2_meta_trunk_entry *mte; 07011 struct ast_iax2_meta_trunk_mini *mtm; 07012 struct iax_frame *fr; 07013 struct iax_frame *cur; 07014 struct ast_frame f = { 0, }; 07015 struct ast_channel *c; 07016 struct iax2_dpcache *dp; 07017 struct iax2_peer *peer; 07018 struct iax2_trunk_peer *tpeer; 07019 struct timeval rxtrunktime; 07020 struct iax_ies ies; 07021 struct iax_ie_data ied0, ied1; 07022 int format; 07023 int fd; 07024 int exists; 07025 int minivid = 0; 07026 unsigned int ts; 07027 char empty[32]=""; /* Safety measure */ 07028 struct iax_frame *duped_fr; 07029 char host_pref_buf[128]; 07030 char caller_pref_buf[128]; 07031 struct ast_codec_pref pref; 07032 char *using_prefs = "mine"; 07033 07034 /* allocate an iax_frame with 4096 bytes of data buffer */ 07035 fr = alloca(sizeof(*fr) + 4096); 07036 memset(fr, 0, sizeof(*fr)); 07037 fr->afdatalen = 4096; /* From alloca() above */ 07038 07039 /* Copy frequently used parameters to the stack */ 07040 res = thread->buf_len; 07041 fd = thread->iofd; 07042 memcpy(&sin, &thread->iosin, sizeof(sin)); 07043 07044 if (res < sizeof(*mh)) { 07045 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07046 return 1; 07047 } 07048 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07049 if (res < sizeof(*vh)) { 07050 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)); 07051 return 1; 07052 } 07053 07054 /* This is a video frame, get call number */ 07055 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07056 minivid = 1; 07057 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07058 unsigned char metatype; 07059 07060 if (res < sizeof(*meta)) { 07061 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)); 07062 return 1; 07063 } 07064 07065 /* This is a meta header */ 07066 switch(meta->metacmd) { 07067 case IAX_META_TRUNK: 07068 if (res < (sizeof(*meta) + sizeof(*mth))) { 07069 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07070 sizeof(*meta) + sizeof(*mth)); 07071 return 1; 07072 } 07073 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07074 ts = ntohl(mth->ts); 07075 metatype = meta->cmddata; 07076 res -= (sizeof(*meta) + sizeof(*mth)); 07077 ptr = mth->data; 07078 tpeer = find_tpeer(&sin, fd); 07079 if (!tpeer) { 07080 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)); 07081 return 1; 07082 } 07083 tpeer->trunkact = ast_tvnow(); 07084 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07085 tpeer->rxtrunktime = tpeer->trunkact; 07086 rxtrunktime = tpeer->rxtrunktime; 07087 ast_mutex_unlock(&tpeer->lock); 07088 while(res >= sizeof(*mte)) { 07089 /* Process channels */ 07090 unsigned short callno, trunked_ts, len; 07091 07092 if (metatype == IAX_META_TRUNK_MINI) { 07093 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07094 ptr += sizeof(*mtm); 07095 res -= sizeof(*mtm); 07096 len = ntohs(mtm->len); 07097 callno = ntohs(mtm->mini.callno); 07098 trunked_ts = ntohs(mtm->mini.ts); 07099 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07100 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07101 ptr += sizeof(*mte); 07102 res -= sizeof(*mte); 07103 len = ntohs(mte->len); 07104 callno = ntohs(mte->callno); 07105 trunked_ts = 0; 07106 } else { 07107 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07108 break; 07109 } 07110 /* Stop if we don't have enough data */ 07111 if (len > res) 07112 break; 07113 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07114 if (fr->callno) { 07115 /* If it's a valid call, deliver the contents. If not, we 07116 drop it, since we don't have a scallno to use for an INVAL */ 07117 /* Process as a mini frame */ 07118 memset(&f, 0, sizeof(f)); 07119 f.frametype = AST_FRAME_VOICE; 07120 if (iaxs[fr->callno]) { 07121 if (iaxs[fr->callno]->voiceformat > 0) { 07122 f.subclass = iaxs[fr->callno]->voiceformat; 07123 f.datalen = len; 07124 if (f.datalen >= 0) { 07125 if (f.datalen) 07126 f.data = ptr; 07127 if(trunked_ts) { 07128 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07129 } else 07130 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07131 /* Don't pass any packets until we're started */ 07132 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07133 /* Common things */ 07134 f.src = "IAX2"; 07135 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07136 f.samples = ast_codec_get_samples(&f); 07137 iax_frame_wrap(fr, &f); 07138 duped_fr = iaxfrdup2(fr); 07139 if (duped_fr) { 07140 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07141 } 07142 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07143 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07144 iaxs[fr->callno]->last = fr->ts; 07145 #if 1 07146 if (option_debug && iaxdebug) 07147 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07148 #endif 07149 } 07150 } 07151 } else { 07152 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07153 } 07154 } else { 07155 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 07156 iax2_vnak(fr->callno); 07157 } 07158 } 07159 ast_mutex_unlock(&iaxsl[fr->callno]); 07160 } 07161 ptr += len; 07162 res -= len; 07163 } 07164 07165 } 07166 return 1; 07167 } 07168 07169 #ifdef DEBUG_SUPPORT 07170 if (iaxdebug && (res >= sizeof(*fh))) 07171 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07172 #endif 07173 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07174 if (res < sizeof(*fh)) { 07175 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)); 07176 return 1; 07177 } 07178 07179 /* Get the destination call number */ 07180 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07181 /* Retrieve the type and subclass */ 07182 f.frametype = fh->type; 07183 if (f.frametype == AST_FRAME_VIDEO) { 07184 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07185 } else { 07186 f.subclass = uncompress_subclass(fh->csub); 07187 } 07188 07189 /* Deal with POKE/PONG without allocating a callno */ 07190 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07191 /* Reply back with a PONG, but don't care about the result. */ 07192 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno); 07193 return 1; 07194 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07195 /* Ignore */ 07196 return 1; 07197 } 07198 07199 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07200 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07201 (f.subclass == IAX_COMMAND_REGREL))) 07202 new = NEW_ALLOW; 07203 } else { 07204 /* Don't know anything about it yet */ 07205 f.frametype = AST_FRAME_NULL; 07206 f.subclass = 0; 07207 } 07208 07209 if (!fr->callno) { 07210 int check_dcallno = 0; 07211 07212 /* 07213 * We enforce accurate destination call numbers for all full frames except 07214 * LAGRQ and PING commands. This is because older versions of Asterisk 07215 * schedule these commands to get sent very quickly, and they will sometimes 07216 * be sent before they receive the first frame from the other side. When 07217 * that happens, it doesn't contain the destination call number. However, 07218 * not checking it for these frames is safe. 07219 * 07220 * Discussed in the following thread: 07221 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07222 */ 07223 07224 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07225 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07226 } 07227 07228 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07229 } 07230 07231 if (fr->callno > 0) 07232 ast_mutex_lock(&iaxsl[fr->callno]); 07233 07234 if (!fr->callno || !iaxs[fr->callno]) { 07235 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07236 frame, reply with an inval */ 07237 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07238 /* We can only raw hangup control frames */ 07239 if (((f.subclass != IAX_COMMAND_INVAL) && 07240 (f.subclass != IAX_COMMAND_TXCNT) && 07241 (f.subclass != IAX_COMMAND_TXACC) && 07242 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07243 (f.frametype != AST_FRAME_IAX)) 07244 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07245 fd); 07246 } 07247 if (fr->callno > 0) 07248 ast_mutex_unlock(&iaxsl[fr->callno]); 07249 return 1; 07250 } 07251 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07252 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07253 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07254 ast_mutex_unlock(&iaxsl[fr->callno]); 07255 return 1; 07256 } 07257 #ifdef DEBUG_SUPPORT 07258 else if (iaxdebug) 07259 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07260 #endif 07261 } 07262 07263 /* count this frame */ 07264 iaxs[fr->callno]->frames_received++; 07265 07266 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07267 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07268 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07269 unsigned short new_peercallno; 07270 07271 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07272 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07273 if (iaxs[fr->callno]->peercallno) { 07274 remove_by_peercallno(iaxs[fr->callno]); 07275 } 07276 iaxs[fr->callno]->peercallno = new_peercallno; 07277 store_by_peercallno(iaxs[fr->callno]); 07278 } 07279 } 07280 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07281 if (option_debug && iaxdebug) 07282 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07283 /* Check if it's out of order (and not an ACK or INVAL) */ 07284 fr->oseqno = fh->oseqno; 07285 fr->iseqno = fh->iseqno; 07286 fr->ts = ntohl(fh->ts); 07287 #ifdef IAXTESTS 07288 if (test_resync) { 07289 if (option_debug) 07290 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07291 fr->ts += test_resync; 07292 } 07293 #endif /* IAXTESTS */ 07294 #if 0 07295 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07296 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07297 (f.subclass == IAX_COMMAND_NEW || 07298 f.subclass == IAX_COMMAND_AUTHREQ || 07299 f.subclass == IAX_COMMAND_ACCEPT || 07300 f.subclass == IAX_COMMAND_REJECT)) ) ) 07301 #endif 07302 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07303 updatehistory = 0; 07304 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07305 (iaxs[fr->callno]->iseqno || 07306 ((f.subclass != IAX_COMMAND_TXCNT) && 07307 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07308 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07309 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07310 (f.subclass != IAX_COMMAND_TXACC)) || 07311 (f.frametype != AST_FRAME_IAX))) { 07312 if ( 07313 ((f.subclass != IAX_COMMAND_ACK) && 07314 (f.subclass != IAX_COMMAND_INVAL) && 07315 (f.subclass != IAX_COMMAND_TXCNT) && 07316 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07317 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07318 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07319 (f.subclass != IAX_COMMAND_TXACC) && 07320 (f.subclass != IAX_COMMAND_VNAK)) || 07321 (f.frametype != AST_FRAME_IAX)) { 07322 /* If it's not an ACK packet, it's out of order. */ 07323 if (option_debug) 07324 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07325 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07326 /* Check to see if we need to request retransmission, 07327 * and take sequence number wraparound into account */ 07328 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07329 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07330 if ((f.frametype != AST_FRAME_IAX) || 07331 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07332 if (option_debug) 07333 ast_log(LOG_DEBUG, "Acking anyway\n"); 07334 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07335 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07336 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07337 } 07338 } else { 07339 /* Send a VNAK requesting retransmission */ 07340 iax2_vnak(fr->callno); 07341 } 07342 ast_mutex_unlock(&iaxsl[fr->callno]); 07343 return 1; 07344 } 07345 } else { 07346 /* Increment unless it's an ACK or VNAK */ 07347 if (((f.subclass != IAX_COMMAND_ACK) && 07348 (f.subclass != IAX_COMMAND_INVAL) && 07349 (f.subclass != IAX_COMMAND_TXCNT) && 07350 (f.subclass != IAX_COMMAND_TXACC) && 07351 (f.subclass != IAX_COMMAND_VNAK)) || 07352 (f.frametype != AST_FRAME_IAX)) 07353 iaxs[fr->callno]->iseqno++; 07354 } 07355 /* A full frame */ 07356 if (res < sizeof(*fh)) { 07357 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07358 ast_mutex_unlock(&iaxsl[fr->callno]); 07359 return 1; 07360 } 07361 /* Ensure text frames are NULL-terminated */ 07362 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07363 if (res < thread->buf_size) 07364 thread->buf[res++] = '\0'; 07365 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07366 thread->buf[res - 1] = '\0'; 07367 } 07368 f.datalen = res - sizeof(*fh); 07369 07370 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07371 from the real peer, not the transfer peer */ 07372 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07373 ((f.subclass != IAX_COMMAND_INVAL) || 07374 (f.frametype != AST_FRAME_IAX))) { 07375 unsigned char x; 07376 int call_to_destroy; 07377 /* XXX This code is not very efficient. Surely there is a better way which still 07378 properly handles boundary conditions? XXX */ 07379 /* First we have to qualify that the ACKed value is within our window */ 07380 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07381 if (fr->iseqno == x) 07382 break; 07383 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07384 /* The acknowledgement is within our window. Time to acknowledge everything 07385 that it says to */ 07386 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07387 /* Ack the packet with the given timestamp */ 07388 if (option_debug && iaxdebug) 07389 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07390 call_to_destroy = 0; 07391 AST_LIST_LOCK(&iaxq.queue); 07392 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07393 /* If it's our call, and our timestamp, mark -1 retries */ 07394 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07395 cur->retries = -1; 07396 /* Destroy call if this is the end */ 07397 if (cur->final) 07398 call_to_destroy = fr->callno; 07399 } 07400 } 07401 AST_LIST_UNLOCK(&iaxq.queue); 07402 if (call_to_destroy) { 07403 if (iaxdebug && option_debug) 07404 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07405 ast_mutex_lock(&iaxsl[call_to_destroy]); 07406 iax2_destroy(call_to_destroy); 07407 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07408 } 07409 } 07410 /* Note how much we've received acknowledgement for */ 07411 if (iaxs[fr->callno]) 07412 iaxs[fr->callno]->rseqno = fr->iseqno; 07413 else { 07414 /* Stop processing now */ 07415 ast_mutex_unlock(&iaxsl[fr->callno]); 07416 return 1; 07417 } 07418 } else if (option_debug) 07419 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07420 } 07421 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07422 ((f.frametype != AST_FRAME_IAX) || 07423 ((f.subclass != IAX_COMMAND_TXACC) && 07424 (f.subclass != IAX_COMMAND_TXCNT)))) { 07425 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07426 ast_mutex_unlock(&iaxsl[fr->callno]); 07427 return 1; 07428 } 07429 07430 if (f.datalen) { 07431 if (f.frametype == AST_FRAME_IAX) { 07432 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07433 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07434 ast_mutex_unlock(&iaxsl[fr->callno]); 07435 return 1; 07436 } 07437 f.data = NULL; 07438 f.datalen = 0; 07439 } else 07440 f.data = thread->buf + sizeof(*fh); 07441 } else { 07442 if (f.frametype == AST_FRAME_IAX) 07443 f.data = NULL; 07444 else 07445 f.data = empty; 07446 memset(&ies, 0, sizeof(ies)); 07447 } 07448 07449 /* when we receive the first full frame for a new incoming channel, 07450 it is safe to start the PBX on the channel because we have now 07451 completed a 3-way handshake with the peer */ 07452 if ((f.frametype == AST_FRAME_VOICE) || 07453 (f.frametype == AST_FRAME_VIDEO) || 07454 (f.frametype == AST_FRAME_IAX)) { 07455 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07456 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07457 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07458 ast_mutex_unlock(&iaxsl[fr->callno]); 07459 return 1; 07460 } 07461 } 07462 } 07463 07464 if (f.frametype == AST_FRAME_VOICE) { 07465 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07466 iaxs[fr->callno]->voiceformat = f.subclass; 07467 if (option_debug) 07468 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07469 if (iaxs[fr->callno]->owner) { 07470 int orignative; 07471 retryowner: 07472 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07473 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07474 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07475 } 07476 if (iaxs[fr->callno]) { 07477 if (iaxs[fr->callno]->owner) { 07478 orignative = iaxs[fr->callno]->owner->nativeformats; 07479 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07480 if (iaxs[fr->callno]->owner->readformat) 07481 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07482 iaxs[fr->callno]->owner->nativeformats = orignative; 07483 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07484 } 07485 } else { 07486 if (option_debug) 07487 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07488 ast_mutex_unlock(&iaxsl[fr->callno]); 07489 return 1; 07490 } 07491 } 07492 } 07493 } 07494 if (f.frametype == AST_FRAME_VIDEO) { 07495 if (f.subclass != iaxs[fr->callno]->videoformat) { 07496 if (option_debug) 07497 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07498 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07499 } 07500 } 07501 if (f.frametype == AST_FRAME_IAX) { 07502 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07503 /* Handle the IAX pseudo frame itself */ 07504 if (option_debug && iaxdebug) 07505 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07506 07507 /* Update last ts unless the frame's timestamp originated with us. */ 07508 if (iaxs[fr->callno]->last < fr->ts && 07509 f.subclass != IAX_COMMAND_ACK && 07510 f.subclass != IAX_COMMAND_PONG && 07511 f.subclass != IAX_COMMAND_LAGRP) { 07512 iaxs[fr->callno]->last = fr->ts; 07513 if (option_debug && iaxdebug) 07514 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07515 } 07516 07517 switch(f.subclass) { 07518 case IAX_COMMAND_ACK: 07519 /* Do nothing */ 07520 break; 07521 case IAX_COMMAND_QUELCH: 07522 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07523 /* Generate Manager Hold event, if necessary*/ 07524 if (iaxs[fr->callno]->owner) { 07525 manager_event(EVENT_FLAG_CALL, "Hold", 07526 "Channel: %s\r\n" 07527 "Uniqueid: %s\r\n", 07528 iaxs[fr->callno]->owner->name, 07529 iaxs[fr->callno]->owner->uniqueid); 07530 } 07531 07532 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07533 if (ies.musiconhold) { 07534 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07535 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07536 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07537 S_OR(mohsuggest, NULL), 07538 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07539 if (!iaxs[fr->callno]) { 07540 ast_mutex_unlock(&iaxsl[fr->callno]); 07541 return 1; 07542 } 07543 } 07544 } 07545 } 07546 break; 07547 case IAX_COMMAND_UNQUELCH: 07548 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07549 /* Generate Manager Unhold event, if necessary*/ 07550 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07551 manager_event(EVENT_FLAG_CALL, "Unhold", 07552 "Channel: %s\r\n" 07553 "Uniqueid: %s\r\n", 07554 iaxs[fr->callno]->owner->name, 07555 iaxs[fr->callno]->owner->uniqueid); 07556 } 07557 07558 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07559 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07560 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07561 if (!iaxs[fr->callno]) { 07562 ast_mutex_unlock(&iaxsl[fr->callno]); 07563 return 1; 07564 } 07565 } 07566 } 07567 break; 07568 case IAX_COMMAND_TXACC: 07569 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07570 /* Ack the packet with the given timestamp */ 07571 AST_LIST_LOCK(&iaxq.queue); 07572 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07573 /* Cancel any outstanding txcnt's */ 07574 if ((fr->callno == cur->callno) && (cur->transfer)) 07575 cur->retries = -1; 07576 } 07577 AST_LIST_UNLOCK(&iaxq.queue); 07578 memset(&ied1, 0, sizeof(ied1)); 07579 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07580 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07581 iaxs[fr->callno]->transferring = TRANSFER_READY; 07582 } 07583 break; 07584 case IAX_COMMAND_NEW: 07585 /* Ignore if it's already up */ 07586 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07587 break; 07588 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07589 ast_mutex_unlock(&iaxsl[fr->callno]); 07590 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07591 ast_mutex_lock(&iaxsl[fr->callno]); 07592 if (!iaxs[fr->callno]) { 07593 ast_mutex_unlock(&iaxsl[fr->callno]); 07594 return 1; 07595 } 07596 } 07597 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07598 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07599 int new_callno; 07600 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07601 fr->callno = new_callno; 07602 } 07603 /* For security, always ack immediately */ 07604 if (delayreject) 07605 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07606 if (check_access(fr->callno, &sin, &ies)) { 07607 /* They're not allowed on */ 07608 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07609 if (authdebug) 07610 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); 07611 break; 07612 } 07613 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07614 const char *context, *exten, *cid_num; 07615 07616 context = ast_strdupa(iaxs[fr->callno]->context); 07617 exten = ast_strdupa(iaxs[fr->callno]->exten); 07618 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07619 07620 /* This might re-enter the IAX code and need the lock */ 07621 ast_mutex_unlock(&iaxsl[fr->callno]); 07622 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07623 ast_mutex_lock(&iaxsl[fr->callno]); 07624 07625 if (!iaxs[fr->callno]) { 07626 ast_mutex_unlock(&iaxsl[fr->callno]); 07627 return 1; 07628 } 07629 } else 07630 exists = 0; 07631 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07632 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07633 memset(&ied0, 0, sizeof(ied0)); 07634 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07635 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07636 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07637 if (!iaxs[fr->callno]) { 07638 ast_mutex_unlock(&iaxsl[fr->callno]); 07639 return 1; 07640 } 07641 if (authdebug) 07642 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); 07643 } else { 07644 /* Select an appropriate format */ 07645 07646 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07647 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07648 using_prefs = "reqonly"; 07649 } else { 07650 using_prefs = "disabled"; 07651 } 07652 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07653 memset(&pref, 0, sizeof(pref)); 07654 strcpy(caller_pref_buf, "disabled"); 07655 strcpy(host_pref_buf, "disabled"); 07656 } else { 07657 using_prefs = "mine"; 07658 /* If the information elements are in here... use them */ 07659 if (ies.codec_prefs) 07660 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07661 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07662 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07663 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07664 pref = iaxs[fr->callno]->rprefs; 07665 using_prefs = "caller"; 07666 } else { 07667 pref = iaxs[fr->callno]->prefs; 07668 } 07669 } else 07670 pref = iaxs[fr->callno]->prefs; 07671 07672 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07673 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07674 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07675 } 07676 if (!format) { 07677 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07678 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07679 if (!format) { 07680 memset(&ied0, 0, sizeof(ied0)); 07681 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07682 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07683 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07684 if (!iaxs[fr->callno]) { 07685 ast_mutex_unlock(&iaxsl[fr->callno]); 07686 return 1; 07687 } 07688 if (authdebug) { 07689 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07690 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); 07691 else 07692 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); 07693 } 07694 } else { 07695 /* Pick one... */ 07696 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07697 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07698 format = 0; 07699 } else { 07700 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07701 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07702 memset(&pref, 0, sizeof(pref)); 07703 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07704 strcpy(caller_pref_buf,"disabled"); 07705 strcpy(host_pref_buf,"disabled"); 07706 } else { 07707 using_prefs = "mine"; 07708 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07709 /* Do the opposite of what we tried above. */ 07710 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07711 pref = iaxs[fr->callno]->prefs; 07712 } else { 07713 pref = iaxs[fr->callno]->rprefs; 07714 using_prefs = "caller"; 07715 } 07716 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07717 07718 } else /* if no codec_prefs IE do it the old way */ 07719 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07720 } 07721 } 07722 07723 if (!format) { 07724 memset(&ied0, 0, sizeof(ied0)); 07725 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07726 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07727 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07728 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07729 if (!iaxs[fr->callno]) { 07730 ast_mutex_unlock(&iaxsl[fr->callno]); 07731 return 1; 07732 } 07733 if (authdebug) 07734 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); 07735 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07736 break; 07737 } 07738 } 07739 } 07740 if (format) { 07741 /* No authentication required, let them in */ 07742 memset(&ied1, 0, sizeof(ied1)); 07743 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07744 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07745 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07746 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07747 if (option_verbose > 2) 07748 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07749 "%srequested format = %s,\n" 07750 "%srequested prefs = %s,\n" 07751 "%sactual format = %s,\n" 07752 "%shost prefs = %s,\n" 07753 "%spriority = %s\n", 07754 ast_inet_ntoa(sin.sin_addr), 07755 VERBOSE_PREFIX_4, 07756 ast_getformatname(iaxs[fr->callno]->peerformat), 07757 VERBOSE_PREFIX_4, 07758 caller_pref_buf, 07759 VERBOSE_PREFIX_4, 07760 ast_getformatname(format), 07761 VERBOSE_PREFIX_4, 07762 host_pref_buf, 07763 VERBOSE_PREFIX_4, 07764 using_prefs); 07765 07766 iaxs[fr->callno]->chosenformat = format; 07767 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07768 } else { 07769 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07770 /* If this is a TBD call, we're ready but now what... */ 07771 if (option_verbose > 2) 07772 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07773 } 07774 } 07775 } 07776 break; 07777 } 07778 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07779 merge_encryption(iaxs[fr->callno],ies.encmethods); 07780 else 07781 iaxs[fr->callno]->encmethods = 0; 07782 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07783 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07784 if (!iaxs[fr->callno]) { 07785 ast_mutex_unlock(&iaxsl[fr->callno]); 07786 return 1; 07787 } 07788 break; 07789 case IAX_COMMAND_DPREQ: 07790 /* Request status in the dialplan */ 07791 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07792 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07793 if (iaxcompat) { 07794 /* Spawn a thread for the lookup */ 07795 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07796 } else { 07797 /* Just look it up */ 07798 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07799 } 07800 } 07801 break; 07802 case IAX_COMMAND_HANGUP: 07803 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07804 if (option_debug) 07805 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07806 /* Set hangup cause according to remote */ 07807 if (ies.causecode && iaxs[fr->callno]->owner) 07808 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07809 /* Send ack immediately, before we destroy */ 07810 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07811 iax2_destroy(fr->callno); 07812 break; 07813 case IAX_COMMAND_REJECT: 07814 /* Set hangup cause according to remote */ 07815 if (ies.causecode && iaxs[fr->callno]->owner) 07816 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07817 07818 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07819 if (iaxs[fr->callno]->owner && authdebug) 07820 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07821 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07822 ies.cause ? ies.cause : "<Unknown>"); 07823 if (option_debug) 07824 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07825 fr->callno); 07826 } 07827 /* Send ack immediately, before we destroy */ 07828 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07829 fr->ts, NULL, 0, fr->iseqno); 07830 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07831 iaxs[fr->callno]->error = EPERM; 07832 iax2_destroy(fr->callno); 07833 break; 07834 case IAX_COMMAND_TRANSFER: 07835 { 07836 struct ast_channel *bridged_chan; 07837 07838 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07839 /* Set BLINDTRANSFER channel variables */ 07840 07841 ast_mutex_unlock(&iaxsl[fr->callno]); 07842 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07843 ast_mutex_lock(&iaxsl[fr->callno]); 07844 if (!iaxs[fr->callno]) { 07845 ast_mutex_unlock(&iaxsl[fr->callno]); 07846 return 1; 07847 } 07848 07849 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07850 if (!strcmp(ies.called_number, ast_parking_ext())) { 07851 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07852 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07853 } else { 07854 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07855 } 07856 } else { 07857 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07858 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07859 ies.called_number, iaxs[fr->callno]->context); 07860 else 07861 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07862 ies.called_number, iaxs[fr->callno]->context); 07863 } 07864 } else 07865 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07866 07867 break; 07868 } 07869 case IAX_COMMAND_ACCEPT: 07870 /* Ignore if call is already up or needs authentication or is a TBD */ 07871 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07872 break; 07873 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07874 /* Send ack immediately, before we destroy */ 07875 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07876 iax2_destroy(fr->callno); 07877 break; 07878 } 07879 if (ies.format) { 07880 iaxs[fr->callno]->peerformat = ies.format; 07881 } else { 07882 if (iaxs[fr->callno]->owner) 07883 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07884 else 07885 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07886 } 07887 if (option_verbose > 2) 07888 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)); 07889 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07890 memset(&ied0, 0, sizeof(ied0)); 07891 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07892 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07893 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07894 if (!iaxs[fr->callno]) { 07895 ast_mutex_unlock(&iaxsl[fr->callno]); 07896 return 1; 07897 } 07898 if (authdebug) 07899 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); 07900 } else { 07901 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07902 if (iaxs[fr->callno]->owner) { 07903 /* Switch us to use a compatible format */ 07904 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07905 if (option_verbose > 2) 07906 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07907 retryowner2: 07908 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07909 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07910 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07911 } 07912 07913 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07914 /* Setup read/write formats properly. */ 07915 if (iaxs[fr->callno]->owner->writeformat) 07916 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07917 if (iaxs[fr->callno]->owner->readformat) 07918 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07919 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07920 } 07921 } 07922 } 07923 if (iaxs[fr->callno]) { 07924 ast_mutex_lock(&dpcache_lock); 07925 dp = iaxs[fr->callno]->dpentries; 07926 while(dp) { 07927 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07928 iax2_dprequest(dp, fr->callno); 07929 } 07930 dp = dp->peer; 07931 } 07932 ast_mutex_unlock(&dpcache_lock); 07933 } 07934 break; 07935 case IAX_COMMAND_POKE: 07936 /* Send back a pong packet with the original timestamp */ 07937 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07938 if (!iaxs[fr->callno]) { 07939 ast_mutex_unlock(&iaxsl[fr->callno]); 07940 return 1; 07941 } 07942 break; 07943 case IAX_COMMAND_PING: 07944 { 07945 struct iax_ie_data pingied; 07946 construct_rr(iaxs[fr->callno], &pingied); 07947 /* Send back a pong packet with the original timestamp */ 07948 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07949 } 07950 break; 07951 case IAX_COMMAND_PONG: 07952 /* Calculate ping time */ 07953 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07954 /* save RR info */ 07955 save_rr(fr, &ies); 07956 07957 if (iaxs[fr->callno]->peerpoke) { 07958 peer = iaxs[fr->callno]->peerpoke; 07959 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07960 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07961 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07962 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07963 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07964 } 07965 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07966 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07967 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07968 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07969 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07970 } 07971 } 07972 peer->lastms = iaxs[fr->callno]->pingtime; 07973 if (peer->smoothing && (peer->lastms > -1)) 07974 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07975 else if (peer->smoothing && peer->lastms < 0) 07976 peer->historicms = (0 + peer->historicms) / 2; 07977 else 07978 peer->historicms = iaxs[fr->callno]->pingtime; 07979 07980 /* Remove scheduled iax2_poke_noanswer */ 07981 if (peer->pokeexpire > -1) { 07982 if (!ast_sched_del(sched, peer->pokeexpire)) { 07983 peer_unref(peer); 07984 peer->pokeexpire = -1; 07985 } 07986 } 07987 /* Schedule the next cycle */ 07988 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07989 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07990 else 07991 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07992 if (peer->pokeexpire == -1) 07993 peer_unref(peer); 07994 /* and finally send the ack */ 07995 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07996 /* And wrap up the qualify call */ 07997 iax2_destroy(fr->callno); 07998 peer->callno = 0; 07999 if (option_debug) 08000 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08001 } 08002 break; 08003 case IAX_COMMAND_LAGRQ: 08004 case IAX_COMMAND_LAGRP: 08005 f.src = "LAGRQ"; 08006 f.mallocd = 0; 08007 f.offset = 0; 08008 f.samples = 0; 08009 iax_frame_wrap(fr, &f); 08010 if(f.subclass == IAX_COMMAND_LAGRQ) { 08011 /* Received a LAGRQ - echo back a LAGRP */ 08012 fr->af.subclass = IAX_COMMAND_LAGRP; 08013 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08014 } else { 08015 /* Received LAGRP in response to our LAGRQ */ 08016 unsigned int ts; 08017 /* This is a reply we've been given, actually measure the difference */ 08018 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08019 iaxs[fr->callno]->lag = ts - fr->ts; 08020 if (option_debug && iaxdebug) 08021 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08022 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08023 } 08024 break; 08025 case IAX_COMMAND_AUTHREQ: 08026 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08027 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>"); 08028 break; 08029 } 08030 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08031 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08032 .subclass = AST_CONTROL_HANGUP, 08033 }; 08034 ast_log(LOG_WARNING, 08035 "I don't know how to authenticate %s to %s\n", 08036 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08037 iax2_queue_frame(fr->callno, &hangup_fr); 08038 } 08039 if (!iaxs[fr->callno]) { 08040 ast_mutex_unlock(&iaxsl[fr->callno]); 08041 return 1; 08042 } 08043 break; 08044 case IAX_COMMAND_AUTHREP: 08045 /* For security, always ack immediately */ 08046 if (delayreject) 08047 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08048 /* Ignore once we've started */ 08049 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08050 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>"); 08051 break; 08052 } 08053 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08054 if (authdebug) 08055 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); 08056 memset(&ied0, 0, sizeof(ied0)); 08057 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08058 break; 08059 } 08060 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08061 /* This might re-enter the IAX code and need the lock */ 08062 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08063 } else 08064 exists = 0; 08065 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08066 if (authdebug) 08067 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); 08068 memset(&ied0, 0, sizeof(ied0)); 08069 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08070 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08071 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08072 if (!iaxs[fr->callno]) { 08073 ast_mutex_unlock(&iaxsl[fr->callno]); 08074 return 1; 08075 } 08076 } else { 08077 /* Select an appropriate format */ 08078 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08079 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08080 using_prefs = "reqonly"; 08081 } else { 08082 using_prefs = "disabled"; 08083 } 08084 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08085 memset(&pref, 0, sizeof(pref)); 08086 strcpy(caller_pref_buf, "disabled"); 08087 strcpy(host_pref_buf, "disabled"); 08088 } else { 08089 using_prefs = "mine"; 08090 if (ies.codec_prefs) 08091 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08092 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08093 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08094 pref = iaxs[fr->callno]->rprefs; 08095 using_prefs = "caller"; 08096 } else { 08097 pref = iaxs[fr->callno]->prefs; 08098 } 08099 } else /* if no codec_prefs IE do it the old way */ 08100 pref = iaxs[fr->callno]->prefs; 08101 08102 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08103 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08104 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08105 } 08106 if (!format) { 08107 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08108 if (option_debug) 08109 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); 08110 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08111 } 08112 if (!format) { 08113 if (authdebug) { 08114 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08115 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); 08116 else 08117 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); 08118 } 08119 memset(&ied0, 0, sizeof(ied0)); 08120 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08121 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08122 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08123 if (!iaxs[fr->callno]) { 08124 ast_mutex_unlock(&iaxsl[fr->callno]); 08125 return 1; 08126 } 08127 } else { 08128 /* Pick one... */ 08129 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08130 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08131 format = 0; 08132 } else { 08133 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08134 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08135 memset(&pref, 0, sizeof(pref)); 08136 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08137 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08138 strcpy(caller_pref_buf,"disabled"); 08139 strcpy(host_pref_buf,"disabled"); 08140 } else { 08141 using_prefs = "mine"; 08142 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08143 /* Do the opposite of what we tried above. */ 08144 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08145 pref = iaxs[fr->callno]->prefs; 08146 } else { 08147 pref = iaxs[fr->callno]->rprefs; 08148 using_prefs = "caller"; 08149 } 08150 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08151 } else /* if no codec_prefs IE do it the old way */ 08152 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08153 } 08154 } 08155 if (!format) { 08156 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08157 if (authdebug) { 08158 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08159 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); 08160 else 08161 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); 08162 } 08163 memset(&ied0, 0, sizeof(ied0)); 08164 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08165 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08166 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08167 if (!iaxs[fr->callno]) { 08168 ast_mutex_unlock(&iaxsl[fr->callno]); 08169 return 1; 08170 } 08171 } 08172 } 08173 } 08174 if (format) { 08175 /* Authentication received */ 08176 memset(&ied1, 0, sizeof(ied1)); 08177 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08178 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08179 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08180 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08181 if (option_verbose > 2) 08182 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08183 "%srequested format = %s,\n" 08184 "%srequested prefs = %s,\n" 08185 "%sactual format = %s,\n" 08186 "%shost prefs = %s,\n" 08187 "%spriority = %s\n", 08188 ast_inet_ntoa(sin.sin_addr), 08189 VERBOSE_PREFIX_4, 08190 ast_getformatname(iaxs[fr->callno]->peerformat), 08191 VERBOSE_PREFIX_4, 08192 caller_pref_buf, 08193 VERBOSE_PREFIX_4, 08194 ast_getformatname(format), 08195 VERBOSE_PREFIX_4, 08196 host_pref_buf, 08197 VERBOSE_PREFIX_4, 08198 using_prefs); 08199 08200 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08201 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08202 iax2_destroy(fr->callno); 08203 } else { 08204 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08205 /* If this is a TBD call, we're ready but now what... */ 08206 if (option_verbose > 2) 08207 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08208 } 08209 } 08210 } 08211 break; 08212 case IAX_COMMAND_DIAL: 08213 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08214 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08215 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08216 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08217 if (authdebug) 08218 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); 08219 memset(&ied0, 0, sizeof(ied0)); 08220 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08221 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08222 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08223 if (!iaxs[fr->callno]) { 08224 ast_mutex_unlock(&iaxsl[fr->callno]); 08225 return 1; 08226 } 08227 } else { 08228 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08229 if (option_verbose > 2) 08230 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08231 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08232 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08233 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08234 iax2_destroy(fr->callno); 08235 } 08236 } 08237 break; 08238 case IAX_COMMAND_INVAL: 08239 iaxs[fr->callno]->error = ENOTCONN; 08240 if (option_debug) 08241 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08242 iax2_destroy(fr->callno); 08243 if (option_debug) 08244 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08245 break; 08246 case IAX_COMMAND_VNAK: 08247 if (option_debug) 08248 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08249 /* Force retransmission */ 08250 vnak_retransmit(fr->callno, fr->iseqno); 08251 break; 08252 case IAX_COMMAND_REGREQ: 08253 case IAX_COMMAND_REGREL: 08254 /* For security, always ack immediately */ 08255 if (delayreject) 08256 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08257 if (register_verify(fr->callno, &sin, &ies)) { 08258 if (!iaxs[fr->callno]) { 08259 ast_mutex_unlock(&iaxsl[fr->callno]); 08260 return 1; 08261 } 08262 /* Send delayed failure */ 08263 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08264 break; 08265 } 08266 if (!iaxs[fr->callno]) { 08267 ast_mutex_unlock(&iaxsl[fr->callno]); 08268 return 1; 08269 } 08270 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08271 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 08272 08273 if (f.subclass == IAX_COMMAND_REGREL) 08274 memset(&sin, 0, sizeof(sin)); 08275 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08276 ast_log(LOG_WARNING, "Registry error\n"); 08277 if (!iaxs[fr->callno]) { 08278 ast_mutex_unlock(&iaxsl[fr->callno]); 08279 return 1; 08280 } 08281 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08282 ast_mutex_unlock(&iaxsl[fr->callno]); 08283 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08284 ast_mutex_lock(&iaxsl[fr->callno]); 08285 if (!iaxs[fr->callno]) { 08286 ast_mutex_unlock(&iaxsl[fr->callno]); 08287 return 1; 08288 } 08289 } 08290 break; 08291 } 08292 registry_authrequest(fr->callno); 08293 if (!iaxs[fr->callno]) { 08294 ast_mutex_unlock(&iaxsl[fr->callno]); 08295 return 1; 08296 } 08297 break; 08298 case IAX_COMMAND_REGACK: 08299 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08300 ast_log(LOG_WARNING, "Registration failure\n"); 08301 /* Send ack immediately, before we destroy */ 08302 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08303 iax2_destroy(fr->callno); 08304 break; 08305 case IAX_COMMAND_REGREJ: 08306 if (iaxs[fr->callno]->reg) { 08307 if (authdebug) { 08308 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)); 08309 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>"); 08310 } 08311 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08312 } 08313 /* Send ack immediately, before we destroy */ 08314 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08315 iax2_destroy(fr->callno); 08316 break; 08317 case IAX_COMMAND_REGAUTH: 08318 /* Authentication request */ 08319 if (registry_rerequest(&ies, fr->callno, &sin)) { 08320 memset(&ied0, 0, sizeof(ied0)); 08321 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08322 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08323 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08324 if (!iaxs[fr->callno]) { 08325 ast_mutex_unlock(&iaxsl[fr->callno]); 08326 return 1; 08327 } 08328 } 08329 break; 08330 case IAX_COMMAND_TXREJ: 08331 iaxs[fr->callno]->transferring = 0; 08332 if (option_verbose > 2) 08333 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08334 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08335 if (iaxs[fr->callno]->bridgecallno) { 08336 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08337 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08338 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08339 } 08340 } 08341 break; 08342 case IAX_COMMAND_TXREADY: 08343 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08344 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08345 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08346 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08347 else 08348 iaxs[fr->callno]->transferring = TRANSFER_READY; 08349 if (option_verbose > 2) 08350 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08351 if (iaxs[fr->callno]->bridgecallno) { 08352 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08353 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08354 /* They're both ready, now release them. */ 08355 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08356 if (option_verbose > 2) 08357 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08358 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08359 08360 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08361 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08362 08363 memset(&ied0, 0, sizeof(ied0)); 08364 memset(&ied1, 0, sizeof(ied1)); 08365 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08366 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08367 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08368 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08369 } else { 08370 if (option_verbose > 2) 08371 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08372 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08373 08374 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08375 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08376 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08377 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08378 08379 /* Stop doing lag & ping requests */ 08380 stop_stuff(fr->callno); 08381 stop_stuff(iaxs[fr->callno]->bridgecallno); 08382 08383 memset(&ied0, 0, sizeof(ied0)); 08384 memset(&ied1, 0, sizeof(ied1)); 08385 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08386 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08387 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08388 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08389 } 08390 08391 } 08392 } 08393 } 08394 break; 08395 case IAX_COMMAND_TXREQ: 08396 try_transfer(iaxs[fr->callno], &ies); 08397 break; 08398 case IAX_COMMAND_TXCNT: 08399 if (iaxs[fr->callno]->transferring) 08400 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08401 break; 08402 case IAX_COMMAND_TXREL: 08403 /* Send ack immediately, rather than waiting until we've changed addresses */ 08404 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08405 complete_transfer(fr->callno, &ies); 08406 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08407 break; 08408 case IAX_COMMAND_TXMEDIA: 08409 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08410 AST_LIST_LOCK(&iaxq.queue); 08411 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08412 /* Cancel any outstanding frames and start anew */ 08413 if ((fr->callno == cur->callno) && (cur->transfer)) { 08414 cur->retries = -1; 08415 } 08416 } 08417 AST_LIST_UNLOCK(&iaxq.queue); 08418 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08419 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08420 } 08421 break; 08422 case IAX_COMMAND_DPREP: 08423 complete_dpreply(iaxs[fr->callno], &ies); 08424 break; 08425 case IAX_COMMAND_UNSUPPORT: 08426 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08427 break; 08428 case IAX_COMMAND_FWDOWNL: 08429 /* Firmware download */ 08430 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08431 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08432 break; 08433 } 08434 memset(&ied0, 0, sizeof(ied0)); 08435 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08436 if (res < 0) 08437 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08438 else if (res > 0) 08439 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08440 else 08441 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08442 if (!iaxs[fr->callno]) { 08443 ast_mutex_unlock(&iaxsl[fr->callno]); 08444 return 1; 08445 } 08446 break; 08447 default: 08448 if (option_debug) 08449 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08450 memset(&ied0, 0, sizeof(ied0)); 08451 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08452 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08453 } 08454 /* Don't actually pass these frames along */ 08455 if ((f.subclass != IAX_COMMAND_ACK) && 08456 (f.subclass != IAX_COMMAND_TXCNT) && 08457 (f.subclass != IAX_COMMAND_TXACC) && 08458 (f.subclass != IAX_COMMAND_INVAL) && 08459 (f.subclass != IAX_COMMAND_VNAK)) { 08460 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08461 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08462 } 08463 ast_mutex_unlock(&iaxsl[fr->callno]); 08464 return 1; 08465 } 08466 /* Unless this is an ACK or INVAL frame, ack it */ 08467 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08468 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08469 } else if (minivid) { 08470 f.frametype = AST_FRAME_VIDEO; 08471 if (iaxs[fr->callno]->videoformat > 0) 08472 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08473 else { 08474 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08475 iax2_vnak(fr->callno); 08476 ast_mutex_unlock(&iaxsl[fr->callno]); 08477 return 1; 08478 } 08479 f.datalen = res - sizeof(*vh); 08480 if (f.datalen) 08481 f.data = thread->buf + sizeof(*vh); 08482 else 08483 f.data = NULL; 08484 #ifdef IAXTESTS 08485 if (test_resync) { 08486 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08487 } else 08488 #endif /* IAXTESTS */ 08489 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08490 } else { 08491 /* A mini frame */ 08492 f.frametype = AST_FRAME_VOICE; 08493 if (iaxs[fr->callno]->voiceformat > 0) 08494 f.subclass = iaxs[fr->callno]->voiceformat; 08495 else { 08496 if (option_debug) 08497 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08498 iax2_vnak(fr->callno); 08499 ast_mutex_unlock(&iaxsl[fr->callno]); 08500 return 1; 08501 } 08502 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08503 if (f.datalen < 0) { 08504 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08505 ast_mutex_unlock(&iaxsl[fr->callno]); 08506 return 1; 08507 } 08508 if (f.datalen) 08509 f.data = thread->buf + sizeof(*mh); 08510 else 08511 f.data = NULL; 08512 #ifdef IAXTESTS 08513 if (test_resync) { 08514 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08515 } else 08516 #endif /* IAXTESTS */ 08517 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08518 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08519 } 08520 /* Don't pass any packets until we're started */ 08521 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08522 ast_mutex_unlock(&iaxsl[fr->callno]); 08523 return 1; 08524 } 08525 /* Common things */ 08526 f.src = "IAX2"; 08527 f.mallocd = 0; 08528 f.offset = 0; 08529 f.len = 0; 08530 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08531 f.samples = ast_codec_get_samples(&f); 08532 /* We need to byteswap incoming slinear samples from network byte order */ 08533 if (f.subclass == AST_FORMAT_SLINEAR) 08534 ast_frame_byteswap_be(&f); 08535 } else 08536 f.samples = 0; 08537 iax_frame_wrap(fr, &f); 08538 08539 /* If this is our most recent packet, use it as our basis for timestamping */ 08540 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08541 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08542 fr->outoforder = 0; 08543 } else { 08544 if (option_debug && iaxdebug && iaxs[fr->callno]) 08545 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); 08546 fr->outoforder = -1; 08547 } 08548 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08549 duped_fr = iaxfrdup2(fr); 08550 if (duped_fr) { 08551 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08552 } 08553 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08554 iaxs[fr->callno]->last = fr->ts; 08555 #if 1 08556 if (option_debug && iaxdebug) 08557 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08558 #endif 08559 } 08560 08561 /* Always run again */ 08562 ast_mutex_unlock(&iaxsl[fr->callno]); 08563 return 1; 08564 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6919 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().
06920 { 06921 struct iax2_thread *thread; 06922 socklen_t len; 06923 time_t t; 06924 static time_t last_errtime = 0; 06925 struct ast_iax2_full_hdr *fh; 06926 06927 if (!(thread = find_idle_thread())) { 06928 time(&t); 06929 if (t != last_errtime && option_debug) 06930 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06931 last_errtime = t; 06932 usleep(1); 06933 return 1; 06934 } 06935 06936 len = sizeof(thread->iosin); 06937 thread->iofd = fd; 06938 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06939 thread->buf_size = sizeof(thread->readbuf); 06940 thread->buf = thread->readbuf; 06941 if (thread->buf_len < 0) { 06942 if (errno != ECONNREFUSED && errno != EAGAIN) 06943 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06944 handle_error(); 06945 thread->iostate = IAX_IOSTATE_IDLE; 06946 signal_condition(&thread->lock, &thread->cond); 06947 return 1; 06948 } 06949 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06950 thread->iostate = IAX_IOSTATE_IDLE; 06951 signal_condition(&thread->lock, &thread->cond); 06952 return 1; 06953 } 06954 06955 /* Determine if this frame is a full frame; if so, and any thread is currently 06956 processing a full frame for the same callno from this peer, then drop this 06957 frame (and the peer will retransmit it) */ 06958 fh = (struct ast_iax2_full_hdr *) thread->buf; 06959 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06960 struct iax2_thread *cur = NULL; 06961 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06962 06963 AST_LIST_LOCK(&active_list); 06964 AST_LIST_TRAVERSE(&active_list, cur, list) { 06965 if ((cur->ffinfo.callno == callno) && 06966 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06967 break; 06968 } 06969 if (cur) { 06970 /* we found another thread processing a full frame for this call, 06971 so queue it up for processing later. */ 06972 defer_full_frame(thread, cur); 06973 AST_LIST_UNLOCK(&active_list); 06974 thread->iostate = IAX_IOSTATE_IDLE; 06975 signal_condition(&thread->lock, &thread->cond); 06976 return 1; 06977 } else { 06978 /* this thread is going to process this frame, so mark it */ 06979 thread->ffinfo.callno = callno; 06980 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06981 thread->ffinfo.type = fh->type; 06982 thread->ffinfo.csub = fh->csub; 06983 } 06984 AST_LIST_UNLOCK(&active_list); 06985 } 06986 06987 /* Mark as ready and send on its way */ 06988 thread->iostate = IAX_IOSTATE_READY; 06989 #ifdef DEBUG_SCHED_MULTITHREAD 06990 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06991 #endif 06992 signal_condition(&thread->lock, &thread->cond); 06993 06994 return 1; 06995 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6706 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().
06707 { 06708 pthread_t newthread; 06709 struct dpreq_data *dpr; 06710 pthread_attr_t attr; 06711 06712 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06713 return; 06714 06715 pthread_attr_init(&attr); 06716 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06717 06718 dpr->callno = callno; 06719 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06720 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06721 if (callerid) 06722 dpr->callerid = ast_strdup(callerid); 06723 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06724 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06725 } 06726 06727 pthread_attr_destroy(&attr); 06728 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9166 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().
09167 { 09168 pthread_attr_t attr; 09169 int threadcount = 0; 09170 int x; 09171 for (x = 0; x < iaxthreadcount; x++) { 09172 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09173 if (thread) { 09174 thread->type = IAX_TYPE_POOL; 09175 thread->threadnum = ++threadcount; 09176 ast_mutex_init(&thread->lock); 09177 ast_cond_init(&thread->cond, NULL); 09178 pthread_attr_init(&attr); 09179 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09180 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09181 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09182 free(thread); 09183 thread = NULL; 09184 } 09185 AST_LIST_LOCK(&idle_list); 09186 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09187 AST_LIST_UNLOCK(&idle_list); 09188 } 09189 } 09190 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09191 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09192 if (option_verbose > 1) 09193 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 09194 return 0; 09195 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6388 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06389 { 06390 iax2_destroy_helper(iaxs[callno]); 06391 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1240 of file chan_iax2.c.
References ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01241 { 01242 if (!pvt->peercallno) { 01243 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01244 return; 01245 } 01246 01247 ao2_link(iax_peercallno_pvts, pvt); 01248 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6575 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().
06576 { 06577 char buf[1024]; 06578 int res; 06579 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06580 int processed = 0; 06581 int totalcalls = 0; 06582 #ifdef ZT_TIMERACK 06583 int x = 1; 06584 #endif 06585 struct timeval now; 06586 if (iaxtrunkdebug) 06587 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06588 gettimeofday(&now, NULL); 06589 if (events & AST_IO_PRI) { 06590 #ifdef ZT_TIMERACK 06591 /* Great, this is a timing interface, just call the ioctl */ 06592 if (ioctl(fd, ZT_TIMERACK, &x)) { 06593 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06594 usleep(1); 06595 return -1; 06596 } 06597 #endif 06598 } else { 06599 /* Read and ignore from the pseudo channel for timing */ 06600 res = read(fd, buf, sizeof(buf)); 06601 if (res < 1) { 06602 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06603 return 1; 06604 } 06605 } 06606 /* For each peer that supports trunking... */ 06607 ast_mutex_lock(&tpeerlock); 06608 tpeer = tpeers; 06609 while(tpeer) { 06610 processed++; 06611 res = 0; 06612 ast_mutex_lock(&tpeer->lock); 06613 /* We can drop a single tpeer per pass. That makes all this logic 06614 substantially easier */ 06615 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06616 /* Take it out of the list, but don't free it yet, because it 06617 could be in use */ 06618 if (prev) 06619 prev->next = tpeer->next; 06620 else 06621 tpeers = tpeer->next; 06622 drop = tpeer; 06623 } else { 06624 res = send_trunk(tpeer, &now); 06625 if (iaxtrunkdebug) 06626 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); 06627 } 06628 totalcalls += res; 06629 res = 0; 06630 ast_mutex_unlock(&tpeer->lock); 06631 prev = tpeer; 06632 tpeer = tpeer->next; 06633 } 06634 ast_mutex_unlock(&tpeerlock); 06635 if (drop) { 06636 ast_mutex_lock(&drop->lock); 06637 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06638 because by the time they could get tpeerlock, we've already grabbed it */ 06639 if (option_debug) 06640 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06641 if (drop->trunkdata) { 06642 free(drop->trunkdata); 06643 drop->trunkdata = NULL; 06644 } 06645 ast_mutex_unlock(&drop->lock); 06646 ast_mutex_destroy(&drop->lock); 06647 free(drop); 06648 06649 } 06650 if (iaxtrunkdebug) 06651 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06652 iaxtrunkdebug =0; 06653 return 1; 06654 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2066 of file chan_iax2.c.
References ast_log(), iax_frame::data, iax_frame::datalen, errno, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02067 { 02068 int res; 02069 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02070 sizeof(*sin)); 02071 if (res < 0) { 02072 if (option_debug) 02073 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02074 handle_error(); 02075 } else 02076 res = 0; 02077 return res; 02078 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1754 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, len, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01755 { 01756 struct stat stbuf; 01757 struct iax_firmware *cur; 01758 int ifd; 01759 int fd; 01760 int res; 01761 01762 struct ast_iax2_firmware_header *fwh, fwh2; 01763 struct MD5Context md5; 01764 unsigned char sum[16]; 01765 unsigned char buf[1024]; 01766 int len, chunk; 01767 char *s2; 01768 char *last; 01769 s2 = alloca(strlen(s) + 100); 01770 if (!s2) { 01771 ast_log(LOG_WARNING, "Alloca failed!\n"); 01772 return -1; 01773 } 01774 last = strrchr(s, '/'); 01775 if (last) 01776 last++; 01777 else 01778 last = s; 01779 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01780 res = stat(s, &stbuf); 01781 if (res < 0) { 01782 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01783 return -1; 01784 } 01785 /* Make sure it's not a directory */ 01786 if (S_ISDIR(stbuf.st_mode)) 01787 return -1; 01788 ifd = open(s, O_RDONLY); 01789 if (ifd < 0) { 01790 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01791 return -1; 01792 } 01793 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01794 if (fd < 0) { 01795 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01796 close(ifd); 01797 return -1; 01798 } 01799 /* Unlink our newly created file */ 01800 unlink(s2); 01801 01802 /* Now copy the firmware into it */ 01803 len = stbuf.st_size; 01804 while(len) { 01805 chunk = len; 01806 if (chunk > sizeof(buf)) 01807 chunk = sizeof(buf); 01808 res = read(ifd, buf, chunk); 01809 if (res != chunk) { 01810 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01811 close(ifd); 01812 close(fd); 01813 return -1; 01814 } 01815 res = write(fd, buf, chunk); 01816 if (res != chunk) { 01817 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01818 close(ifd); 01819 close(fd); 01820 return -1; 01821 } 01822 len -= chunk; 01823 } 01824 close(ifd); 01825 /* Return to the beginning */ 01826 lseek(fd, 0, SEEK_SET); 01827 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01828 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01829 close(fd); 01830 return -1; 01831 } 01832 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01833 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01834 close(fd); 01835 return -1; 01836 } 01837 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01838 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01839 close(fd); 01840 return -1; 01841 } 01842 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01843 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01844 close(fd); 01845 return -1; 01846 } 01847 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01848 if (fwh == (void *) -1) { 01849 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01850 close(fd); 01851 return -1; 01852 } 01853 MD5Init(&md5); 01854 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01855 MD5Final(sum, &md5); 01856 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01857 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01858 munmap((void*)fwh, stbuf.st_size); 01859 close(fd); 01860 return -1; 01861 } 01862 cur = waresl.wares; 01863 while(cur) { 01864 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01865 /* Found a candidate */ 01866 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01867 /* The version we have on loaded is older, load this one instead */ 01868 break; 01869 /* This version is no newer than what we have. Don't worry about it. 01870 We'll consider it a proper load anyhow though */ 01871 munmap((void*)fwh, stbuf.st_size); 01872 close(fd); 01873 return 0; 01874 } 01875 cur = cur->next; 01876 } 01877 if (!cur) { 01878 /* Allocate a new one and link it */ 01879 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01880 cur->fd = -1; 01881 cur->next = waresl.wares; 01882 waresl.wares = cur; 01883 } 01884 } 01885 if (cur) { 01886 if (cur->fwh) { 01887 munmap((void*)cur->fwh, cur->mmaplen); 01888 } 01889 if (cur->fd > -1) 01890 close(cur->fd); 01891 cur->fwh = fwh; 01892 cur->fd = fd; 01893 cur->mmaplen = stbuf.st_size; 01894 cur->dead = 0; 01895 } 01896 return 0; 01897 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5781 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().
05782 { 05783 int newcall = 0; 05784 char newip[256]; 05785 struct iax_ie_data ied; 05786 struct sockaddr_in new; 05787 05788 05789 memset(&ied, 0, sizeof(ied)); 05790 if (ies->apparent_addr) 05791 bcopy(ies->apparent_addr, &new, sizeof(new)); 05792 if (ies->callno) 05793 newcall = ies->callno; 05794 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05795 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05796 return -1; 05797 } 05798 pvt->transfercallno = newcall; 05799 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05800 inet_aton(newip, &pvt->transfer.sin_addr); 05801 pvt->transfer.sin_family = AF_INET; 05802 pvt->transferring = TRANSFER_BEGIN; 05803 pvt->transferid = ies->transferid; 05804 if (ies->transferid) 05805 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05806 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05807 return 0; 05808 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1085 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01086 { 01087 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01088 if (csub & IAX_FLAG_SC_LOG) { 01089 /* special case for 'compressed' -1 */ 01090 if (csub == 0xff) 01091 return -1; 01092 else 01093 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01094 } 01095 else 01096 return csub; 01097 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6053 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().
06054 { 06055 if (peer->expire > -1) { 06056 if (!ast_sched_del(sched, peer->expire)) { 06057 peer->expire = -1; 06058 peer_unref(peer); 06059 } 06060 } 06061 06062 if (peer->pokeexpire > -1) { 06063 if (!ast_sched_del(sched, peer->pokeexpire)) { 06064 peer->pokeexpire = -1; 06065 peer_unref(peer); 06066 } 06067 } 06068 06069 ao2_unlink(peers, peer); 06070 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11091 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11092 { 11093 ast_custom_function_unregister(&iaxpeer_function); 11094 return __unload_module(); 11095 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3474 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03475 { 03476 ast_mutex_unlock(&iaxsl[callno1]); 03477 ast_mutex_unlock(&iaxsl[callno0]); 03478 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2500 of file chan_iax2.c.
References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02501 { 02502 int x; 02503 02504 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02505 x = fr->ts - iaxs[fr->callno]->last; 02506 if (x < -50000) { 02507 /* Sudden big jump backwards in timestamp: 02508 What likely happened here is that miniframe timestamp has circled but we haven't 02509 gotten the update from the main packet. We'll just pretend that we did, and 02510 update the timestamp appropriately. */ 02511 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02512 if (option_debug && iaxdebug) 02513 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02514 } 02515 if (x > 50000) { 02516 /* Sudden apparent big jump forwards in timestamp: 02517 What's likely happened is this is an old miniframe belonging to the previous 02518 top-16-bit timestamp that has turned up out of order. 02519 Adjust the timestamp appropriately. */ 02520 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02521 if (option_debug && iaxdebug) 02522 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02523 } 02524 } 02525 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2529 of file chan_iax2.c.
References AST_SCHED_DEL, chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
02530 { 02531 int when; 02532 02533 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02534 02535 when = jb_next(pvt->jb) - when; 02536 02537 AST_SCHED_DEL(sched, pvt->jbid); 02538 02539 if(when <= 0) { 02540 /* XXX should really just empty until when > 0.. */ 02541 when = 1; 02542 } 02543 02544 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02545 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1453 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01454 { 01455 int max = 1; 01456 int x; 01457 /* XXX Prolly don't need locks here XXX */ 01458 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01459 if (iaxs[x]) 01460 max = x + 1; 01461 } 01462 maxnontrunkcall = max; 01463 if (option_debug && iaxdebug) 01464 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01465 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1260 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), iaxs, LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01261 { 01262 int max = TRUNK_CALL_START; 01263 int x; 01264 01265 /* XXX Prolly don't need locks here XXX */ 01266 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01267 if (iaxs[x]) { 01268 max = x + 1; 01269 } 01270 } 01271 01272 maxtrunkcall = max; 01273 if (option_debug && iaxdebug) 01274 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01275 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2137 of file chan_iax2.c.
References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno.
Referenced by __attempt_transmit().
02138 { 02139 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02140 struct ast_iax2_full_hdr *fh = f->data; 02141 /* Mark this as a retransmission */ 02142 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02143 /* Update iseqno */ 02144 f->iseqno = iaxs[f->callno]->iseqno; 02145 fh->iseqno = f->iseqno; 02146 return 0; 02147 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6164 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().
06165 { 06166 /* Called from IAX thread only, with proper iaxsl lock */ 06167 struct iax_ie_data ied; 06168 struct iax2_peer *p; 06169 int msgcount; 06170 char data[80]; 06171 int version; 06172 const char *peer_name; 06173 int res = -1; 06174 06175 memset(&ied, 0, sizeof(ied)); 06176 06177 peer_name = ast_strdupa(iaxs[callno]->peer); 06178 06179 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06180 ast_mutex_unlock(&iaxsl[callno]); 06181 if (!(p = find_peer(peer_name, 1))) { 06182 ast_mutex_lock(&iaxsl[callno]); 06183 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06184 return -1; 06185 } 06186 ast_mutex_lock(&iaxsl[callno]); 06187 if (!iaxs[callno]) 06188 goto return_unref; 06189 06190 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06191 if (sin->sin_addr.s_addr) { 06192 time_t nowtime; 06193 time(&nowtime); 06194 realtime_update_peer(peer_name, sin, nowtime); 06195 } else { 06196 realtime_update_peer(peer_name, sin, 0); 06197 } 06198 } 06199 if (inaddrcmp(&p->addr, sin)) { 06200 if (iax2_regfunk) 06201 iax2_regfunk(p->name, 1); 06202 /* Stash the IP address from which they registered */ 06203 memcpy(&p->addr, sin, sizeof(p->addr)); 06204 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06205 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06206 ast_db_put("IAX/Registry", p->name, data); 06207 if (option_verbose > 2) 06208 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06209 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06210 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06211 register_peer_exten(p, 1); 06212 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06213 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06214 if (option_verbose > 2) 06215 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06216 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06217 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06218 register_peer_exten(p, 0); 06219 ast_db_del("IAX/Registry", p->name); 06220 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06221 } 06222 /* Update the host */ 06223 /* Verify that the host is really there */ 06224 iax2_poke_peer(p, callno); 06225 } 06226 06227 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06228 if (!iaxs[callno]) { 06229 res = 0; 06230 goto return_unref; 06231 } 06232 06233 /* Store socket fd */ 06234 p->sockfd = fd; 06235 /* Setup the expiry */ 06236 if (p->expire > -1) { 06237 if (!ast_sched_del(sched, p->expire)) { 06238 p->expire = -1; 06239 peer_unref(p); 06240 } 06241 } 06242 /* treat an unspecified refresh interval as the minimum */ 06243 if (!refresh) 06244 refresh = min_reg_expire; 06245 if (refresh > max_reg_expire) { 06246 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06247 p->name, max_reg_expire, refresh); 06248 p->expiry = max_reg_expire; 06249 } else if (refresh < min_reg_expire) { 06250 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06251 p->name, min_reg_expire, refresh); 06252 p->expiry = min_reg_expire; 06253 } else { 06254 p->expiry = refresh; 06255 } 06256 if (p->expiry && sin->sin_addr.s_addr) { 06257 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06258 if (p->expire == -1) 06259 peer_unref(p); 06260 } 06261 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06262 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06263 if (sin->sin_addr.s_addr) { 06264 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06265 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06266 if (!ast_strlen_zero(p->mailbox)) { 06267 int new, old; 06268 ast_app_inboxcount(p->mailbox, &new, &old); 06269 if (new > 255) 06270 new = 255; 06271 if (old > 255) 06272 old = 255; 06273 msgcount = (old << 8) | new; 06274 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06275 } 06276 if (ast_test_flag(p, IAX_HASCALLERID)) { 06277 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06278 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06279 } 06280 } 06281 version = iax_check_version(devtype); 06282 if (version) 06283 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06284 06285 res = 0; 06286 06287 return_unref: 06288 peer_unref(p); 06289 06290 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06291 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1132 of file chan_iax2.c.
Referenced by load_module().
01133 { 01134 struct iax2_user *user = obj, *user2 = arg; 01135 01136 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01137 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9806 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09807 { 09808 struct iax2_user *user = obj; 09809 09810 ast_set_flag(user, IAX_DELME); 09811 09812 return 0; 09813 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9570 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().
09571 { 09572 struct iax2_user *user = obj; 09573 09574 ast_free_ha(user->ha); 09575 free_context(user->contexts); 09576 if(user->vars) { 09577 ast_variables_destroy(user->vars); 09578 user->vars = NULL; 09579 } 09580 ast_string_field_free_memory(user); 09581 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1122 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01123 { 01124 const struct iax2_user *user = obj; 01125 01126 return ast_str_hash(user->name); 01127 }
Definition at line 1171 of file chan_iax2.c.
References ao2_ref().
01172 { 01173 ao2_ref(user, +1); 01174 return user; 01175 }
Definition at line 1177 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), prune_users(), and set_config().
01178 { 01179 ao2_ref(user, -1); 01180 return NULL; 01181 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6489 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().
06490 { 06491 struct iax_frame *f; 06492 06493 AST_LIST_LOCK(&iaxq.queue); 06494 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06495 /* Send a copy immediately */ 06496 if ((f->callno == callno) && iaxs[f->callno] && 06497 ((unsigned char ) (f->oseqno - last) < 128) && 06498 (f->retries >= 0)) { 06499 send_packet(f); 06500 } 06501 } 06502 AST_LIST_UNLOCK(&iaxq.queue); 06503 }
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 10887 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 10892 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 10902 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 10897 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 10882 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 10856 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 10848 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 10840 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 10798 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 867 of file chan_iax2.c.
Referenced by __unload_module(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
char iax2_test_losspct_usage[] [static] |
Initial value:
"Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n"
Definition at line 10864 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 826 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_peercallno(), and store_by_peercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 453 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 207 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 163 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 452 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 813 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 814 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), and update_registry().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 209 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 202 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 153 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 147 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 161 of file chan_iax2.c.
Definition at line 815 of file chan_iax2.c.
Referenced by __find_callno(), iax2_destroy(), and make_trunk().
int max_reg_expire [static] |
Definition at line 170 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 151 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 150 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 154 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 156 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 833 of file chan_iax2.c.
Referenced by __find_callno(), and update_max_nontrunk().
int maxtrunkcall = TRUNK_CALL_START [static] |
int min_reg_expire [static] |
Definition at line 169 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 221 of file chan_iax2.c.
Referenced by check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 174 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 10860 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 10852 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 10844 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 8815 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peers [static] |
Definition at line 651 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), abort_request(), authenticate_reply(), build_peer(), build_transactions(), cancel_request(), chanavail_exec(), check_request(), complete_iax2_show_peer(), complete_peer_helper(), delete_users(), destroy_trans(), discover_transactions(), dundi_flush(), dundi_ie_append_eid_appropriately(), dundi_lookup_thread(), dundi_precache_internal(), dundi_precache_thread(), dundi_query_thread(), dundi_rexmit(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), dundi_show_trans(), find_peer(), handle_command_response(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), mark_mappings(), mark_peers(), network_thread(), optimize_transactions(), poke_all_peers(), precache_transactions(), prune_mappings(), prune_peers(), query_transactions(), realtime_peer(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 152 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 141 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10794 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 10786 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 10814 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 10832 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 10818 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 10790 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 10826 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10802 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 10836 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 10782 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 10822 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 10809 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 143 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 211 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 172 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 167 of file chan_iax2.c.
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 157 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 654 of file chan_iax2.c.
Referenced by __unload_module(), ast_get_manager_by_name_locked(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_voicemail_show_users(), delete_users(), find_or_create(), find_user(), handle_showmanager(), handle_showmanagers(), handle_voicemail_show_users(), iax2_destroy_helper(), iax2_show_users(), init_manager(), load_config(), load_module(), prune_users(), realtime_user(), reset_user_pw(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().