#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Include dependency graph for chan_iax2.c:
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START 0x4000 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2), IAX_STATE_UNCHANGED = (1 << 3) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static 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) |
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) |
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 | 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 | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static 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 int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static struct timeval | lastused [IAX_MAX_CALLS] |
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 123 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 134 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 201 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 200 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 199 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 443 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 182 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 190 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 195 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 184 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 699 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#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 114 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 440 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 446 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 444 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 441 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 1240 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 122 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().
#define SCHED_MULTITHREADED |
Definition at line 107 of file chan_iax2.c.
Definition at line 966 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 0x4000 |
Definition at line 132 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 449 of file chan_iax2.c.
anonymous enum |
Definition at line 235 of file chan_iax2.c.
00235 { 00236 IAX_STATE_STARTED = (1 << 0), 00237 IAX_STATE_AUTHENTICATED = (1 << 1), 00238 IAX_STATE_TBD = (1 << 2), 00239 IAX_STATE_UNCHANGED = (1 << 3), 00240 } iax2_state;
anonymous enum |
Definition at line 247 of file chan_iax2.c.
00247 { 00248 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00249 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00250 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00251 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00252 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00253 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00254 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00255 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00256 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00257 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00258 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00259 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00260 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00261 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00262 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00263 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00264 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00265 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00266 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00267 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00268 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00269 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00270 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00271 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00272 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00273 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00274 response, so that we've achieved a three-way handshake with 00275 them before sending voice or anything else*/ 00276 } 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 395 of file chan_iax2.c.
00395 { 00396 REG_STATE_UNREGISTERED = 0, 00397 REG_STATE_REGSENT, 00398 REG_STATE_AUTHSENT, 00399 REG_STATE_REGISTERED, 00400 REG_STATE_REJECTED, 00401 REG_STATE_TIMEOUT, 00402 REG_STATE_NOAUTH 00403 };
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 405 of file chan_iax2.c.
00405 { 00406 TRANSFER_NONE = 0, 00407 TRANSFER_BEGIN, 00408 TRANSFER_READY, 00409 TRANSFER_RELEASED, 00410 TRANSFER_PASSTHROUGH, 00411 TRANSFER_MBEGIN, 00412 TRANSFER_MREADY, 00413 TRANSFER_MRELEASED, 00414 TRANSFER_MPASSTHROUGH, 00415 TRANSFER_MEDIA, 00416 TRANSFER_MEDIAPASS 00417 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2034 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02035 { 02036 /* Attempt to transmit the frame to the remote peer... 02037 Called without iaxsl held. */ 02038 struct iax_frame *f = (struct iax_frame *)data; 02039 int freeme=0; 02040 int callno = f->callno; 02041 /* Make sure this call is still active */ 02042 if (callno) 02043 ast_mutex_lock(&iaxsl[callno]); 02044 if (callno && iaxs[callno]) { 02045 if ((f->retries < 0) /* Already ACK'd */ || 02046 (f->retries >= max_retries) /* Too many attempts */) { 02047 /* Record an error if we've transmitted too many times */ 02048 if (f->retries >= max_retries) { 02049 if (f->transfer) { 02050 /* Transfer timeout */ 02051 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02052 } else if (f->final) { 02053 if (f->final) 02054 iax2_destroy(callno); 02055 } else { 02056 if (iaxs[callno]->owner) 02057 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); 02058 iaxs[callno]->error = ETIMEDOUT; 02059 if (iaxs[callno]->owner) { 02060 struct ast_frame fr = { 0, }; 02061 /* Hangup the fd */ 02062 fr.frametype = AST_FRAME_CONTROL; 02063 fr.subclass = AST_CONTROL_HANGUP; 02064 iax2_queue_frame(callno, &fr); // XXX 02065 /* Remember, owner could disappear */ 02066 if (iaxs[callno] && iaxs[callno]->owner) 02067 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02068 } else { 02069 if (iaxs[callno]->reg) { 02070 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02071 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02072 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02073 } 02074 iax2_destroy(callno); 02075 } 02076 } 02077 02078 } 02079 freeme++; 02080 } else { 02081 /* Update it if it needs it */ 02082 update_packet(f); 02083 /* Attempt transmission */ 02084 send_packet(f); 02085 f->retries++; 02086 /* Try again later after 10 times as long */ 02087 f->retrytime *= 10; 02088 if (f->retrytime > MAX_RETRY_TIME) 02089 f->retrytime = MAX_RETRY_TIME; 02090 /* Transfer messages max out at one second */ 02091 if (f->transfer && (f->retrytime > 1000)) 02092 f->retrytime = 1000; 02093 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02094 } 02095 } else { 02096 /* Make sure it gets freed */ 02097 f->retries = -1; 02098 freeme++; 02099 } 02100 if (callno) 02101 ast_mutex_unlock(&iaxsl[callno]); 02102 /* Do not try again */ 02103 if (freeme) { 02104 /* Don't attempt delivery, just remove it from the queue */ 02105 AST_LIST_LOCK(&iaxq.queue); 02106 AST_LIST_REMOVE(&iaxq.queue, f, list); 02107 iaxq.count--; 02108 AST_LIST_UNLOCK(&iaxq.queue); 02109 f->retrans = -1; 02110 /* Free the IAX frame */ 02111 iax2_frame_free(f); 02112 } 02113 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6203 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
06204 { 06205 /* Called from IAX thread only, without iaxs lock */ 06206 int callno = (int)(long)(nothing); 06207 struct iax_ie_data ied; 06208 ast_mutex_lock(&iaxsl[callno]); 06209 if (iaxs[callno]) { 06210 memset(&ied, 0, sizeof(ied)); 06211 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06212 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06213 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06214 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06215 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06216 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06217 } 06218 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06219 } 06220 ast_mutex_unlock(&iaxsl[callno]); 06221 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 2995 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
02996 { 02997 int callno = PTR_TO_CALLNO(nothing); 02998 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02999 ast_mutex_lock(&iaxsl[callno]); 03000 if (iaxs[callno]) { 03001 iaxs[callno]->initid = -1; 03002 iax2_queue_frame(callno, &f); 03003 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03004 } 03005 ast_mutex_unlock(&iaxsl[callno]); 03006 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6252 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
06253 { 06254 /* Called from IAX thread only, without iaxs lock */ 06255 int callno = (int)(long)(nothing); 06256 struct iax_ie_data ied; 06257 ast_mutex_lock(&iaxsl[callno]); 06258 if (iaxs[callno]) { 06259 memset(&ied, 0, sizeof(ied)); 06260 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06261 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06262 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06263 } 06264 ast_mutex_unlock(&iaxsl[callno]); 06265 }
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 1797 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().
01798 { 01799 /* Just deliver the packet by using queueing. This is called by 01800 the IAX thread with the iaxsl lock held. */ 01801 struct iax_frame *fr = data; 01802 fr->retrans = -1; 01803 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 01804 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01805 iax2_queue_frame(fr->callno, &fr->af); 01806 /* Free our iax frame */ 01807 iax2_frame_free(fr); 01808 /* And don't run again */ 01809 return 0; 01810 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5891 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
05892 { 05893 struct iax2_peer *peer = (struct iax2_peer *) data; 05894 05895 if (!peer) 05896 return; 05897 05898 peer->expire = -1; 05899 05900 if (option_debug) 05901 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 05902 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05903 realtime_update_peer(peer->name, &peer->addr, 0); 05904 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05905 /* Reset the address */ 05906 memset(&peer->addr, 0, sizeof(peer->addr)); 05907 /* Reset expiry value */ 05908 peer->expiry = min_reg_expire; 05909 if (!ast_test_flag(peer, IAX_TEMPONLY)) 05910 ast_db_del("IAX/Registry", peer->name); 05911 register_peer_exten(peer, 0); 05912 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 05913 if (iax2_regfunk) 05914 iax2_regfunk(peer->name, 0); 05915 05916 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 05917 unlink_peer(peer); 05918 05919 peer_unref(peer); 05920 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2431 of file chan_iax2.c.
References __do_deliver(), ast_backtrace(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, LOG_ERROR, 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().
02432 { 02433 int callno = PTR_TO_CALLNO(p); 02434 struct chan_iax2_pvt *pvt = NULL; 02435 struct iax_frame *fr; 02436 jb_frame frame; 02437 int ret; 02438 long now; 02439 long next; 02440 struct timeval tv; 02441 02442 /* Make sure we have a valid private structure before going on */ 02443 ast_mutex_lock(&iaxsl[callno]); 02444 pvt = iaxs[callno]; 02445 if (!pvt) { 02446 /* No go! */ 02447 ast_mutex_unlock(&iaxsl[callno]); 02448 return; 02449 } 02450 02451 if( pvt->jb == NULL ) { 02452 ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" ); 02453 ast_backtrace(); 02454 return; 02455 } 02456 02457 pvt->jbid = -1; 02458 02459 gettimeofday(&tv,NULL); 02460 /* round up a millisecond since ast_sched_runq does; */ 02461 /* prevents us from spinning while waiting for our now */ 02462 /* to catch up with runq's now */ 02463 tv.tv_usec += 1000; 02464 02465 now = ast_tvdiff_ms(tv, pvt->rxcore); 02466 02467 if(now >= (next = jb_next(pvt->jb))) { 02468 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02469 switch(ret) { 02470 case JB_OK: 02471 fr = frame.data; 02472 __do_deliver(fr); 02473 /* __do_deliver() can cause the call to disappear */ 02474 pvt = iaxs[callno]; 02475 break; 02476 case JB_INTERP: 02477 { 02478 struct ast_frame af = { 0, }; 02479 02480 /* create an interpolation frame */ 02481 af.frametype = AST_FRAME_VOICE; 02482 af.subclass = pvt->voiceformat; 02483 af.samples = frame.ms * 8; 02484 af.src = "IAX2 JB interpolation"; 02485 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02486 af.offset = AST_FRIENDLY_OFFSET; 02487 02488 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02489 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02490 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02491 iax2_queue_frame(callno, &af); 02492 /* iax2_queue_frame() could cause the call to disappear */ 02493 pvt = iaxs[callno]; 02494 } 02495 } 02496 break; 02497 case JB_DROP: 02498 iax2_frame_free(frame.data); 02499 break; 02500 case JB_NOFRAME: 02501 case JB_EMPTY: 02502 /* do nothing */ 02503 break; 02504 default: 02505 /* shouldn't happen */ 02506 break; 02507 } 02508 } 02509 if (pvt) 02510 update_jbsched(pvt); 02511 ast_mutex_unlock(&iaxsl[callno]); 02512 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5590 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05591 { 05592 struct iax2_registry *reg = (struct iax2_registry *)data; 05593 reg->expire = -1; 05594 iax2_do_register(reg); 05595 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8639 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
08640 { 08641 struct iax2_peer *peer = (struct iax2_peer *)data; 08642 if (peer->lastms > -1) { 08643 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08644 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08645 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08646 } 08647 if (peer->callno > 0) { 08648 ast_mutex_lock(&iaxsl[peer->callno]); 08649 iax2_destroy(peer->callno); 08650 ast_mutex_unlock(&iaxsl[peer->callno]); 08651 } 08652 peer->callno = 0; 08653 peer->lastms = -1; 08654 /* Try again quickly */ 08655 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08656 if (peer->pokeexpire == -1) 08657 peer_unref(peer); 08658 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6315 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06316 { 06317 struct iax2_peer *peer = (struct iax2_peer *)data; 06318 iax2_poke_peer(peer, 0); 06319 peer_unref(peer); 06320 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4380 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04381 { 04382 regex_t regexbuf; 04383 int havepattern = 0; 04384 int total_peers = 0; 04385 int online_peers = 0; 04386 int offline_peers = 0; 04387 int unmonitored_peers = 0; 04388 struct ao2_iterator i; 04389 04390 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04391 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04392 04393 struct iax2_peer *peer = NULL; 04394 char name[256]; 04395 int registeredonly=0; 04396 char *term = manager ? "\r\n" : "\n"; 04397 04398 switch (argc) { 04399 case 6: 04400 if (!strcasecmp(argv[3], "registered")) 04401 registeredonly = 1; 04402 else 04403 return RESULT_SHOWUSAGE; 04404 if (!strcasecmp(argv[4], "like")) { 04405 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04406 return RESULT_SHOWUSAGE; 04407 havepattern = 1; 04408 } else 04409 return RESULT_SHOWUSAGE; 04410 break; 04411 case 5: 04412 if (!strcasecmp(argv[3], "like")) { 04413 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04414 return RESULT_SHOWUSAGE; 04415 havepattern = 1; 04416 } else 04417 return RESULT_SHOWUSAGE; 04418 break; 04419 case 4: 04420 if (!strcasecmp(argv[3], "registered")) 04421 registeredonly = 1; 04422 else 04423 return RESULT_SHOWUSAGE; 04424 break; 04425 case 3: 04426 break; 04427 default: 04428 return RESULT_SHOWUSAGE; 04429 } 04430 04431 04432 if (s) 04433 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04434 else 04435 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04436 04437 i = ao2_iterator_init(peers, 0); 04438 for (peer = ao2_iterator_next(&i); peer; 04439 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04440 char nm[20]; 04441 char status[20]; 04442 char srch[2000]; 04443 int retstatus; 04444 04445 if (registeredonly && !peer->addr.sin_addr.s_addr) 04446 continue; 04447 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04448 continue; 04449 04450 if (!ast_strlen_zero(peer->username)) 04451 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04452 else 04453 ast_copy_string(name, peer->name, sizeof(name)); 04454 04455 retstatus = peer_status(peer, status, sizeof(status)); 04456 if (retstatus > 0) 04457 online_peers++; 04458 else if (!retstatus) 04459 offline_peers++; 04460 else 04461 unmonitored_peers++; 04462 04463 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04464 04465 snprintf(srch, sizeof(srch), FORMAT, name, 04466 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04467 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04468 nm, 04469 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04470 peer->encmethods ? "(E)" : " ", status, term); 04471 04472 if (s) 04473 astman_append(s, FORMAT, name, 04474 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04475 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04476 nm, 04477 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04478 peer->encmethods ? "(E)" : " ", status, term); 04479 else 04480 ast_cli(fd, FORMAT, name, 04481 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04482 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04483 nm, 04484 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04485 peer->encmethods ? "(E)" : " ", status, term); 04486 total_peers++; 04487 } 04488 04489 if (s) 04490 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04491 else 04492 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04493 04494 if (havepattern) 04495 regfree(®exbuf); 04496 04497 return RESULT_SUCCESS; 04498 #undef FORMAT 04499 #undef FORMAT2 04500 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 941 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00942 { 00943 struct iax2_thread *thread = NULL; 00944 static time_t lasterror; 00945 static time_t t; 00946 00947 thread = find_idle_thread(); 00948 00949 if (thread != NULL) { 00950 thread->schedfunc = func; 00951 thread->scheddata = data; 00952 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00953 #ifdef DEBUG_SCHED_MULTITHREAD 00954 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00955 #endif 00956 signal_condition(&thread->lock, &thread->cond); 00957 return 0; 00958 } 00959 time(&t); 00960 if (t != lasterror && option_debug) 00961 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00962 lasterror = t; 00963 00964 return -1; 00965 }
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 4881 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04883 { 04884 struct ast_frame f = { 0, }; 04885 04886 f.frametype = type; 04887 f.subclass = command; 04888 f.datalen = datalen; 04889 f.src = __FUNCTION__; 04890 f.data = (void *) data; 04891 04892 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04893 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1015 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, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01016 { 01017 int callno = (long)data; 01018 /* Ping only if it's real not if it's bridged */ 01019 ast_mutex_lock(&iaxsl[callno]); 01020 if (iaxs[callno] && iaxs[callno]->lagid > -1) { 01021 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01022 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01023 } 01024 ast_mutex_unlock(&iaxsl[callno]); 01025 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 981 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, sched, send_command(), and send_ping().
Referenced by send_ping().
00982 { 00983 int callno = (long)data; 00984 ast_mutex_lock(&iaxsl[callno]); 00985 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00986 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00987 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 00988 } 00989 ast_mutex_unlock(&iaxsl[callno]); 00990 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10758 of file chan_iax2.c.
References ao2_ref(), 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_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, netsock, outsock, peers, reload_firmware(), sched, sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10759 { 10760 struct iax2_thread *thread = NULL; 10761 int x; 10762 10763 /* Make sure threads do not hold shared resources when they are canceled */ 10764 10765 /* Grab the sched lock resource to keep it away from threads about to die */ 10766 /* Cancel the network thread, close the net socket */ 10767 if (netthreadid != AST_PTHREADT_NULL) { 10768 AST_LIST_LOCK(&iaxq.queue); 10769 ast_mutex_lock(&sched_lock); 10770 pthread_cancel(netthreadid); 10771 ast_cond_signal(&sched_cond); 10772 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10773 AST_LIST_UNLOCK(&iaxq.queue); 10774 pthread_join(netthreadid, NULL); 10775 } 10776 if (schedthreadid != AST_PTHREADT_NULL) { 10777 ast_mutex_lock(&sched_lock); 10778 pthread_cancel(schedthreadid); 10779 ast_cond_signal(&sched_cond); 10780 ast_mutex_unlock(&sched_lock); 10781 pthread_join(schedthreadid, NULL); 10782 } 10783 10784 /* Call for all threads to halt */ 10785 AST_LIST_LOCK(&idle_list); 10786 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10787 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10788 pthread_cancel(thread->threadid); 10789 } 10790 AST_LIST_TRAVERSE_SAFE_END 10791 AST_LIST_UNLOCK(&idle_list); 10792 10793 AST_LIST_LOCK(&active_list); 10794 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10795 AST_LIST_REMOVE_CURRENT(&active_list, list); 10796 pthread_cancel(thread->threadid); 10797 } 10798 AST_LIST_TRAVERSE_SAFE_END 10799 AST_LIST_UNLOCK(&active_list); 10800 10801 AST_LIST_LOCK(&dynamic_list); 10802 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10803 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10804 pthread_cancel(thread->threadid); 10805 } 10806 AST_LIST_TRAVERSE_SAFE_END 10807 AST_LIST_UNLOCK(&dynamic_list); 10808 10809 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10810 10811 /* Wait for threads to exit */ 10812 while(0 < iaxactivethreadcount) 10813 usleep(10000); 10814 10815 ast_netsock_release(netsock); 10816 ast_netsock_release(outsock); 10817 for (x=0;x<IAX_MAX_CALLS;x++) 10818 if (iaxs[x]) 10819 iax2_destroy(x); 10820 ast_manager_unregister( "IAXpeers" ); 10821 ast_manager_unregister( "IAXnetstats" ); 10822 ast_unregister_application(papp); 10823 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10824 ast_unregister_switch(&iax2_switch); 10825 ast_channel_unregister(&iax2_tech); 10826 delete_users(); 10827 iax_provision_unload(); 10828 sched_context_destroy(sched); 10829 reload_firmware(1); 10830 10831 ast_mutex_destroy(&waresl.lock); 10832 10833 for (x = 0; x < IAX_MAX_CALLS; x++) 10834 ast_mutex_destroy(&iaxsl[x]); 10835 10836 ao2_ref(peers, -1); 10837 ao2_ref(users, -1); 10838 10839 return 0; 10840 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 4934 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04935 { 04936 while(con) { 04937 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04938 return -1; 04939 con = con->next; 04940 } 04941 return 0; 04942 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4708 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04709 { 04710 int x; 04711 int numchans = 0; 04712 for (x=0;x<IAX_MAX_CALLS;x++) { 04713 ast_mutex_lock(&iaxsl[x]); 04714 if (iaxs[x]) { 04715 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04716 char *fmt; 04717 jb_info jbinfo; 04718 04719 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04720 jb_getinfo(iaxs[x]->jb, &jbinfo); 04721 localjitter = jbinfo.jitter; 04722 localdelay = jbinfo.current - jbinfo.min; 04723 locallost = jbinfo.frames_lost; 04724 locallosspct = jbinfo.losspct/1000; 04725 localdropped = jbinfo.frames_dropped; 04726 localooo = jbinfo.frames_ooo; 04727 } else { 04728 localjitter = -1; 04729 localdelay = 0; 04730 locallost = -1; 04731 locallosspct = -1; 04732 localdropped = 0; 04733 localooo = -1; 04734 } 04735 if (limit_fmt) 04736 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04737 else 04738 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04739 if (s) 04740 04741 astman_append(s, fmt, 04742 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04743 iaxs[x]->pingtime, 04744 localjitter, 04745 localdelay, 04746 locallost, 04747 locallosspct, 04748 localdropped, 04749 localooo, 04750 iaxs[x]->frames_received/1000, 04751 iaxs[x]->remote_rr.jitter, 04752 iaxs[x]->remote_rr.delay, 04753 iaxs[x]->remote_rr.losscnt, 04754 iaxs[x]->remote_rr.losspct, 04755 iaxs[x]->remote_rr.dropped, 04756 iaxs[x]->remote_rr.ooo, 04757 iaxs[x]->remote_rr.packets/1000); 04758 else 04759 ast_cli(fd, fmt, 04760 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04761 iaxs[x]->pingtime, 04762 localjitter, 04763 localdelay, 04764 locallost, 04765 locallosspct, 04766 localdropped, 04767 localooo, 04768 iaxs[x]->frames_received/1000, 04769 iaxs[x]->remote_rr.jitter, 04770 iaxs[x]->remote_rr.delay, 04771 iaxs[x]->remote_rr.losscnt, 04772 iaxs[x]->remote_rr.losspct, 04773 iaxs[x]->remote_rr.dropped, 04774 iaxs[x]->remote_rr.ooo, 04775 iaxs[x]->remote_rr.packets/1000 04776 ); 04777 numchans++; 04778 } 04779 ast_mutex_unlock(&iaxsl[x]); 04780 } 04781 return numchans; 04782 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 3594 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_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().
03595 { 03596 struct ast_channel *tmp; 03597 struct chan_iax2_pvt *i; 03598 struct ast_variable *v = NULL; 03599 03600 if (!(i = iaxs[callno])) { 03601 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03602 return NULL; 03603 } 03604 03605 /* Don't hold call lock */ 03606 ast_mutex_unlock(&iaxsl[callno]); 03607 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); 03608 ast_mutex_lock(&iaxsl[callno]); 03609 if (!tmp) 03610 return NULL; 03611 tmp->tech = &iax2_tech; 03612 /* We can support any format by default, until we get restricted */ 03613 tmp->nativeformats = capability; 03614 tmp->readformat = ast_best_codec(capability); 03615 tmp->writeformat = ast_best_codec(capability); 03616 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03617 03618 /* Don't use ast_set_callerid() here because it will 03619 * generate a NewCallerID event before the NewChannel event */ 03620 if (!ast_strlen_zero(i->ani)) 03621 tmp->cid.cid_ani = ast_strdup(i->ani); 03622 else 03623 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03624 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03625 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03626 tmp->cid.cid_pres = i->calling_pres; 03627 tmp->cid.cid_ton = i->calling_ton; 03628 tmp->cid.cid_tns = i->calling_tns; 03629 if (!ast_strlen_zero(i->language)) 03630 ast_string_field_set(tmp, language, i->language); 03631 if (!ast_strlen_zero(i->accountcode)) 03632 ast_string_field_set(tmp, accountcode, i->accountcode); 03633 if (i->amaflags) 03634 tmp->amaflags = i->amaflags; 03635 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03636 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03637 if (i->adsi) 03638 tmp->adsicpe = i->peeradsicpe; 03639 else 03640 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03641 i->owner = tmp; 03642 i->capability = capability; 03643 03644 for (v = i->vars ; v ; v = v->next) 03645 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03646 03647 if (state != AST_STATE_DOWN) { 03648 if (ast_pbx_start(tmp)) { 03649 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03650 ast_hangup(tmp); 03651 i->owner = NULL; 03652 return NULL; 03653 } 03654 } 03655 03656 ast_module_ref(ast_module_info->self); 03657 03658 return tmp; 03659 }
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 2115 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02116 { 02117 #ifdef SCHED_MULTITHREADED 02118 if (schedule_action(__attempt_transmit, data)) 02119 #endif 02120 __attempt_transmit(data); 02121 return 0; 02122 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6237 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), iaxs, and sched.
Referenced by socket_process().
06238 { 06239 /* Schedule sending the authentication failure in one second, to prevent 06240 guessing */ 06241 if (iaxs[callno]) { 06242 iaxs[callno]->authfail = failcode; 06243 if (delayreject) { 06244 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06245 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06246 } else 06247 auth_reject((void *)(long)callno); 06248 } 06249 return 0; 06250 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6223 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06224 { 06225 int callno = (int)(long)(data); 06226 ast_mutex_lock(&iaxsl[callno]); 06227 if (iaxs[callno]) 06228 iaxs[callno]->authid = -1; 06229 ast_mutex_unlock(&iaxsl[callno]); 06230 #ifdef SCHED_MULTITHREADED 06231 if (schedule_action(__auth_reject, data)) 06232 #endif 06233 __auth_reject(data); 06234 return 0; 06235 }
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 5459 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, key(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05460 { 05461 int res = -1; 05462 int x; 05463 if (!ast_strlen_zero(keyn)) { 05464 if (!(authmethods & IAX_AUTH_RSA)) { 05465 if (ast_strlen_zero(secret)) 05466 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)); 05467 } else if (ast_strlen_zero(challenge)) { 05468 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05469 } else { 05470 char sig[256]; 05471 struct ast_key *key; 05472 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05473 if (!key) { 05474 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05475 } else { 05476 if (ast_sign(key, (char*)challenge, sig)) { 05477 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05478 res = -1; 05479 } else { 05480 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05481 res = 0; 05482 } 05483 } 05484 } 05485 } 05486 /* Fall back */ 05487 if (res && !ast_strlen_zero(secret)) { 05488 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05489 struct MD5Context md5; 05490 unsigned char digest[16]; 05491 char digres[128]; 05492 MD5Init(&md5); 05493 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05494 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05495 MD5Final(digest, &md5); 05496 /* If they support md5, authenticate with it. */ 05497 for (x=0;x<16;x++) 05498 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05499 if (ecx && dcx) 05500 build_enc_keys(digest, ecx, dcx); 05501 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05502 res = 0; 05503 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05504 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05505 res = 0; 05506 } else 05507 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05508 } 05509 return res; 05510 }
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 5516 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax2_peer::authmethods, chan_iax2_pvt::callno, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, ies, iax2_peer::mask, merge_encryption(), peer_unref(), peers, realtime_peer(), and send_command().
Referenced by socket_process().
05517 { 05518 struct iax2_peer *peer = NULL; 05519 /* Start pessimistic */ 05520 int res = -1; 05521 int authmethods = 0; 05522 struct iax_ie_data ied; 05523 uint16_t callno = p->callno; 05524 05525 memset(&ied, 0, sizeof(ied)); 05526 05527 if (ies->username) 05528 ast_string_field_set(p, username, ies->username); 05529 if (ies->challenge) 05530 ast_string_field_set(p, challenge, ies->challenge); 05531 if (ies->authmethods) 05532 authmethods = ies->authmethods; 05533 if (authmethods & IAX_AUTH_MD5) 05534 merge_encryption(p, ies->encmethods); 05535 else 05536 p->encmethods = 0; 05537 05538 /* Check for override RSA authentication first */ 05539 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05540 /* Normal password authentication */ 05541 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05542 } else { 05543 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05544 while ((peer = ao2_iterator_next(&i))) { 05545 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05546 /* No peer specified at our end, or this is the peer */ 05547 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05548 /* No username specified in peer rule, or this is the right username */ 05549 && (!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))) 05550 /* No specified host, or this is our host */ 05551 ) { 05552 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05553 if (!res) { 05554 peer_unref(peer); 05555 break; 05556 } 05557 } 05558 peer_unref(peer); 05559 } 05560 if (!peer) { 05561 /* We checked our list and didn't find one. It's unlikely, but possible, 05562 that we're trying to authenticate *to* a realtime peer */ 05563 const char *peer_name = ast_strdupa(p->peer); 05564 ast_mutex_unlock(&iaxsl[callno]); 05565 if ((peer = realtime_peer(peer_name, NULL))) { 05566 ast_mutex_lock(&iaxsl[callno]); 05567 if (!(p = iaxs[callno])) { 05568 peer_unref(peer); 05569 return -1; 05570 } 05571 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05572 peer_unref(peer); 05573 } 05574 if (!peer) { 05575 ast_mutex_lock(&iaxsl[callno]); 05576 if (!(p = iaxs[callno])) 05577 return -1; 05578 } 05579 } 05580 } 05581 if (ies->encmethods) 05582 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05583 if (!res) 05584 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05585 return res; 05586 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5194 of file chan_iax2.c.
References ao2_find(), AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, iax2_user::maxauthreq, send_command(), send_command_final(), user_unref(), and users.
Referenced by socket_process().
05195 { 05196 struct iax_ie_data ied; 05197 int res = -1, authreq_restrict = 0; 05198 char challenge[10]; 05199 struct chan_iax2_pvt *p = iaxs[call_num]; 05200 05201 memset(&ied, 0, sizeof(ied)); 05202 05203 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05204 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05205 struct iax2_user *user, tmp_user = { 05206 .name = p->username, 05207 }; 05208 05209 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05210 if (user) { 05211 if (user->curauthreq == user->maxauthreq) 05212 authreq_restrict = 1; 05213 else 05214 user->curauthreq++; 05215 user = user_unref(user); 05216 } 05217 } 05218 05219 /* If the AUTHREQ limit test failed, send back an error */ 05220 if (authreq_restrict) { 05221 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05222 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05223 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05224 return 0; 05225 } 05226 05227 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05228 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05229 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05230 ast_string_field_set(p, challenge, challenge); 05231 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05232 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05233 } 05234 if (p->encmethods) 05235 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05236 05237 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05238 05239 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05240 05241 if (p->encmethods) 05242 ast_set_flag(p, IAX_ENCRYPTED); 05243 05244 return res; 05245 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5247 of file chan_iax2.c.
References ao2_find(), ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, key(), LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05248 { 05249 char requeststr[256]; 05250 char md5secret[256] = ""; 05251 char secret[256] = ""; 05252 char rsasecret[256] = ""; 05253 int res = -1; 05254 int x; 05255 struct iax2_user *user, tmp_user = { 05256 .name = p->username, 05257 }; 05258 05259 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05260 if (user) { 05261 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05262 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05263 ast_clear_flag(p, IAX_MAXAUTHREQ); 05264 } 05265 ast_string_field_set(p, host, user->name); 05266 user = user_unref(user); 05267 } 05268 05269 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05270 return res; 05271 if (ies->password) 05272 ast_copy_string(secret, ies->password, sizeof(secret)); 05273 if (ies->md5_result) 05274 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05275 if (ies->rsa_result) 05276 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05277 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05278 struct ast_key *key; 05279 char *keyn; 05280 char tmpkey[256]; 05281 char *stringp=NULL; 05282 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05283 stringp=tmpkey; 05284 keyn = strsep(&stringp, ":"); 05285 while(keyn) { 05286 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05287 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05288 res = 0; 05289 break; 05290 } else if (!key) 05291 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05292 keyn = strsep(&stringp, ":"); 05293 } 05294 } else if (p->authmethods & IAX_AUTH_MD5) { 05295 struct MD5Context md5; 05296 unsigned char digest[16]; 05297 char *tmppw, *stringp; 05298 05299 tmppw = ast_strdupa(p->secret); 05300 stringp = tmppw; 05301 while((tmppw = strsep(&stringp, ";"))) { 05302 MD5Init(&md5); 05303 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05304 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05305 MD5Final(digest, &md5); 05306 /* If they support md5, authenticate with it. */ 05307 for (x=0;x<16;x++) 05308 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05309 if (!strcasecmp(requeststr, md5secret)) { 05310 res = 0; 05311 break; 05312 } 05313 } 05314 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05315 if (!strcmp(secret, p->secret)) 05316 res = 0; 05317 } 05318 return res; 05319 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3008 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03009 { 03010 #ifdef SCHED_MULTITHREADED 03011 if (schedule_action(__auto_congest, data)) 03012 #endif 03013 __auto_congest(data); 03014 return 0; 03015 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6267 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06268 { 06269 int callno = (int)(long)(data); 06270 ast_mutex_lock(&iaxsl[callno]); 06271 if (iaxs[callno]) { 06272 iaxs[callno]->autoid = -1; 06273 } 06274 ast_mutex_unlock(&iaxsl[callno]); 06275 #ifdef SCHED_MULTITHREADED 06276 if (schedule_action(__auto_hangup, data)) 06277 #endif 06278 __auto_hangup(data); 06279 return 0; 06280 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 8953 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
08954 { 08955 struct iax2_context *con; 08956 08957 if ((con = ast_calloc(1, sizeof(*con)))) 08958 ast_copy_string(con->context, context, sizeof(con->context)); 08959 08960 return con; 08961 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3966 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03967 { 03968 aes_encrypt_key128(digest, ecx); 03969 aes_decrypt_key128(digest, dcx); 03970 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 9099 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), cid_name, cid_num, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, prefs, sched, secret, unlink_peer(), and ast_variable::value.
09100 { 09101 struct iax2_peer *peer = NULL; 09102 struct ast_ha *oldha = NULL; 09103 int maskfound=0; 09104 int found=0; 09105 int firstpass=1; 09106 struct iax2_peer tmp_peer = { 09107 .name = name, 09108 }; 09109 09110 if (!temponly) { 09111 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09112 if (peer && !ast_test_flag(peer, IAX_DELME)) 09113 firstpass = 0; 09114 } 09115 09116 if (peer) { 09117 found++; 09118 if (firstpass) { 09119 oldha = peer->ha; 09120 peer->ha = NULL; 09121 } 09122 unlink_peer(peer); 09123 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09124 peer->expire = -1; 09125 peer->pokeexpire = -1; 09126 peer->sockfd = defaultsockfd; 09127 if (ast_string_field_init(peer, 32)) 09128 peer = peer_unref(peer); 09129 } 09130 09131 if (peer) { 09132 if (firstpass) { 09133 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09134 peer->encmethods = iax2_encryption; 09135 peer->adsi = adsi; 09136 ast_string_field_set(peer,secret,""); 09137 if (!found) { 09138 ast_string_field_set(peer, name, name); 09139 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09140 peer->expiry = min_reg_expire; 09141 } 09142 peer->prefs = prefs; 09143 peer->capability = iax2_capability; 09144 peer->smoothing = 0; 09145 peer->pokefreqok = DEFAULT_FREQ_OK; 09146 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09147 ast_string_field_set(peer,context,""); 09148 ast_string_field_set(peer,peercontext,""); 09149 ast_clear_flag(peer, IAX_HASCALLERID); 09150 ast_string_field_set(peer, cid_name, ""); 09151 ast_string_field_set(peer, cid_num, ""); 09152 } 09153 09154 if (!v) { 09155 v = alt; 09156 alt = NULL; 09157 } 09158 while(v) { 09159 if (!strcasecmp(v->name, "secret")) { 09160 ast_string_field_set(peer, secret, v->value); 09161 } else if (!strcasecmp(v->name, "mailbox")) { 09162 ast_string_field_set(peer, mailbox, v->value); 09163 } else if (!strcasecmp(v->name, "mohinterpret")) { 09164 ast_string_field_set(peer, mohinterpret, v->value); 09165 } else if (!strcasecmp(v->name, "mohsuggest")) { 09166 ast_string_field_set(peer, mohsuggest, v->value); 09167 } else if (!strcasecmp(v->name, "dbsecret")) { 09168 ast_string_field_set(peer, dbsecret, v->value); 09169 } else if (!strcasecmp(v->name, "trunk")) { 09170 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09171 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09172 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09173 ast_clear_flag(peer, IAX_TRUNK); 09174 } 09175 } else if (!strcasecmp(v->name, "auth")) { 09176 peer->authmethods = get_auth_methods(v->value); 09177 } else if (!strcasecmp(v->name, "encryption")) { 09178 peer->encmethods = get_encrypt_methods(v->value); 09179 } else if (!strcasecmp(v->name, "notransfer")) { 09180 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09181 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09182 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09183 } else if (!strcasecmp(v->name, "transfer")) { 09184 if (!strcasecmp(v->value, "mediaonly")) { 09185 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09186 } else if (ast_true(v->value)) { 09187 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09188 } else 09189 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09190 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09191 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09192 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09193 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09194 } else if (!strcasecmp(v->name, "host")) { 09195 if (!strcasecmp(v->value, "dynamic")) { 09196 /* They'll register with us */ 09197 ast_set_flag(peer, IAX_DYNAMIC); 09198 if (!found) { 09199 /* Initialize stuff iff we're not found, otherwise 09200 we keep going with what we had */ 09201 memset(&peer->addr.sin_addr, 0, 4); 09202 if (peer->addr.sin_port) { 09203 /* If we've already got a port, make it the default rather than absolute */ 09204 peer->defaddr.sin_port = peer->addr.sin_port; 09205 peer->addr.sin_port = 0; 09206 } 09207 } 09208 } else { 09209 /* Non-dynamic. Make sure we become that way if we're not */ 09210 AST_SCHED_DEL(sched, peer->expire); 09211 ast_clear_flag(peer, IAX_DYNAMIC); 09212 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09213 return peer_unref(peer); 09214 if (!peer->addr.sin_port) 09215 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09216 } 09217 if (!maskfound) 09218 inet_aton("255.255.255.255", &peer->mask); 09219 } else if (!strcasecmp(v->name, "defaultip")) { 09220 if (ast_get_ip(&peer->defaddr, v->value)) 09221 return peer_unref(peer); 09222 } else if (!strcasecmp(v->name, "sourceaddress")) { 09223 peer_set_srcaddr(peer, v->value); 09224 } else if (!strcasecmp(v->name, "permit") || 09225 !strcasecmp(v->name, "deny")) { 09226 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09227 } else if (!strcasecmp(v->name, "mask")) { 09228 maskfound++; 09229 inet_aton(v->value, &peer->mask); 09230 } else if (!strcasecmp(v->name, "context")) { 09231 ast_string_field_set(peer, context, v->value); 09232 } else if (!strcasecmp(v->name, "regexten")) { 09233 ast_string_field_set(peer, regexten, v->value); 09234 } else if (!strcasecmp(v->name, "peercontext")) { 09235 ast_string_field_set(peer, peercontext, v->value); 09236 } else if (!strcasecmp(v->name, "port")) { 09237 if (ast_test_flag(peer, IAX_DYNAMIC)) 09238 peer->defaddr.sin_port = htons(atoi(v->value)); 09239 else 09240 peer->addr.sin_port = htons(atoi(v->value)); 09241 } else if (!strcasecmp(v->name, "username")) { 09242 ast_string_field_set(peer, username, v->value); 09243 } else if (!strcasecmp(v->name, "allow")) { 09244 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09245 } else if (!strcasecmp(v->name, "disallow")) { 09246 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09247 } else if (!strcasecmp(v->name, "callerid")) { 09248 if (!ast_strlen_zero(v->value)) { 09249 char name2[80]; 09250 char num2[80]; 09251 ast_callerid_split(v->value, name2, 80, num2, 80); 09252 ast_string_field_set(peer, cid_name, name2); 09253 ast_string_field_set(peer, cid_num, num2); 09254 ast_set_flag(peer, IAX_HASCALLERID); 09255 } else { 09256 ast_clear_flag(peer, IAX_HASCALLERID); 09257 ast_string_field_set(peer, cid_name, ""); 09258 ast_string_field_set(peer, cid_num, ""); 09259 } 09260 } else if (!strcasecmp(v->name, "fullname")) { 09261 if (!ast_strlen_zero(v->value)) { 09262 ast_string_field_set(peer, cid_name, v->value); 09263 ast_set_flag(peer, IAX_HASCALLERID); 09264 } else { 09265 ast_string_field_set(peer, cid_name, ""); 09266 if (ast_strlen_zero(peer->cid_num)) 09267 ast_clear_flag(peer, IAX_HASCALLERID); 09268 } 09269 } else if (!strcasecmp(v->name, "cid_number")) { 09270 if (!ast_strlen_zero(v->value)) { 09271 ast_string_field_set(peer, cid_num, v->value); 09272 ast_set_flag(peer, IAX_HASCALLERID); 09273 } else { 09274 ast_string_field_set(peer, cid_num, ""); 09275 if (ast_strlen_zero(peer->cid_name)) 09276 ast_clear_flag(peer, IAX_HASCALLERID); 09277 } 09278 } else if (!strcasecmp(v->name, "sendani")) { 09279 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09280 } else if (!strcasecmp(v->name, "inkeys")) { 09281 ast_string_field_set(peer, inkeys, v->value); 09282 } else if (!strcasecmp(v->name, "outkey")) { 09283 ast_string_field_set(peer, outkey, v->value); 09284 } else if (!strcasecmp(v->name, "qualify")) { 09285 if (!strcasecmp(v->value, "no")) { 09286 peer->maxms = 0; 09287 } else if (!strcasecmp(v->value, "yes")) { 09288 peer->maxms = DEFAULT_MAXMS; 09289 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09290 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); 09291 peer->maxms = 0; 09292 } 09293 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09294 peer->smoothing = ast_true(v->value); 09295 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09296 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09297 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); 09298 } 09299 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09300 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09301 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); 09302 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09303 } else if (!strcasecmp(v->name, "timezone")) { 09304 ast_string_field_set(peer, zonetag, v->value); 09305 } else if (!strcasecmp(v->name, "adsi")) { 09306 peer->adsi = ast_true(v->value); 09307 }/* else if (strcasecmp(v->name,"type")) */ 09308 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09309 v = v->next; 09310 if (!v) { 09311 v = alt; 09312 alt = NULL; 09313 } 09314 } 09315 if (!peer->authmethods) 09316 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09317 ast_clear_flag(peer, IAX_DELME); 09318 /* Make sure these are IPv4 addresses */ 09319 peer->addr.sin_family = AF_INET; 09320 } 09321 if (oldha) 09322 ast_free_ha(oldha); 09323 return peer; 09324 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 9340 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_user::prefs, prefs, secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09341 { 09342 struct iax2_user *user = NULL; 09343 struct iax2_context *con, *conl = NULL; 09344 struct ast_ha *oldha = NULL; 09345 struct iax2_context *oldcon = NULL; 09346 int format; 09347 int firstpass=1; 09348 int oldcurauthreq = 0; 09349 char *varname = NULL, *varval = NULL; 09350 struct ast_variable *tmpvar = NULL; 09351 struct iax2_user tmp_user = { 09352 .name = name, 09353 }; 09354 09355 if (!temponly) { 09356 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09357 if (user && !ast_test_flag(user, IAX_DELME)) 09358 firstpass = 0; 09359 } 09360 09361 if (user) { 09362 if (firstpass) { 09363 oldcurauthreq = user->curauthreq; 09364 oldha = user->ha; 09365 oldcon = user->contexts; 09366 user->ha = NULL; 09367 user->contexts = NULL; 09368 } 09369 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09370 ao2_unlink(users, user); 09371 } else { 09372 user = ao2_alloc(sizeof(*user), user_destructor); 09373 } 09374 09375 if (user) { 09376 if (firstpass) { 09377 ast_string_field_free_memory(user); 09378 memset(user, 0, sizeof(struct iax2_user)); 09379 if (ast_string_field_init(user, 32)) { 09380 user = user_unref(user); 09381 goto cleanup; 09382 } 09383 user->maxauthreq = maxauthreq; 09384 user->curauthreq = oldcurauthreq; 09385 user->prefs = prefs; 09386 user->capability = iax2_capability; 09387 user->encmethods = iax2_encryption; 09388 user->adsi = adsi; 09389 ast_string_field_set(user, name, name); 09390 ast_string_field_set(user, language, language); 09391 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09392 ast_clear_flag(user, IAX_HASCALLERID); 09393 ast_string_field_set(user, cid_name, ""); 09394 ast_string_field_set(user, cid_num, ""); 09395 } 09396 if (!v) { 09397 v = alt; 09398 alt = NULL; 09399 } 09400 while(v) { 09401 if (!strcasecmp(v->name, "context")) { 09402 con = build_context(v->value); 09403 if (con) { 09404 if (conl) 09405 conl->next = con; 09406 else 09407 user->contexts = con; 09408 conl = con; 09409 } 09410 } else if (!strcasecmp(v->name, "permit") || 09411 !strcasecmp(v->name, "deny")) { 09412 user->ha = ast_append_ha(v->name, v->value, user->ha); 09413 } else if (!strcasecmp(v->name, "setvar")) { 09414 varname = ast_strdupa(v->value); 09415 if (varname && (varval = strchr(varname,'='))) { 09416 *varval = '\0'; 09417 varval++; 09418 if((tmpvar = ast_variable_new(varname, varval))) { 09419 tmpvar->next = user->vars; 09420 user->vars = tmpvar; 09421 } 09422 } 09423 } else if (!strcasecmp(v->name, "allow")) { 09424 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09425 } else if (!strcasecmp(v->name, "disallow")) { 09426 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09427 } else if (!strcasecmp(v->name, "trunk")) { 09428 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09429 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09430 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09431 ast_clear_flag(user, IAX_TRUNK); 09432 } 09433 } else if (!strcasecmp(v->name, "auth")) { 09434 user->authmethods = get_auth_methods(v->value); 09435 } else if (!strcasecmp(v->name, "encryption")) { 09436 user->encmethods = get_encrypt_methods(v->value); 09437 } else if (!strcasecmp(v->name, "notransfer")) { 09438 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09439 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09440 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09441 } else if (!strcasecmp(v->name, "transfer")) { 09442 if (!strcasecmp(v->value, "mediaonly")) { 09443 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09444 } else if (ast_true(v->value)) { 09445 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09446 } else 09447 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09448 } else if (!strcasecmp(v->name, "codecpriority")) { 09449 if(!strcasecmp(v->value, "caller")) 09450 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09451 else if(!strcasecmp(v->value, "disabled")) 09452 ast_set_flag(user, IAX_CODEC_NOPREFS); 09453 else if(!strcasecmp(v->value, "reqonly")) { 09454 ast_set_flag(user, IAX_CODEC_NOCAP); 09455 ast_set_flag(user, IAX_CODEC_NOPREFS); 09456 } 09457 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09458 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09459 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09460 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09461 } else if (!strcasecmp(v->name, "dbsecret")) { 09462 ast_string_field_set(user, dbsecret, v->value); 09463 } else if (!strcasecmp(v->name, "secret")) { 09464 if (!ast_strlen_zero(user->secret)) { 09465 char *old = ast_strdupa(user->secret); 09466 09467 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09468 } else 09469 ast_string_field_set(user, secret, v->value); 09470 } else if (!strcasecmp(v->name, "callerid")) { 09471 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09472 char name2[80]; 09473 char num2[80]; 09474 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09475 ast_string_field_set(user, cid_name, name2); 09476 ast_string_field_set(user, cid_num, num2); 09477 ast_set_flag(user, IAX_HASCALLERID); 09478 } else { 09479 ast_clear_flag(user, IAX_HASCALLERID); 09480 ast_string_field_set(user, cid_name, ""); 09481 ast_string_field_set(user, cid_num, ""); 09482 } 09483 } else if (!strcasecmp(v->name, "fullname")) { 09484 if (!ast_strlen_zero(v->value)) { 09485 ast_string_field_set(user, cid_name, v->value); 09486 ast_set_flag(user, IAX_HASCALLERID); 09487 } else { 09488 ast_string_field_set(user, cid_name, ""); 09489 if (ast_strlen_zero(user->cid_num)) 09490 ast_clear_flag(user, IAX_HASCALLERID); 09491 } 09492 } else if (!strcasecmp(v->name, "cid_number")) { 09493 if (!ast_strlen_zero(v->value)) { 09494 ast_string_field_set(user, cid_num, v->value); 09495 ast_set_flag(user, IAX_HASCALLERID); 09496 } else { 09497 ast_string_field_set(user, cid_num, ""); 09498 if (ast_strlen_zero(user->cid_name)) 09499 ast_clear_flag(user, IAX_HASCALLERID); 09500 } 09501 } else if (!strcasecmp(v->name, "accountcode")) { 09502 ast_string_field_set(user, accountcode, v->value); 09503 } else if (!strcasecmp(v->name, "mohinterpret")) { 09504 ast_string_field_set(user, mohinterpret, v->value); 09505 } else if (!strcasecmp(v->name, "mohsuggest")) { 09506 ast_string_field_set(user, mohsuggest, v->value); 09507 } else if (!strcasecmp(v->name, "language")) { 09508 ast_string_field_set(user, language, v->value); 09509 } else if (!strcasecmp(v->name, "amaflags")) { 09510 format = ast_cdr_amaflags2int(v->value); 09511 if (format < 0) { 09512 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09513 } else { 09514 user->amaflags = format; 09515 } 09516 } else if (!strcasecmp(v->name, "inkeys")) { 09517 ast_string_field_set(user, inkeys, v->value); 09518 } else if (!strcasecmp(v->name, "maxauthreq")) { 09519 user->maxauthreq = atoi(v->value); 09520 if (user->maxauthreq < 0) 09521 user->maxauthreq = 0; 09522 } else if (!strcasecmp(v->name, "adsi")) { 09523 user->adsi = ast_true(v->value); 09524 }/* else if (strcasecmp(v->name,"type")) */ 09525 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09526 v = v->next; 09527 if (!v) { 09528 v = alt; 09529 alt = NULL; 09530 } 09531 } 09532 if (!user->authmethods) { 09533 if (!ast_strlen_zero(user->secret)) { 09534 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09535 if (!ast_strlen_zero(user->inkeys)) 09536 user->authmethods |= IAX_AUTH_RSA; 09537 } else if (!ast_strlen_zero(user->inkeys)) { 09538 user->authmethods = IAX_AUTH_RSA; 09539 } else { 09540 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09541 } 09542 } 09543 ast_clear_flag(user, IAX_DELME); 09544 } 09545 cleanup: 09546 if (oldha) 09547 ast_free_ha(oldha); 09548 if (oldcon) 09549 free_context(oldcon); 09550 return user; 09551 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10054 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
10055 { 10056 struct sockaddr_in sin; 10057 int x; 10058 int callno; 10059 struct iax_ie_data ied; 10060 struct create_addr_info cai; 10061 struct parsed_dial_string pds; 10062 char *tmpstr; 10063 10064 for (x=0; x<IAX_MAX_CALLS; x++) { 10065 /* Look for an *exact match* call. Once a call is negotiated, it can only 10066 look up entries for a single context */ 10067 if (!ast_mutex_trylock(&iaxsl[x])) { 10068 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10069 return x; 10070 ast_mutex_unlock(&iaxsl[x]); 10071 } 10072 } 10073 10074 /* No match found, we need to create a new one */ 10075 10076 memset(&cai, 0, sizeof(cai)); 10077 memset(&ied, 0, sizeof(ied)); 10078 memset(&pds, 0, sizeof(pds)); 10079 10080 tmpstr = ast_strdupa(data); 10081 parse_dial_string(tmpstr, &pds); 10082 10083 if (ast_strlen_zero(pds.peer)) { 10084 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10085 return -1; 10086 } 10087 10088 /* Populate our address from the given */ 10089 if (create_addr(pds.peer, NULL, &sin, &cai)) 10090 return -1; 10091 10092 if (option_debug) 10093 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10094 pds.peer, pds.username, pds.password, pds.context); 10095 10096 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 10097 if (callno < 1) { 10098 ast_log(LOG_WARNING, "Unable to create call\n"); 10099 return -1; 10100 } 10101 10102 ast_mutex_lock(&iaxsl[callno]); 10103 ast_string_field_set(iaxs[callno], dproot, data); 10104 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10105 10106 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10107 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10108 /* the string format is slightly different from a standard dial string, 10109 because the context appears in the 'exten' position 10110 */ 10111 if (pds.exten) 10112 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10113 if (pds.username) 10114 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10115 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10116 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10117 /* Keep password handy */ 10118 if (pds.password) 10119 ast_string_field_set(iaxs[callno], secret, pds.password); 10120 if (pds.key) 10121 ast_string_field_set(iaxs[callno], outkey, pds.key); 10122 /* Start the call going */ 10123 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10124 10125 return callno; 10126 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3834 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03835 { 03836 /* Returns where in "receive time" we are. That is, how many ms 03837 since we received (or would have received) the frame with timestamp 0 */ 03838 int ms; 03839 #ifdef IAXTESTS 03840 int jit; 03841 #endif /* IAXTESTS */ 03842 /* Setup rxcore if necessary */ 03843 if (ast_tvzero(p->rxcore)) { 03844 p->rxcore = ast_tvnow(); 03845 if (option_debug && iaxdebug) 03846 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03847 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03848 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03849 #if 1 03850 if (option_debug && iaxdebug) 03851 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03852 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03853 #endif 03854 } 03855 03856 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03857 #ifdef IAXTESTS 03858 if (test_jit) { 03859 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03860 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03861 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03862 jit = -jit; 03863 ms += jit; 03864 } 03865 } 03866 if (test_late) { 03867 ms += test_late; 03868 test_late = 0; 03869 } 03870 #endif /* IAXTESTS */ 03871 return ms; 03872 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3705 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, and chan_iax2_pvt::peercallno.
Referenced by iax2_send(), and socket_process().
03706 { 03707 int ms; 03708 int voice = 0; 03709 int genuine = 0; 03710 int adjust; 03711 struct timeval *delivery = NULL; 03712 03713 03714 /* What sort of frame do we have?: voice is self-explanatory 03715 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03716 non-genuine frames are CONTROL frames [ringing etc], DTMF 03717 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03718 the others need a timestamp slaved to the voice frames so that they go in sequence 03719 */ 03720 if (f) { 03721 if (f->frametype == AST_FRAME_VOICE) { 03722 voice = 1; 03723 delivery = &f->delivery; 03724 } else if (f->frametype == AST_FRAME_IAX) { 03725 genuine = 1; 03726 } else if (f->frametype == AST_FRAME_CNG) { 03727 p->notsilenttx = 0; 03728 } 03729 } 03730 if (ast_tvzero(p->offset)) { 03731 gettimeofday(&p->offset, NULL); 03732 /* Round to nearest 20ms for nice looking traces */ 03733 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03734 } 03735 /* If the timestamp is specified, just send it as is */ 03736 if (ts) 03737 return ts; 03738 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03739 if (delivery && !ast_tvzero(*delivery)) { 03740 ms = ast_tvdiff_ms(*delivery, p->offset); 03741 if (option_debug > 2 && iaxdebug) 03742 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03743 } else { 03744 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03745 if (ms < 0) 03746 ms = 0; 03747 if (voice) { 03748 /* On a voice frame, use predicted values if appropriate */ 03749 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03750 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03751 /* AN EXPLANATION: 03752 When we send voice, we usually send "calculated" timestamps worked out 03753 on the basis of the number of samples sent. When we send other frames, 03754 we usually send timestamps worked out from the real clock. 03755 The problem is that they can tend to drift out of step because the 03756 source channel's clock and our clock may not be exactly at the same rate. 03757 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03758 for this call. Moving it adjusts timestamps for non-voice frames. 03759 We make the adjustment in the style of a moving average. Each time we 03760 adjust p->offset by 10% of the difference between our clock-derived 03761 timestamp and the predicted timestamp. That's why you see "10000" 03762 below even though IAX2 timestamps are in milliseconds. 03763 The use of a moving average avoids offset moving too radically. 03764 Generally, "adjust" roams back and forth around 0, with offset hardly 03765 changing at all. But if a consistent different starts to develop it 03766 will be eliminated over the course of 10 frames (200-300msecs) 03767 */ 03768 adjust = (ms - p->nextpred); 03769 if (adjust < 0) 03770 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03771 else if (adjust > 0) 03772 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03773 03774 if (!p->nextpred) { 03775 p->nextpred = ms; /*f->samples / 8;*/ 03776 if (p->nextpred <= p->lastsent) 03777 p->nextpred = p->lastsent + 3; 03778 } 03779 ms = p->nextpred; 03780 } else { 03781 /* in this case, just use the actual 03782 * time, since we're either way off 03783 * (shouldn't happen), or we're ending a 03784 * silent period -- and seed the next 03785 * predicted time. Also, round ms to the 03786 * next multiple of frame size (so our 03787 * silent periods are multiples of 03788 * frame size too) */ 03789 03790 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03791 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03792 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03793 03794 if (f->samples >= 8) /* check to make sure we dont core dump */ 03795 { 03796 int diff = ms % (f->samples / 8); 03797 if (diff) 03798 ms += f->samples/8 - diff; 03799 } 03800 03801 p->nextpred = ms; 03802 p->notsilenttx = 1; 03803 } 03804 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03805 /* 03806 * IAX2 draft 03 says that timestamps MUST be in order. 03807 * It does not say anything about several frames having the same timestamp 03808 * When transporting video, we can have a frame that spans multiple iax packets 03809 * (so called slices), so it would make sense to use the same timestamp for all of 03810 * them 03811 * We do want to make sure that frames don't go backwards though 03812 */ 03813 if ( (unsigned int)ms < p->lastsent ) 03814 ms = p->lastsent; 03815 } else { 03816 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03817 it's a genuine frame */ 03818 if (genuine) { 03819 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03820 if (ms <= p->lastsent) 03821 ms = p->lastsent + 3; 03822 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03823 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03824 ms = p->lastsent + 3; 03825 } 03826 } 03827 } 03828 p->lastsent = ms; 03829 if (voice) 03830 p->nextpred = p->nextpred + f->samples / 8; 03831 return ms; 03832 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3661 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().
03662 { 03663 unsigned long int mssincetx; /* unsigned to handle overflows */ 03664 long int ms, pred; 03665 03666 tpeer->trunkact = *tv; 03667 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03668 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03669 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03670 tpeer->txtrunktime = *tv; 03671 tpeer->lastsent = 999999; 03672 } 03673 /* Update last transmit time now */ 03674 tpeer->lasttxtime = *tv; 03675 03676 /* Calculate ms offset */ 03677 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03678 /* Predict from last value */ 03679 pred = tpeer->lastsent + sampms; 03680 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03681 ms = pred; 03682 03683 /* We never send the same timestamp twice, so fudge a little if we must */ 03684 if (ms == tpeer->lastsent) 03685 ms = tpeer->lastsent + 1; 03686 tpeer->lastsent = ms; 03687 return ms; 03688 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4945 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, cid_name, cid_num, iax2_context::context, iax2_user::contexts, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, ies, key(), LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), secret, user_unref(), users, ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
04946 { 04947 /* Start pessimistic */ 04948 int res = -1; 04949 int version = 2; 04950 struct iax2_user *user = NULL, *best = NULL; 04951 int bestscore = 0; 04952 int gotcapability = 0; 04953 struct ast_variable *v = NULL, *tmpvar = NULL; 04954 struct ao2_iterator i; 04955 04956 if (!iaxs[callno]) 04957 return res; 04958 if (ies->called_number) 04959 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04960 if (ies->calling_number) { 04961 ast_shrink_phone_number(ies->calling_number); 04962 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04963 } 04964 if (ies->calling_name) 04965 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04966 if (ies->calling_ani) 04967 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04968 if (ies->dnid) 04969 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04970 if (ies->rdnis) 04971 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04972 if (ies->called_context) 04973 ast_string_field_set(iaxs[callno], context, ies->called_context); 04974 if (ies->language) 04975 ast_string_field_set(iaxs[callno], language, ies->language); 04976 if (ies->username) 04977 ast_string_field_set(iaxs[callno], username, ies->username); 04978 if (ies->calling_ton > -1) 04979 iaxs[callno]->calling_ton = ies->calling_ton; 04980 if (ies->calling_tns > -1) 04981 iaxs[callno]->calling_tns = ies->calling_tns; 04982 if (ies->calling_pres > -1) 04983 iaxs[callno]->calling_pres = ies->calling_pres; 04984 if (ies->format) 04985 iaxs[callno]->peerformat = ies->format; 04986 if (ies->adsicpe) 04987 iaxs[callno]->peeradsicpe = ies->adsicpe; 04988 if (ies->capability) { 04989 gotcapability = 1; 04990 iaxs[callno]->peercapability = ies->capability; 04991 } 04992 if (ies->version) 04993 version = ies->version; 04994 04995 /* Use provided preferences until told otherwise for actual preferences */ 04996 if(ies->codec_prefs) { 04997 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04998 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04999 } 05000 05001 if (!gotcapability) 05002 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05003 if (version > IAX_PROTO_VERSION) { 05004 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05005 ast_inet_ntoa(sin->sin_addr), version); 05006 return res; 05007 } 05008 /* Search the userlist for a compatible entry, and fill in the rest */ 05009 i = ao2_iterator_init(users, 0); 05010 while ((user = ao2_iterator_next(&i))) { 05011 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05012 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05013 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05014 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05015 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05016 if (!ast_strlen_zero(iaxs[callno]->username)) { 05017 /* Exact match, stop right now. */ 05018 if (best) 05019 user_unref(best); 05020 best = user; 05021 break; 05022 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05023 /* No required authentication */ 05024 if (user->ha) { 05025 /* There was host authentication and we passed, bonus! */ 05026 if (bestscore < 4) { 05027 bestscore = 4; 05028 if (best) 05029 user_unref(best); 05030 best = user; 05031 continue; 05032 } 05033 } else { 05034 /* No host access, but no secret, either, not bad */ 05035 if (bestscore < 3) { 05036 bestscore = 3; 05037 if (best) 05038 user_unref(best); 05039 best = user; 05040 continue; 05041 } 05042 } 05043 } else { 05044 if (user->ha) { 05045 /* Authentication, but host access too, eh, it's something.. */ 05046 if (bestscore < 2) { 05047 bestscore = 2; 05048 if (best) 05049 user_unref(best); 05050 best = user; 05051 continue; 05052 } 05053 } else { 05054 /* Authentication and no host access... This is our baseline */ 05055 if (bestscore < 1) { 05056 bestscore = 1; 05057 if (best) 05058 user_unref(best); 05059 best = user; 05060 continue; 05061 } 05062 } 05063 } 05064 } 05065 user_unref(user); 05066 } 05067 user = best; 05068 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05069 user = realtime_user(iaxs[callno]->username, sin); 05070 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05071 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05072 user = user_unref(user); 05073 } 05074 } 05075 if (user) { 05076 /* We found our match (use the first) */ 05077 /* copy vars */ 05078 for (v = user->vars ; v ; v = v->next) { 05079 if((tmpvar = ast_variable_new(v->name, v->value))) { 05080 tmpvar->next = iaxs[callno]->vars; 05081 iaxs[callno]->vars = tmpvar; 05082 } 05083 } 05084 /* If a max AUTHREQ restriction is in place, activate it */ 05085 if (user->maxauthreq > 0) 05086 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05087 iaxs[callno]->prefs = user->prefs; 05088 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05089 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05090 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05091 iaxs[callno]->encmethods = user->encmethods; 05092 /* Store the requested username if not specified */ 05093 if (ast_strlen_zero(iaxs[callno]->username)) 05094 ast_string_field_set(iaxs[callno], username, user->name); 05095 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05096 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05097 iaxs[callno]->capability = user->capability; 05098 /* And use the default context */ 05099 if (ast_strlen_zero(iaxs[callno]->context)) { 05100 if (user->contexts) 05101 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05102 else 05103 ast_string_field_set(iaxs[callno], context, context); 05104 } 05105 /* And any input keys */ 05106 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05107 /* And the permitted authentication methods */ 05108 iaxs[callno]->authmethods = user->authmethods; 05109 iaxs[callno]->adsi = user->adsi; 05110 /* If they have callerid, override the given caller id. Always store the ANI */ 05111 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05112 if (ast_test_flag(user, IAX_HASCALLERID)) { 05113 iaxs[callno]->calling_tns = 0; 05114 iaxs[callno]->calling_ton = 0; 05115 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05116 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05117 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05118 } 05119 if (ast_strlen_zero(iaxs[callno]->ani)) 05120 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05121 } else { 05122 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05123 } 05124 if (!ast_strlen_zero(user->accountcode)) 05125 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05126 if (!ast_strlen_zero(user->mohinterpret)) 05127 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05128 if (!ast_strlen_zero(user->mohsuggest)) 05129 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05130 if (user->amaflags) 05131 iaxs[callno]->amaflags = user->amaflags; 05132 if (!ast_strlen_zero(user->language)) 05133 ast_string_field_set(iaxs[callno], language, user->language); 05134 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05135 /* Keep this check last */ 05136 if (!ast_strlen_zero(user->dbsecret)) { 05137 char *family, *key=NULL; 05138 char buf[80]; 05139 family = ast_strdupa(user->dbsecret); 05140 key = strchr(family, '/'); 05141 if (key) { 05142 *key = '\0'; 05143 key++; 05144 } 05145 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05146 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05147 else 05148 ast_string_field_set(iaxs[callno], secret, buf); 05149 } else 05150 ast_string_field_set(iaxs[callno], secret, user->secret); 05151 res = 0; 05152 user = user_unref(user); 05153 } 05154 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05155 return res; 05156 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6625 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06626 { 06627 unsigned int ourver; 06628 char rsi[80]; 06629 snprintf(rsi, sizeof(rsi), "si-%s", si); 06630 if (iax_provision_version(&ourver, rsi, 1)) 06631 return 0; 06632 if (option_debug) 06633 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06634 if (ourver != ver) 06635 iax2_provision(sin, sockfd, NULL, rsi, 1); 06636 return 0; 06637 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 8979 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
08980 { 08981 int sd; 08982 int res; 08983 08984 sd = socket(AF_INET, SOCK_DGRAM, 0); 08985 if (sd < 0) { 08986 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08987 return -1; 08988 } 08989 08990 res = bind(sd, sa, salen); 08991 if (res < 0) { 08992 if (option_debug) 08993 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08994 close(sd); 08995 return 1; 08996 } 08997 08998 close(sd); 08999 return 0; 09000 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5635 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
05636 { 05637 char exten[256] = ""; 05638 int status = CACHE_FLAG_UNKNOWN; 05639 int expiry = iaxdefaultdpcache; 05640 int x; 05641 int matchmore = 0; 05642 struct iax2_dpcache *dp, *prev; 05643 05644 if (ies->called_number) 05645 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05646 05647 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05648 status = CACHE_FLAG_EXISTS; 05649 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05650 status = CACHE_FLAG_CANEXIST; 05651 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05652 status = CACHE_FLAG_NONEXISTENT; 05653 05654 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05655 /* Don't really do anything with this */ 05656 } 05657 if (ies->refresh) 05658 expiry = ies->refresh; 05659 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05660 matchmore = CACHE_FLAG_MATCHMORE; 05661 ast_mutex_lock(&dpcache_lock); 05662 prev = NULL; 05663 dp = pvt->dpentries; 05664 while(dp) { 05665 if (!strcmp(dp->exten, exten)) { 05666 /* Let them go */ 05667 if (prev) 05668 prev->peer = dp->peer; 05669 else 05670 pvt->dpentries = dp->peer; 05671 dp->peer = NULL; 05672 dp->callno = 0; 05673 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05674 if (dp->flags & CACHE_FLAG_PENDING) { 05675 dp->flags &= ~CACHE_FLAG_PENDING; 05676 dp->flags |= status; 05677 dp->flags |= matchmore; 05678 } 05679 /* Wake up waiters */ 05680 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05681 if (dp->waiters[x] > -1) 05682 write(dp->waiters[x], "asdf", 4); 05683 } 05684 prev = dp; 05685 dp = dp->peer; 05686 } 05687 ast_mutex_unlock(&dpcache_lock); 05688 return 0; 05689 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2277 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02278 { 02279 int which = 0; 02280 struct iax2_peer *peer; 02281 char *res = NULL; 02282 int wordlen = strlen(word); 02283 struct ao2_iterator i; 02284 02285 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02286 if (pos != 3) 02287 return NULL; 02288 02289 i = ao2_iterator_init(peers, 0); 02290 while ((peer = ao2_iterator_next(&i))) { 02291 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02292 res = ast_strdup(peer->name); 02293 peer_unref(peer); 02294 break; 02295 } 02296 peer_unref(peer); 02297 } 02298 02299 return res; 02300 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5691 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, 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().
05692 { 05693 int peercallno = 0; 05694 struct chan_iax2_pvt *pvt = iaxs[callno]; 05695 struct iax_frame *cur; 05696 jb_frame frame; 05697 05698 if (ies->callno) 05699 peercallno = ies->callno; 05700 05701 if (peercallno < 1) { 05702 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05703 return -1; 05704 } 05705 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05706 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05707 /* Reset sequence numbers */ 05708 pvt->oseqno = 0; 05709 pvt->rseqno = 0; 05710 pvt->iseqno = 0; 05711 pvt->aseqno = 0; 05712 pvt->peercallno = peercallno; 05713 pvt->transferring = TRANSFER_NONE; 05714 pvt->svoiceformat = -1; 05715 pvt->voiceformat = 0; 05716 pvt->svideoformat = -1; 05717 pvt->videoformat = 0; 05718 pvt->transfercallno = -1; 05719 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05720 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05721 /* reset jitterbuffer */ 05722 while(jb_getall(pvt->jb,&frame) == JB_OK) 05723 iax2_frame_free(frame.data); 05724 jb_reset(pvt->jb); 05725 pvt->lag = 0; 05726 pvt->last = 0; 05727 pvt->lastsent = 0; 05728 pvt->nextpred = 0; 05729 pvt->pingtime = DEFAULT_RETRY_TIME; 05730 AST_LIST_LOCK(&iaxq.queue); 05731 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05732 /* We must cancel any packets that would have been transmitted 05733 because now we're talking to someone new. It's okay, they 05734 were transmitted to someone that didn't care anyway. */ 05735 if (callno == cur->callno) 05736 cur->retries = -1; 05737 } 05738 AST_LIST_UNLOCK(&iaxq.queue); 05739 return 0; 05740 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1036 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), and raw_hangup().
01037 { 01038 int x; 01039 int power=-1; 01040 /* If it's 128 or smaller, just return it */ 01041 if (subclass < IAX_FLAG_SC_LOG) 01042 return subclass; 01043 /* Otherwise find its power */ 01044 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01045 if (subclass & (1 << x)) { 01046 if (power > -1) { 01047 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01048 return 0; 01049 } else 01050 power = x; 01051 } 01052 } 01053 return power | IAX_FLAG_SC_LOG; 01054 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6639 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().
06640 { 06641 jb_info stats; 06642 jb_getinfo(pvt->jb, &stats); 06643 06644 memset(iep, 0, sizeof(*iep)); 06645 06646 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06647 if(stats.frames_in == 0) stats.frames_in = 1; 06648 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06649 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06650 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06651 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06652 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06653 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2900 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
02901 { 02902 struct ast_hostent ahp; 02903 struct hostent *hp; 02904 struct iax2_peer *peer; 02905 int res = -1; 02906 struct ast_codec_pref ourprefs; 02907 02908 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02909 cai->sockfd = defaultsockfd; 02910 cai->maxtime = 0; 02911 sin->sin_family = AF_INET; 02912 02913 if (!(peer = find_peer(peername, 1))) { 02914 cai->found = 0; 02915 02916 hp = ast_gethostbyname(peername, &ahp); 02917 if (hp) { 02918 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02919 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02920 /* use global iax prefs for unknown peer/user */ 02921 /* But move the calling channel's native codec to the top of the preference list */ 02922 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 02923 if (c) 02924 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 02925 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 02926 return 0; 02927 } else { 02928 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02929 return -1; 02930 } 02931 } 02932 02933 cai->found = 1; 02934 02935 /* if the peer has no address (current or default), return failure */ 02936 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 02937 goto return_unref; 02938 02939 /* if the peer is being monitored and is currently unreachable, return failure */ 02940 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 02941 goto return_unref; 02942 02943 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02944 cai->maxtime = peer->maxms; 02945 cai->capability = peer->capability; 02946 cai->encmethods = peer->encmethods; 02947 cai->sockfd = peer->sockfd; 02948 cai->adsi = peer->adsi; 02949 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 02950 /* Move the calling channel's native codec to the top of the preference list */ 02951 if (c) { 02952 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 02953 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 02954 } 02955 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 02956 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02957 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02958 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02959 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02960 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02961 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02962 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02963 if (ast_strlen_zero(peer->dbsecret)) { 02964 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02965 } else { 02966 char *family; 02967 char *key = NULL; 02968 02969 family = ast_strdupa(peer->dbsecret); 02970 key = strchr(family, '/'); 02971 if (key) 02972 *key++ = '\0'; 02973 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02974 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02975 goto return_unref; 02976 } 02977 } 02978 02979 if (peer->addr.sin_addr.s_addr) { 02980 sin->sin_addr = peer->addr.sin_addr; 02981 sin->sin_port = peer->addr.sin_port; 02982 } else { 02983 sin->sin_addr = peer->defaddr.sin_addr; 02984 sin->sin_port = peer->defaddr.sin_port; 02985 } 02986 02987 res = 0; 02988 02989 return_unref: 02990 peer_unref(peer); 02991 02992 return res; 02993 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4020 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
04021 { 04022 int padding; 04023 unsigned char *workspace; 04024 04025 workspace = alloca(*datalen); 04026 memset(f, 0, sizeof(*f)); 04027 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04028 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04029 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04030 return -1; 04031 /* Decrypt */ 04032 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04033 04034 padding = 16 + (workspace[15] & 0xf); 04035 if (option_debug && iaxdebug) 04036 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04037 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04038 return -1; 04039 04040 *datalen -= padding; 04041 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04042 f->frametype = fh->type; 04043 if (f->frametype == AST_FRAME_VIDEO) { 04044 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04045 } else { 04046 f->subclass = uncompress_subclass(fh->csub); 04047 } 04048 } else { 04049 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04050 if (option_debug && iaxdebug) 04051 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04052 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04053 return -1; 04054 /* Decrypt */ 04055 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04056 padding = 16 + (workspace[15] & 0x0f); 04057 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04058 return -1; 04059 *datalen -= padding; 04060 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04061 } 04062 return 0; 04063 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4106 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
04107 { 04108 int res=-1; 04109 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04110 /* Search for possible keys, given secrets */ 04111 struct MD5Context md5; 04112 unsigned char digest[16]; 04113 char *tmppw, *stringp; 04114 04115 tmppw = ast_strdupa(iaxs[callno]->secret); 04116 stringp = tmppw; 04117 while ((tmppw = strsep(&stringp, ";"))) { 04118 MD5Init(&md5); 04119 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04120 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04121 MD5Final(digest, &md5); 04122 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04123 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04124 if (!res) { 04125 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04126 break; 04127 } 04128 } 04129 } else 04130 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04131 return res; 04132 }
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 6701 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().
06702 { 06703 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06704 struct ast_iax2_full_hdr *fh, *cur_fh; 06705 06706 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06707 return; 06708 06709 pkt_buf->len = from_here->buf_len; 06710 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06711 06712 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06713 ast_mutex_lock(&to_here->lock); 06714 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06715 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06716 if (fh->oseqno < cur_fh->oseqno) { 06717 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06718 break; 06719 } 06720 } 06721 AST_LIST_TRAVERSE_SAFE_END 06722 06723 if (!cur_pkt_buf) 06724 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06725 06726 ast_mutex_unlock(&to_here->lock); 06727 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9571 of file chan_iax2.c.
References ao2_callback(), ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
09572 { 09573 struct iax2_registry *reg; 09574 09575 ao2_callback(users, 0, user_delme_cb, NULL); 09576 09577 AST_LIST_LOCK(®istrations); 09578 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09579 ast_sched_del(sched, reg->expire); 09580 if (reg->callno) { 09581 ast_mutex_lock(&iaxsl[reg->callno]); 09582 if (iaxs[reg->callno]) { 09583 iaxs[reg->callno]->reg = NULL; 09584 iax2_destroy(reg->callno); 09585 } 09586 ast_mutex_unlock(&iaxsl[reg->callno]); 09587 } 09588 if (reg->dnsmgr) 09589 ast_dnsmgr_release(reg->dnsmgr); 09590 free(reg); 09591 } 09592 AST_LIST_UNLOCK(®istrations); 09593 09594 ao2_callback(peers, 0, peer_delme_cb, NULL); 09595 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1524 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01525 { 01526 /* Close firmware */ 01527 if (cur->fwh) { 01528 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01529 } 01530 close(cur->fd); 01531 free(cur); 01532 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6473 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06474 { 06475 unsigned short dpstatus = 0; 06476 struct iax_ie_data ied1; 06477 int mm; 06478 06479 memset(&ied1, 0, sizeof(ied1)); 06480 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06481 /* Must be started */ 06482 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06483 dpstatus = IAX_DPSTATUS_EXISTS; 06484 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06485 dpstatus = IAX_DPSTATUS_CANEXIST; 06486 } else { 06487 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06488 } 06489 if (ast_ignore_pattern(context, callednum)) 06490 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06491 if (mm) 06492 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06493 if (!skiplock) 06494 ast_mutex_lock(&iaxsl[callno]); 06495 if (iaxs[callno]) { 06496 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06497 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06498 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06499 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06500 } 06501 if (!skiplock) 06502 ast_mutex_unlock(&iaxsl[callno]); 06503 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6505 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().
06506 { 06507 /* Look up for dpreq */ 06508 struct dpreq_data *dpr = data; 06509 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06510 if (dpr->callerid) 06511 free(dpr->callerid); 06512 free(dpr); 06513 return NULL; 06514 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4065 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
04066 { 04067 int padding; 04068 unsigned char *workspace; 04069 workspace = alloca(*datalen + 32); 04070 if (!workspace) 04071 return -1; 04072 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04073 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04074 if (option_debug && iaxdebug) 04075 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04076 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04077 padding = 16 + (padding & 0xf); 04078 memcpy(workspace, poo, padding); 04079 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04080 workspace[15] &= 0xf0; 04081 workspace[15] |= (padding & 0xf); 04082 if (option_debug && iaxdebug) 04083 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]); 04084 *datalen += padding; 04085 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04086 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04087 memcpy(poo, workspace + *datalen - 32, 32); 04088 } else { 04089 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04090 if (option_debug && iaxdebug) 04091 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04092 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04093 padding = 16 + (padding & 0xf); 04094 memcpy(workspace, poo, padding); 04095 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04096 workspace[15] &= 0xf0; 04097 workspace[15] |= (padding & 0x0f); 04098 *datalen += padding; 04099 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04100 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04101 memcpy(poo, workspace + *datalen - 32, 32); 04102 } 04103 return 0; 04104 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5922 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
05923 { 05924 #ifdef SCHED_MULTITHREADED 05925 if (schedule_action(__expire_registry, data)) 05926 #endif 05927 __expire_registry(data); 05928 return 0; 05929 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 10128 of file chan_iax2.c.
References ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, timeout, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
10129 { 10130 struct iax2_dpcache *dp, *prev = NULL, *next; 10131 struct timeval tv; 10132 int x; 10133 int com[2]; 10134 int timeout; 10135 int old=0; 10136 int outfd; 10137 int abort; 10138 int callno; 10139 struct ast_channel *c; 10140 struct ast_frame *f; 10141 gettimeofday(&tv, NULL); 10142 dp = dpcache; 10143 while(dp) { 10144 next = dp->next; 10145 /* Expire old caches */ 10146 if (ast_tvcmp(tv, dp->expiry) > 0) { 10147 /* It's expired, let it disappear */ 10148 if (prev) 10149 prev->next = dp->next; 10150 else 10151 dpcache = dp->next; 10152 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10153 /* Free memory and go again */ 10154 free(dp); 10155 } else { 10156 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); 10157 } 10158 dp = next; 10159 continue; 10160 } 10161 /* We found an entry that matches us! */ 10162 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10163 break; 10164 prev = dp; 10165 dp = next; 10166 } 10167 if (!dp) { 10168 /* No matching entry. Create a new one. */ 10169 /* First, can we make a callno? */ 10170 callno = cache_get_callno_locked(data); 10171 if (callno < 0) { 10172 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10173 return NULL; 10174 } 10175 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10176 ast_mutex_unlock(&iaxsl[callno]); 10177 return NULL; 10178 } 10179 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10180 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10181 gettimeofday(&dp->expiry, NULL); 10182 dp->orig = dp->expiry; 10183 /* Expires in 30 mins by default */ 10184 dp->expiry.tv_sec += iaxdefaultdpcache; 10185 dp->next = dpcache; 10186 dp->flags = CACHE_FLAG_PENDING; 10187 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10188 dp->waiters[x] = -1; 10189 dpcache = dp; 10190 dp->peer = iaxs[callno]->dpentries; 10191 iaxs[callno]->dpentries = dp; 10192 /* Send the request if we're already up */ 10193 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10194 iax2_dprequest(dp, callno); 10195 ast_mutex_unlock(&iaxsl[callno]); 10196 } 10197 /* By here we must have a dp */ 10198 if (dp->flags & CACHE_FLAG_PENDING) { 10199 /* Okay, here it starts to get nasty. We need a pipe now to wait 10200 for a reply to come back so long as it's pending */ 10201 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10202 /* Find an empty slot */ 10203 if (dp->waiters[x] < 0) 10204 break; 10205 } 10206 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10207 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10208 return NULL; 10209 } 10210 if (pipe(com)) { 10211 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10212 return NULL; 10213 } 10214 dp->waiters[x] = com[1]; 10215 /* Okay, now we wait */ 10216 timeout = iaxdefaulttimeout * 1000; 10217 /* Temporarily unlock */ 10218 ast_mutex_unlock(&dpcache_lock); 10219 /* Defer any dtmf */ 10220 if (chan) 10221 old = ast_channel_defer_dtmf(chan); 10222 abort = 0; 10223 while(timeout) { 10224 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10225 if (outfd > -1) { 10226 break; 10227 } 10228 if (c) { 10229 f = ast_read(c); 10230 if (f) 10231 ast_frfree(f); 10232 else { 10233 /* Got hung up on, abort! */ 10234 break; 10235 abort = 1; 10236 } 10237 } 10238 } 10239 if (!timeout) { 10240 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10241 } 10242 ast_mutex_lock(&dpcache_lock); 10243 dp->waiters[x] = -1; 10244 close(com[1]); 10245 close(com[0]); 10246 if (abort) { 10247 /* Don't interpret anything, just abort. Not sure what th epoint 10248 of undeferring dtmf on a hung up channel is but hey whatever */ 10249 if (!old && chan) 10250 ast_channel_undefer_dtmf(chan); 10251 return NULL; 10252 } 10253 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10254 /* Now to do non-independent analysis the results of our wait */ 10255 if (dp->flags & CACHE_FLAG_PENDING) { 10256 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10257 pending. Don't let it take as long to timeout. */ 10258 dp->flags &= ~CACHE_FLAG_PENDING; 10259 dp->flags |= CACHE_FLAG_TIMEOUT; 10260 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10261 systems without leaving it unavailable once the server comes back online */ 10262 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10263 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10264 if (dp->waiters[x] > -1) 10265 write(dp->waiters[x], "asdf", 4); 10266 } 10267 } 10268 /* Our caller will obtain the rest */ 10269 if (!old && chan) 10270 ast_channel_undefer_dtmf(chan); 10271 } 10272 return dp; 10273 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd | |||
) | [static] |
Definition at line 1339 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_process().
01340 { 01341 int res = 0; 01342 int x; 01343 struct timeval now; 01344 char host[80]; 01345 01346 if (new <= NEW_ALLOW) { 01347 /* Look for an existing connection first */ 01348 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01349 ast_mutex_lock(&iaxsl[x]); 01350 if (iaxs[x]) { 01351 /* Look for an exact match */ 01352 if (match(sin, callno, dcallno, iaxs[x])) { 01353 res = x; 01354 } 01355 } 01356 ast_mutex_unlock(&iaxsl[x]); 01357 } 01358 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01359 ast_mutex_lock(&iaxsl[x]); 01360 if (iaxs[x]) { 01361 /* Look for an exact match */ 01362 if (match(sin, callno, dcallno, iaxs[x])) { 01363 res = x; 01364 } 01365 } 01366 ast_mutex_unlock(&iaxsl[x]); 01367 } 01368 } 01369 if ((res < 1) && (new >= NEW_ALLOW)) { 01370 /* It may seem odd that we look through the peer list for a name for 01371 * this *incoming* call. Well, it is weird. However, users don't 01372 * have an IP address/port number that we can match against. So, 01373 * this is just checking for a peer that has that IP/port and 01374 * assuming that we have a user of the same name. This isn't always 01375 * correct, but it will be changed if needed after authentication. */ 01376 if (!iax2_getpeername(*sin, host, sizeof(host))) 01377 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01378 gettimeofday(&now, NULL); 01379 for (x=1;x<TRUNK_CALL_START;x++) { 01380 /* Find first unused call number that hasn't been used in a while */ 01381 ast_mutex_lock(&iaxsl[x]); 01382 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01383 ast_mutex_unlock(&iaxsl[x]); 01384 } 01385 /* We've still got lock held if we found a spot */ 01386 if (x >= TRUNK_CALL_START) { 01387 ast_log(LOG_WARNING, "No more space\n"); 01388 return 0; 01389 } 01390 iaxs[x] = new_iax(sin, host); 01391 update_max_nontrunk(); 01392 if (iaxs[x]) { 01393 if (option_debug && iaxdebug) 01394 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01395 iaxs[x]->sockfd = sockfd; 01396 iaxs[x]->addr.sin_port = sin->sin_port; 01397 iaxs[x]->addr.sin_family = sin->sin_family; 01398 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01399 iaxs[x]->peercallno = callno; 01400 iaxs[x]->callno = x; 01401 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01402 iaxs[x]->expiry = min_reg_expire; 01403 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01404 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01405 iaxs[x]->amaflags = amaflags; 01406 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01407 01408 ast_string_field_set(iaxs[x], accountcode, accountcode); 01409 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01410 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01411 } else { 01412 ast_log(LOG_WARNING, "Out of resources\n"); 01413 ast_mutex_unlock(&iaxsl[x]); 01414 return 0; 01415 } 01416 ast_mutex_unlock(&iaxsl[x]); 01417 res = x; 01418 } 01419 return res; 01420 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 892 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00893 { 00894 pthread_attr_t attr; 00895 struct iax2_thread *thread = NULL; 00896 00897 /* Pop the head of the list off */ 00898 AST_LIST_LOCK(&idle_list); 00899 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00900 AST_LIST_UNLOCK(&idle_list); 00901 00902 /* If no idle thread is available from the regular list, try dynamic */ 00903 if (thread == NULL) { 00904 AST_LIST_LOCK(&dynamic_list); 00905 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00906 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00907 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00908 /* We need to MAKE a thread! */ 00909 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00910 thread->threadnum = iaxdynamicthreadcount; 00911 thread->type = IAX_TYPE_DYNAMIC; 00912 ast_mutex_init(&thread->lock); 00913 ast_cond_init(&thread->cond, NULL); 00914 pthread_attr_init(&attr); 00915 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00916 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00917 free(thread); 00918 thread = NULL; 00919 } else { 00920 /* All went well and the thread is up, so increment our count */ 00921 iaxdynamicthreadcount++; 00922 00923 /* Wait for the thread to be ready before returning it to the caller */ 00924 while (!thread->ready_for_signal) 00925 usleep(1); 00926 } 00927 } 00928 } 00929 AST_LIST_UNLOCK(&dynamic_list); 00930 } 00931 00932 /* this thread is not processing a full frame (since it is idle), 00933 so ensure that the field for the full frame call number is empty */ 00934 if (thread) 00935 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00936 00937 return thread; 00938 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1114 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01115 { 01116 struct iax2_peer *peer = NULL; 01117 struct iax2_peer tmp_peer = { 01118 .name = name, 01119 }; 01120 01121 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01122 01123 /* Now go for realtime if applicable */ 01124 if(!peer && realtime) 01125 peer = realtime_peer(name, NULL); 01126 01127 return peer; 01128 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 3874 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
03875 { 03876 struct iax2_trunk_peer *tpeer; 03877 03878 /* Finds and locks trunk peer */ 03879 ast_mutex_lock(&tpeerlock); 03880 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03881 /* We don't lock here because tpeer->addr *never* changes */ 03882 if (!inaddrcmp(&tpeer->addr, sin)) { 03883 ast_mutex_lock(&tpeer->lock); 03884 break; 03885 } 03886 } 03887 if (!tpeer) { 03888 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03889 ast_mutex_init(&tpeer->lock); 03890 tpeer->lastsent = 9999; 03891 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03892 tpeer->trunkact = ast_tvnow(); 03893 ast_mutex_lock(&tpeer->lock); 03894 tpeer->next = tpeers; 03895 tpeer->sockfd = fd; 03896 tpeers = tpeer; 03897 #ifdef SO_NO_CHECK 03898 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03899 #endif 03900 if (option_debug) 03901 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03902 } 03903 } 03904 ast_mutex_unlock(&tpeerlock); 03905 return tpeer; 03906 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3690 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03691 { 03692 long ms; /* NOT unsigned */ 03693 if (ast_tvzero(iaxs[callno]->rxcore)) { 03694 /* Initialize rxcore time if appropriate */ 03695 gettimeofday(&iaxs[callno]->rxcore, NULL); 03696 /* Round to nearest 20ms so traces look pretty */ 03697 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03698 } 03699 /* Calculate difference between trunk and channel */ 03700 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03701 /* Return as the sum of trunk time and the difference between trunk and real time */ 03702 return ms + ts; 03703 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8736 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08737 { 08738 struct iax2_context *conl; 08739 while(con) { 08740 conl = con; 08741 con = con->next; 08742 free(conl); 08743 } 08744 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10397 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10398 { 10399 struct iax2_peer *peer; 10400 char *peername, *colname; 10401 10402 peername = ast_strdupa(data); 10403 10404 /* if our channel, return the IP address of the endpoint of current channel */ 10405 if (!strcmp(peername,"CURRENTCHANNEL")) { 10406 unsigned short callno; 10407 if (chan->tech != &iax2_tech) 10408 return -1; 10409 callno = PTR_TO_CALLNO(chan->tech_pvt); 10410 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10411 return 0; 10412 } 10413 10414 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10415 *colname++ = '\0'; 10416 else if ((colname = strchr(peername, '|'))) 10417 *colname++ = '\0'; 10418 else 10419 colname = "ip"; 10420 10421 if (!(peer = find_peer(peername, 1))) 10422 return -1; 10423 10424 if (!strcasecmp(colname, "ip")) { 10425 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10426 } else if (!strcasecmp(colname, "status")) { 10427 peer_status(peer, buf, len); 10428 } else if (!strcasecmp(colname, "mailbox")) { 10429 ast_copy_string(buf, peer->mailbox, len); 10430 } else if (!strcasecmp(colname, "context")) { 10431 ast_copy_string(buf, peer->context, len); 10432 } else if (!strcasecmp(colname, "expire")) { 10433 snprintf(buf, len, "%d", peer->expire); 10434 } else if (!strcasecmp(colname, "dynamic")) { 10435 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10436 } else if (!strcasecmp(colname, "callerid_name")) { 10437 ast_copy_string(buf, peer->cid_name, len); 10438 } else if (!strcasecmp(colname, "callerid_num")) { 10439 ast_copy_string(buf, peer->cid_num, len); 10440 } else if (!strcasecmp(colname, "codecs")) { 10441 ast_getformatname_multiple(buf, len -1, peer->capability); 10442 } else if (!strncasecmp(colname, "codec[", 6)) { 10443 char *codecnum, *ptr; 10444 int index = 0, codec = 0; 10445 10446 codecnum = strchr(colname, '['); 10447 *codecnum = '\0'; 10448 codecnum++; 10449 if ((ptr = strchr(codecnum, ']'))) { 10450 *ptr = '\0'; 10451 } 10452 index = atoi(codecnum); 10453 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10454 ast_copy_string(buf, ast_getformatname(codec), len); 10455 } 10456 } 10457 10458 peer_unref(peer); 10459 10460 return 0; 10461 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8963 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08964 { 08965 int methods = 0; 08966 if (strstr(value, "rsa")) 08967 methods |= IAX_AUTH_RSA; 08968 if (strstr(value, "md5")) 08969 methods |= IAX_AUTH_MD5; 08970 if (strstr(value, "plaintext")) 08971 methods |= IAX_AUTH_PLAINTEXT; 08972 return methods; 08973 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1001 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01002 { 01003 int e; 01004 if (!strcasecmp(s, "aes128")) 01005 e = IAX_ENCRYPT_AES128; 01006 else if (ast_true(s)) 01007 e = IAX_ENCRYPT_AES128; 01008 else 01009 e = 0; 01010 return e; 01011 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2514 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02515 { 02516 #ifdef SCHED_MULTITHREADED 02517 if (schedule_action(__get_from_jb, data)) 02518 #endif 02519 __get_from_jb(data); 02520 return 0; 02521 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6671 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), socket_process(), and thread.
06672 { 06673 struct iax2_pkt_buf *pkt_buf; 06674 06675 ast_mutex_lock(&thread->lock); 06676 06677 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06678 ast_mutex_unlock(&thread->lock); 06679 06680 thread->buf = pkt_buf->buf; 06681 thread->buf_len = pkt_buf->len; 06682 thread->buf_size = pkt_buf->len + 1; 06683 06684 socket_process(thread); 06685 06686 thread->buf = NULL; 06687 ast_free(pkt_buf); 06688 06689 ast_mutex_lock(&thread->lock); 06690 } 06691 06692 ast_mutex_unlock(&thread->lock); 06693 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1812 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().
01813 { 01814 /* XXX Ideally we should figure out why an error occured and then abort those 01815 rather than continuing to try. Unfortunately, the published interface does 01816 not seem to work XXX */ 01817 #if 0 01818 struct sockaddr_in *sin; 01819 int res; 01820 struct msghdr m; 01821 struct sock_extended_err e; 01822 m.msg_name = NULL; 01823 m.msg_namelen = 0; 01824 m.msg_iov = NULL; 01825 m.msg_control = &e; 01826 m.msg_controllen = sizeof(e); 01827 m.msg_flags = 0; 01828 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01829 if (res < 0) 01830 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01831 else { 01832 if (m.msg_controllen) { 01833 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01834 if (sin) 01835 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01836 else 01837 ast_log(LOG_WARNING, "No address detected??\n"); 01838 } else { 01839 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01840 } 01841 } 01842 #endif 01843 return 0; 01844 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5743 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05744 { 05745 struct iax2_registry *reg; 05746 /* Start pessimistic */ 05747 char peer[256] = ""; 05748 char msgstatus[60]; 05749 int refresh = 60; 05750 char ourip[256] = "<Unspecified>"; 05751 struct sockaddr_in oldus; 05752 struct sockaddr_in us; 05753 int oldmsgs; 05754 05755 memset(&us, 0, sizeof(us)); 05756 if (ies->apparent_addr) 05757 bcopy(ies->apparent_addr, &us, sizeof(us)); 05758 if (ies->username) 05759 ast_copy_string(peer, ies->username, sizeof(peer)); 05760 if (ies->refresh) 05761 refresh = ies->refresh; 05762 if (ies->calling_number) { 05763 /* We don't do anything with it really, but maybe we should */ 05764 } 05765 reg = iaxs[callno]->reg; 05766 if (!reg) { 05767 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05768 return -1; 05769 } 05770 memcpy(&oldus, ®->us, sizeof(oldus)); 05771 oldmsgs = reg->messages; 05772 if (inaddrcmp(®->addr, sin)) { 05773 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05774 return -1; 05775 } 05776 memcpy(®->us, &us, sizeof(reg->us)); 05777 if (ies->msgcount >= 0) 05778 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05779 /* always refresh the registration at the interval requested by the server 05780 we are registering to 05781 */ 05782 reg->refresh = refresh; 05783 AST_SCHED_DEL(sched, reg->expire); 05784 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05785 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05786 if (option_verbose > 2) { 05787 if (reg->messages > 255) 05788 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05789 else if (reg->messages > 1) 05790 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05791 else if (reg->messages > 0) 05792 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05793 else 05794 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05795 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05796 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05797 } 05798 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05799 } 05800 reg->regstate = REG_STATE_REGISTERED; 05801 return 0; 05802 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3511 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03512 { 03513 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03514 if (option_debug) 03515 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03516 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03517 }
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 3361 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, tv, unlock_both(), and VERBOSE_PREFIX_3.
03362 { 03363 struct ast_channel *cs[3]; 03364 struct ast_channel *who, *other; 03365 int to = -1; 03366 int res = -1; 03367 int transferstarted=0; 03368 struct ast_frame *f; 03369 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03370 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03371 struct timeval waittimer = {0, 0}, tv; 03372 03373 lock_both(callno0, callno1); 03374 if (!iaxs[callno0] || !iaxs[callno1]) { 03375 unlock_both(callno0, callno1); 03376 return AST_BRIDGE_FAILED; 03377 } 03378 /* Put them in native bridge mode */ 03379 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03380 iaxs[callno0]->bridgecallno = callno1; 03381 iaxs[callno1]->bridgecallno = callno0; 03382 } 03383 unlock_both(callno0, callno1); 03384 03385 /* If not, try to bridge until we can execute a transfer, if we can */ 03386 cs[0] = c0; 03387 cs[1] = c1; 03388 for (/* ever */;;) { 03389 /* Check in case we got masqueraded into */ 03390 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03391 if (option_verbose > 2) 03392 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03393 /* Remove from native mode */ 03394 if (c0->tech == &iax2_tech) { 03395 ast_mutex_lock(&iaxsl[callno0]); 03396 iaxs[callno0]->bridgecallno = 0; 03397 ast_mutex_unlock(&iaxsl[callno0]); 03398 } 03399 if (c1->tech == &iax2_tech) { 03400 ast_mutex_lock(&iaxsl[callno1]); 03401 iaxs[callno1]->bridgecallno = 0; 03402 ast_mutex_unlock(&iaxsl[callno1]); 03403 } 03404 return AST_BRIDGE_FAILED_NOWARN; 03405 } 03406 if (c0->nativeformats != c1->nativeformats) { 03407 if (option_verbose > 2) { 03408 char buf0[255]; 03409 char buf1[255]; 03410 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03411 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03412 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03413 } 03414 /* Remove from native mode */ 03415 lock_both(callno0, callno1); 03416 if (iaxs[callno0]) 03417 iaxs[callno0]->bridgecallno = 0; 03418 if (iaxs[callno1]) 03419 iaxs[callno1]->bridgecallno = 0; 03420 unlock_both(callno0, callno1); 03421 return AST_BRIDGE_FAILED_NOWARN; 03422 } 03423 /* check if transfered and if we really want native bridging */ 03424 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03425 /* Try the transfer */ 03426 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03427 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03428 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03429 transferstarted = 1; 03430 } 03431 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03432 /* Call has been transferred. We're no longer involved */ 03433 gettimeofday(&tv, NULL); 03434 if (ast_tvzero(waittimer)) { 03435 waittimer = tv; 03436 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03437 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03438 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03439 *fo = NULL; 03440 *rc = c0; 03441 res = AST_BRIDGE_COMPLETE; 03442 break; 03443 } 03444 } 03445 to = 1000; 03446 who = ast_waitfor_n(cs, 2, &to); 03447 if (timeoutms > -1) { 03448 timeoutms -= (1000 - to); 03449 if (timeoutms < 0) 03450 timeoutms = 0; 03451 } 03452 if (!who) { 03453 if (!timeoutms) { 03454 res = AST_BRIDGE_RETRY; 03455 break; 03456 } 03457 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03458 res = AST_BRIDGE_FAILED; 03459 break; 03460 } 03461 continue; 03462 } 03463 f = ast_read(who); 03464 if (!f) { 03465 *fo = NULL; 03466 *rc = who; 03467 res = AST_BRIDGE_COMPLETE; 03468 break; 03469 } 03470 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03471 *fo = f; 03472 *rc = who; 03473 res = AST_BRIDGE_COMPLETE; 03474 break; 03475 } 03476 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03477 if ((f->frametype == AST_FRAME_VOICE) || 03478 (f->frametype == AST_FRAME_TEXT) || 03479 (f->frametype == AST_FRAME_VIDEO) || 03480 (f->frametype == AST_FRAME_IMAGE) || 03481 (f->frametype == AST_FRAME_DTMF)) { 03482 /* monitored dtmf take out of the bridge. 03483 * check if we monitor the specific source. 03484 */ 03485 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03486 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03487 *rc = who; 03488 *fo = f; 03489 res = AST_BRIDGE_COMPLETE; 03490 /* Remove from native mode */ 03491 break; 03492 } 03493 /* everything else goes to the other side */ 03494 ast_write(other, f); 03495 } 03496 ast_frfree(f); 03497 /* Swap who gets priority */ 03498 cs[2] = cs[0]; 03499 cs[0] = cs[1]; 03500 cs[1] = cs[2]; 03501 } 03502 lock_both(callno0, callno1); 03503 if(iaxs[callno0]) 03504 iaxs[callno0]->bridgecallno = 0; 03505 if(iaxs[callno1]) 03506 iaxs[callno1]->bridgecallno = 0; 03507 unlock_both(callno0, callno1); 03508 return res; 03509 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3105 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, and ast_channel::tech_pvt.
03106 { 03107 struct sockaddr_in sin; 03108 char *l=NULL, *n=NULL, *tmpstr; 03109 struct iax_ie_data ied; 03110 char *defaultrdest = "s"; 03111 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03112 struct parsed_dial_string pds; 03113 struct create_addr_info cai; 03114 03115 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03116 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03117 return -1; 03118 } 03119 03120 memset(&cai, 0, sizeof(cai)); 03121 cai.encmethods = iax2_encryption; 03122 03123 memset(&pds, 0, sizeof(pds)); 03124 tmpstr = ast_strdupa(dest); 03125 parse_dial_string(tmpstr, &pds); 03126 03127 if (ast_strlen_zero(pds.peer)) { 03128 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03129 return -1; 03130 } 03131 03132 if (!pds.exten) 03133 pds.exten = defaultrdest; 03134 03135 if (create_addr(pds.peer, c, &sin, &cai)) { 03136 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03137 return -1; 03138 } 03139 03140 if (!pds.username && !ast_strlen_zero(cai.username)) 03141 pds.username = cai.username; 03142 if (!pds.password && !ast_strlen_zero(cai.secret)) 03143 pds.password = cai.secret; 03144 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03145 pds.key = cai.outkey; 03146 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03147 pds.context = cai.peercontext; 03148 03149 /* Keep track of the context for outgoing calls too */ 03150 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03151 03152 if (pds.port) 03153 sin.sin_port = htons(atoi(pds.port)); 03154 03155 l = c->cid.cid_num; 03156 n = c->cid.cid_name; 03157 03158 /* Now build request */ 03159 memset(&ied, 0, sizeof(ied)); 03160 03161 /* On new call, first IE MUST be IAX version of caller */ 03162 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03163 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03164 if (pds.options && strchr(pds.options, 'a')) { 03165 /* Request auto answer */ 03166 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03167 } 03168 03169 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03170 03171 if (l) { 03172 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03173 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03174 } else { 03175 if (n) 03176 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03177 else 03178 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03179 } 03180 03181 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03182 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03183 03184 if (n) 03185 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03186 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03187 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03188 03189 if (!ast_strlen_zero(c->language)) 03190 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03191 if (!ast_strlen_zero(c->cid.cid_dnid)) 03192 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03193 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03194 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03195 03196 if (pds.context) 03197 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03198 03199 if (pds.username) 03200 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03201 03202 if (cai.encmethods) 03203 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03204 03205 ast_mutex_lock(&iaxsl[callno]); 03206 03207 if (!ast_strlen_zero(c->context)) 03208 ast_string_field_set(iaxs[callno], context, c->context); 03209 03210 if (pds.username) 03211 ast_string_field_set(iaxs[callno], username, pds.username); 03212 03213 iaxs[callno]->encmethods = cai.encmethods; 03214 03215 iaxs[callno]->adsi = cai.adsi; 03216 03217 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03218 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03219 03220 if (pds.key) 03221 ast_string_field_set(iaxs[callno], outkey, pds.key); 03222 if (pds.password) 03223 ast_string_field_set(iaxs[callno], secret, pds.password); 03224 03225 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03226 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03227 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03228 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03229 03230 if (iaxs[callno]->maxtime) { 03231 /* Initialize pingtime and auto-congest time */ 03232 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03233 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03234 } else if (autokill) { 03235 iaxs[callno]->pingtime = autokill / 2; 03236 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03237 } 03238 03239 /* send the command using the appropriate socket for this peer */ 03240 iaxs[callno]->sockfd = cai.sockfd; 03241 03242 /* Transmit the string in a "NEW" request */ 03243 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03244 03245 ast_mutex_unlock(&iaxsl[callno]); 03246 ast_setstate(c, AST_STATE_RINGING); 03247 03248 return 0; 03249 }
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 10299 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.
10300 { 10301 int res = 0; 10302 struct iax2_dpcache *dp; 10303 #if 0 10304 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10305 #endif 10306 if ((priority != 1) && (priority != 2)) 10307 return 0; 10308 ast_mutex_lock(&dpcache_lock); 10309 dp = find_cache(chan, data, context, exten, priority); 10310 if (dp) { 10311 if (dp->flags & CACHE_FLAG_CANEXIST) 10312 res= 1; 10313 } 10314 ast_mutex_unlock(&dpcache_lock); 10315 if (!dp) { 10316 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10317 } 10318 return res; 10319 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3017 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03018 { 03019 time_t t; 03020 struct tm tm; 03021 unsigned int tmp; 03022 time(&t); 03023 if (!ast_strlen_zero(tz)) 03024 ast_localtime(&t, &tm, tz); 03025 else 03026 ast_localtime(&t, &tm, NULL); 03027 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03028 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03029 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03030 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03031 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03032 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03033 return tmp; 03034 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1951 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, ast_channel::lock, LOG_NOTICE, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, update_max_trunk(), and chan_iax2_pvt::vars.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01952 { 01953 struct chan_iax2_pvt *pvt; 01954 struct iax_frame *cur; 01955 struct ast_channel *owner; 01956 01957 retry: 01958 pvt = iaxs[callno]; 01959 gettimeofday(&lastused[callno], NULL); 01960 01961 owner = pvt ? pvt->owner : NULL; 01962 01963 if (owner) { 01964 if (ast_mutex_trylock(&owner->lock)) { 01965 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01966 ast_mutex_unlock(&iaxsl[callno]); 01967 usleep(1); 01968 ast_mutex_lock(&iaxsl[callno]); 01969 goto retry; 01970 } 01971 } 01972 if (!owner) 01973 iaxs[callno] = NULL; 01974 if (pvt) { 01975 if (!owner) 01976 pvt->owner = NULL; 01977 iax2_destroy_helper(pvt); 01978 01979 /* Already gone */ 01980 ast_set_flag(pvt, IAX_ALREADYGONE); 01981 01982 if (owner) { 01983 /* If there's an owner, prod it to give up */ 01984 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01985 * because we already hold the owner channel lock. */ 01986 ast_queue_hangup(owner); 01987 } 01988 01989 AST_LIST_LOCK(&iaxq.queue); 01990 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01991 /* Cancel any pending transmissions */ 01992 if (cur->callno == pvt->callno) 01993 cur->retries = -1; 01994 } 01995 AST_LIST_UNLOCK(&iaxq.queue); 01996 01997 if (pvt->reg) 01998 pvt->reg->callno = 0; 01999 if (!owner) { 02000 jb_frame frame; 02001 if (pvt->vars) { 02002 ast_variables_destroy(pvt->vars); 02003 pvt->vars = NULL; 02004 } 02005 02006 while (jb_getall(pvt->jb, &frame) == JB_OK) 02007 iax2_frame_free(frame.data); 02008 jb_destroy(pvt->jb); 02009 /* gotta free up the stringfields */ 02010 ast_string_field_free_memory(pvt); 02011 free(pvt); 02012 } 02013 } 02014 if (owner) { 02015 ast_mutex_unlock(&owner->lock); 02016 } 02017 if (callno & 0x4000) 02018 update_max_trunk(); 02019 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1900 of file chan_iax2.c.
References ao2_find(), ast_clear_flag, AST_SCHED_DEL, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, chan_iax2_pvt::pingid, sched, user_unref(), and users.
Referenced by iax2_destroy(), iax2_predestroy(), and stop_stuff().
01901 { 01902 /* Decrement AUTHREQ count if needed */ 01903 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01904 struct iax2_user *user; 01905 struct iax2_user tmp_user = { 01906 .name = pvt->username, 01907 }; 01908 01909 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01910 if (user) { 01911 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01912 user_unref(user); 01913 } 01914 01915 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01916 } 01917 /* No more pings or lagrq's */ 01918 AST_SCHED_DEL(sched, pvt->pingid); 01919 AST_SCHED_DEL(sched, pvt->lagid); 01920 AST_SCHED_DEL(sched, pvt->autoid); 01921 AST_SCHED_DEL(sched, pvt->authid); 01922 AST_SCHED_DEL(sched, pvt->initid); 01923 AST_SCHED_DEL(sched, pvt->jbid); 01924 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10486 of file chan_iax2.c.
References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().
10487 { 10488 struct parsed_dial_string pds; 10489 char *tmp = ast_strdupa(data); 10490 struct iax2_peer *p; 10491 int res = AST_DEVICE_INVALID; 10492 10493 memset(&pds, 0, sizeof(pds)); 10494 parse_dial_string(tmp, &pds); 10495 10496 if (ast_strlen_zero(pds.peer)) { 10497 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10498 return res; 10499 } 10500 10501 if (option_debug > 2) 10502 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10503 10504 /* SLD: FIXME: second call to find_peer during registration */ 10505 if (!(p = find_peer(pds.peer, 1))) 10506 return res; 10507 10508 res = AST_DEVICE_UNAVAILABLE; 10509 if (option_debug > 2) 10510 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10511 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10512 10513 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10514 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10515 /* Peer is registered, or have default IP address 10516 and a valid registration */ 10517 if (p->historicms == 0 || p->historicms <= p->maxms) 10518 /* let the core figure out whether it is in use or not */ 10519 res = AST_DEVICE_UNKNOWN; 10520 } 10521 10522 peer_unref(p); 10523 10524 return res; 10525 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2633 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02634 { 02635 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02636 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2638 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02639 { 02640 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02641 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4796 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04797 { 04798 if (argc < 2 || argc > 3) 04799 return RESULT_SHOWUSAGE; 04800 iaxdebug = 1; 04801 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04802 return RESULT_SUCCESS; 04803 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4814 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04815 { 04816 if (argc < 3 || argc > 4) 04817 return RESULT_SHOWUSAGE; 04818 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04819 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04820 return RESULT_SUCCESS; 04821 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8464 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08465 { 08466 struct iax_ie_data ied; 08467 if (option_debug && iaxdebug) 08468 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08469 08470 if (reg->dnsmgr && 08471 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08472 /* Maybe the IP has changed, force DNS refresh */ 08473 ast_dnsmgr_refresh(reg->dnsmgr); 08474 } 08475 08476 /* 08477 * if IP has Changed, free allocated call to create a new one with new IP 08478 * call has the pointer to IP and must be updated to the new one 08479 */ 08480 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08481 ast_mutex_lock(&iaxsl[reg->callno]); 08482 iax2_destroy(reg->callno); 08483 ast_mutex_unlock(&iaxsl[reg->callno]); 08484 reg->callno = 0; 08485 } 08486 if (!reg->addr.sin_addr.s_addr) { 08487 if (option_debug && iaxdebug) 08488 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08489 /* Setup the next registration attempt */ 08490 AST_SCHED_DEL(sched, reg->expire); 08491 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08492 return -1; 08493 } 08494 08495 if (!reg->callno) { 08496 if (option_debug) 08497 ast_log(LOG_DEBUG, "Allocate call number\n"); 08498 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, defaultsockfd); 08499 if (reg->callno < 1) { 08500 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08501 return -1; 08502 } else if (option_debug) 08503 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08504 iaxs[reg->callno]->reg = reg; 08505 } 08506 /* Schedule the next registration attempt */ 08507 AST_SCHED_DEL(sched, reg->expire); 08508 /* Setup the next registration a little early */ 08509 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08510 /* Send the request */ 08511 memset(&ied, 0, sizeof(ied)); 08512 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08513 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08514 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08515 reg->regstate = REG_STATE_REGSENT; 08516 return 0; 08517 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5597 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05598 { 05599 #ifdef SCHED_MULTITHREADED 05600 if (schedule_action(__iax2_do_register_s, data)) 05601 #endif 05602 __iax2_do_register_s(data); 05603 return 0; 05604 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4805 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04806 { 04807 if (argc < 3 || argc > 4) 04808 return RESULT_SHOWUSAGE; 04809 iaxtrunkdebug = 1; 04810 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04811 return RESULT_SUCCESS; 04812 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6282 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
06283 { 06284 struct iax_ie_data ied; 06285 /* Auto-hangup with 30 seconds of inactivity */ 06286 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06287 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06288 memset(&ied, 0, sizeof(ied)); 06289 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06290 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06291 dp->flags |= CACHE_FLAG_TRANSMITTED; 06292 }
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 10345 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.
10346 { 10347 char odata[256]; 10348 char req[256]; 10349 char *ncontext; 10350 struct iax2_dpcache *dp; 10351 struct ast_app *dial; 10352 #if 0 10353 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); 10354 #endif 10355 if (priority == 2) { 10356 /* Indicate status, can be overridden in dialplan */ 10357 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10358 if (dialstatus) { 10359 dial = pbx_findapp(dialstatus); 10360 if (dial) 10361 pbx_exec(chan, dial, ""); 10362 } 10363 return -1; 10364 } else if (priority != 1) 10365 return -1; 10366 ast_mutex_lock(&dpcache_lock); 10367 dp = find_cache(chan, data, context, exten, priority); 10368 if (dp) { 10369 if (dp->flags & CACHE_FLAG_EXISTS) { 10370 ast_copy_string(odata, data, sizeof(odata)); 10371 ncontext = strchr(odata, '/'); 10372 if (ncontext) { 10373 *ncontext = '\0'; 10374 ncontext++; 10375 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10376 } else { 10377 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10378 } 10379 if (option_verbose > 2) 10380 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10381 } else { 10382 ast_mutex_unlock(&dpcache_lock); 10383 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10384 return -1; 10385 } 10386 } 10387 ast_mutex_unlock(&dpcache_lock); 10388 dial = pbx_findapp("Dial"); 10389 if (dial) { 10390 return pbx_exec(chan, dial, req); 10391 } else { 10392 ast_log(LOG_WARNING, "No dial application registered\n"); 10393 } 10394 return -1; 10395 }
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 10276 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.
10277 { 10278 struct iax2_dpcache *dp; 10279 int res = 0; 10280 #if 0 10281 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10282 #endif 10283 if ((priority != 1) && (priority != 2)) 10284 return 0; 10285 ast_mutex_lock(&dpcache_lock); 10286 dp = find_cache(chan, data, context, exten, priority); 10287 if (dp) { 10288 if (dp->flags & CACHE_FLAG_EXISTS) 10289 res= 1; 10290 } 10291 ast_mutex_unlock(&dpcache_lock); 10292 if (!dp) { 10293 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10294 } 10295 return res; 10296 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2660 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02661 { 02662 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02663 ast_mutex_lock(&iaxsl[callno]); 02664 if (iaxs[callno]) 02665 iaxs[callno]->owner = newchan; 02666 else 02667 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02668 ast_mutex_unlock(&iaxsl[callno]); 02669 return 0; 02670 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1422 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), iax2_destroy(), and schedule_delivery().
01423 { 01424 AST_SCHED_DEL(sched, fr->retrans); 01425 iax_frame_free(fr); 01426 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1154 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().
01155 { 01156 struct iax2_peer *peer = NULL; 01157 int res = 0; 01158 struct ao2_iterator i; 01159 01160 i = ao2_iterator_init(peers, 0); 01161 while ((peer = ao2_iterator_next(&i))) { 01162 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01163 (peer->addr.sin_port == sin.sin_port)) { 01164 ast_copy_string(host, peer->name, len); 01165 peer_unref(peer); 01166 res = 1; 01167 break; 01168 } 01169 peer_unref(peer); 01170 } 01171 01172 if (!peer) { 01173 peer = realtime_peer(NULL, &sin); 01174 if (peer) { 01175 ast_copy_string(host, peer->name, len); 01176 peer_unref(peer); 01177 res = 1; 01178 } 01179 } 01180 01181 return res; 01182 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3573 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().
03574 { 03575 struct iax2_peer *peer; 03576 int res = 0; 03577 struct ao2_iterator i; 03578 03579 i = ao2_iterator_init(peers, 0); 03580 while ((peer = ao2_iterator_next(&i))) { 03581 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03582 (peer->addr.sin_port == sin.sin_port)) { 03583 res = ast_test_flag(peer, IAX_TRUNK); 03584 peer_unref(peer); 03585 break; 03586 } 03587 peer_unref(peer); 03588 } 03589 03590 return res; 03591 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3251 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, option_debug, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03252 { 03253 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03254 int alreadygone; 03255 struct iax_ie_data ied; 03256 memset(&ied, 0, sizeof(ied)); 03257 ast_mutex_lock(&iaxsl[callno]); 03258 if (callno && iaxs[callno]) { 03259 if (option_debug) 03260 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03261 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03262 /* Send the hangup unless we have had a transmission error or are already gone */ 03263 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03264 if (!iaxs[callno]->error && !alreadygone) { 03265 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03266 if (!iaxs[callno]) { 03267 ast_mutex_unlock(&iaxsl[callno]); 03268 return 0; 03269 } 03270 } 03271 /* Explicitly predestroy it */ 03272 iax2_predestroy(callno); 03273 /* If we were already gone to begin with, destroy us now */ 03274 if (alreadygone && iaxs[callno]) { 03275 if (option_debug) 03276 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03277 iax2_destroy(callno); 03278 } 03279 } 03280 ast_mutex_unlock(&iaxsl[callno]); 03281 if (option_verbose > 2) 03282 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03283 return 0; 03284 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3519 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, option_debug, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03520 { 03521 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03522 struct chan_iax2_pvt *pvt; 03523 int res = 0; 03524 03525 if (option_debug && iaxdebug) 03526 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03527 03528 ast_mutex_lock(&iaxsl[callno]); 03529 pvt = iaxs[callno]; 03530 03531 switch (condition) { 03532 case AST_CONTROL_HOLD: 03533 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03534 ast_moh_start(c, data, pvt->mohinterpret); 03535 goto done; 03536 } 03537 break; 03538 case AST_CONTROL_UNHOLD: 03539 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03540 ast_moh_stop(c); 03541 goto done; 03542 } 03543 } 03544 03545 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03546 03547 done: 03548 ast_mutex_unlock(&iaxsl[callno]); 03549 03550 return res; 03551 }
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 10322 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.
10323 { 10324 int res = 0; 10325 struct iax2_dpcache *dp; 10326 #if 0 10327 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10328 #endif 10329 if ((priority != 1) && (priority != 2)) 10330 return 0; 10331 ast_mutex_lock(&dpcache_lock); 10332 dp = find_cache(chan, data, context, exten, priority); 10333 if (dp) { 10334 if (dp->flags & CACHE_FLAG_MATCHMORE) 10335 res= 1; 10336 } 10337 ast_mutex_unlock(&dpcache_lock); 10338 if (!dp) { 10339 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10340 } 10341 return res; 10342 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4823 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04824 { 04825 if (argc < 3 || argc > 4) 04826 return RESULT_SHOWUSAGE; 04827 iaxdebug = 0; 04828 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04829 return RESULT_SUCCESS; 04830 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4841 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04842 { 04843 if (argc < 4 || argc > 5) 04844 return RESULT_SHOWUSAGE; 04845 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04846 jb_debug_output("\n"); 04847 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04848 return RESULT_SUCCESS; 04849 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4832 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04833 { 04834 if (argc < 4 || argc > 5) 04835 return RESULT_SHOWUSAGE; 04836 iaxtrunkdebug = 0; 04837 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04838 return RESULT_SUCCESS; 04839 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8660 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08661 { 08662 struct iax2_peer *peer = (struct iax2_peer *)data; 08663 peer->pokeexpire = -1; 08664 #ifdef SCHED_MULTITHREADED 08665 if (schedule_action(__iax2_poke_noanswer, data)) 08666 #endif 08667 __iax2_poke_noanswer(data); 08668 peer_unref(peer); 08669 return 0; 08670 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8681 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
08682 { 08683 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08684 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08685 immediately after clearing things out */ 08686 peer->lastms = 0; 08687 peer->historicms = 0; 08688 peer->pokeexpire = -1; 08689 peer->callno = 0; 08690 return 0; 08691 } 08692 if (peer->callno > 0) { 08693 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08694 ast_mutex_lock(&iaxsl[peer->callno]); 08695 iax2_destroy(peer->callno); 08696 ast_mutex_unlock(&iaxsl[peer->callno]); 08697 } 08698 if (heldcall) 08699 ast_mutex_unlock(&iaxsl[heldcall]); 08700 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd); 08701 if (heldcall) 08702 ast_mutex_lock(&iaxsl[heldcall]); 08703 if (peer->callno < 1) { 08704 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08705 return -1; 08706 } 08707 08708 /* Speed up retransmission times for this qualify call */ 08709 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08710 iaxs[peer->callno]->peerpoke = peer; 08711 08712 /* Remove any pending pokeexpire task */ 08713 if (peer->pokeexpire > -1) { 08714 if (!ast_sched_del(sched, peer->pokeexpire)) { 08715 peer->pokeexpire = -1; 08716 peer_unref(peer); 08717 } 08718 } 08719 08720 /* Queue up a new task to handle no reply */ 08721 /* If the host is already unreachable then use the unreachable interval instead */ 08722 if (peer->lastms < 0) { 08723 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08724 } else 08725 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08726 08727 if (peer->pokeexpire == -1) 08728 peer_unref(peer); 08729 08730 /* And send the poke */ 08731 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08732 08733 return 0; 08734 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8672 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08673 { 08674 struct iax2_peer *peer = obj; 08675 08676 iax2_poke_peer(peer, 0); 08677 08678 return 0; 08679 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6322 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06323 { 06324 struct iax2_peer *peer = (struct iax2_peer *)data; 06325 peer->pokeexpire = -1; 06326 #ifdef SCHED_MULTITHREADED 06327 if (schedule_action(__iax2_poke_peer_s, data)) 06328 #endif 06329 __iax2_poke_peer_s(data); 06330 return 0; 06331 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1930 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().
01931 { 01932 struct ast_channel *c; 01933 struct chan_iax2_pvt *pvt = iaxs[callno]; 01934 01935 if (!pvt) 01936 return -1; 01937 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01938 iax2_destroy_helper(pvt); 01939 ast_set_flag(pvt, IAX_ALREADYGONE); 01940 } 01941 c = pvt->owner; 01942 if (c) { 01943 c->tech_pvt = NULL; 01944 iax2_queue_hangup(callno); 01945 pvt->owner = NULL; 01946 ast_module_unref(ast_module_info->self); 01947 } 01948 return 0; 01949 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8339 of file chan_iax2.c.
References ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08340 { 08341 struct iax2_thread *thread = data; 08342 struct timeval tv; 08343 struct timespec ts; 08344 int put_into_idle = 0; 08345 08346 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08347 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08348 for(;;) { 08349 /* Wait for something to signal us to be awake */ 08350 ast_mutex_lock(&thread->lock); 08351 08352 /* Flag that we're ready to accept signals */ 08353 thread->ready_for_signal = 1; 08354 08355 /* Put into idle list if applicable */ 08356 if (put_into_idle) 08357 insert_idle_thread(thread); 08358 08359 if (thread->type == IAX_TYPE_DYNAMIC) { 08360 struct iax2_thread *t = NULL; 08361 /* Wait to be signalled or time out */ 08362 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08363 ts.tv_sec = tv.tv_sec; 08364 ts.tv_nsec = tv.tv_usec * 1000; 08365 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08366 /* This thread was never put back into the available dynamic 08367 * thread list, so just go away. */ 08368 if (!put_into_idle) { 08369 ast_mutex_unlock(&thread->lock); 08370 break; 08371 } 08372 AST_LIST_LOCK(&dynamic_list); 08373 /* Account for the case where this thread is acquired *right* after a timeout */ 08374 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08375 iaxdynamicthreadcount--; 08376 AST_LIST_UNLOCK(&dynamic_list); 08377 if (t) { 08378 /* This dynamic thread timed out waiting for a task and was 08379 * not acquired immediately after the timeout, 08380 * so it's time to go away. */ 08381 ast_mutex_unlock(&thread->lock); 08382 break; 08383 } 08384 /* Someone grabbed our thread *right* after we timed out. 08385 * Wait for them to set us up with something to do and signal 08386 * us to continue. */ 08387 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08388 ts.tv_sec = tv.tv_sec; 08389 ts.tv_nsec = tv.tv_usec * 1000; 08390 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08391 { 08392 ast_mutex_unlock(&thread->lock); 08393 break; 08394 } 08395 } 08396 } else { 08397 ast_cond_wait(&thread->cond, &thread->lock); 08398 } 08399 08400 /* Go back into our respective list */ 08401 put_into_idle = 1; 08402 08403 ast_mutex_unlock(&thread->lock); 08404 08405 if (thread->iostate == IAX_IOSTATE_IDLE) 08406 continue; 08407 08408 /* Add ourselves to the active list now */ 08409 AST_LIST_LOCK(&active_list); 08410 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08411 AST_LIST_UNLOCK(&active_list); 08412 08413 /* See what we need to do */ 08414 switch(thread->iostate) { 08415 case IAX_IOSTATE_READY: 08416 thread->actions++; 08417 thread->iostate = IAX_IOSTATE_PROCESSING; 08418 socket_process(thread); 08419 handle_deferred_full_frames(thread); 08420 break; 08421 case IAX_IOSTATE_SCHEDREADY: 08422 thread->actions++; 08423 thread->iostate = IAX_IOSTATE_PROCESSING; 08424 #ifdef SCHED_MULTITHREADED 08425 thread->schedfunc(thread->scheddata); 08426 #endif 08427 break; 08428 } 08429 time(&thread->checktime); 08430 thread->iostate = IAX_IOSTATE_IDLE; 08431 #ifdef DEBUG_SCHED_MULTITHREAD 08432 thread->curfunc[0]='\0'; 08433 #endif 08434 08435 /* Now... remove ourselves from the active list, and return to the idle list */ 08436 AST_LIST_LOCK(&active_list); 08437 AST_LIST_REMOVE(&active_list, thread, list); 08438 AST_LIST_UNLOCK(&active_list); 08439 08440 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08441 handle_deferred_full_frames(thread); 08442 } 08443 08444 /*!\note For some reason, idle threads are exiting without being removed 08445 * from an idle list, which is causing memory corruption. Forcibly remove 08446 * it from the list, if it's there. 08447 */ 08448 AST_LIST_LOCK(&idle_list); 08449 AST_LIST_REMOVE(&idle_list, thread, list); 08450 AST_LIST_UNLOCK(&idle_list); 08451 08452 AST_LIST_LOCK(&dynamic_list); 08453 AST_LIST_REMOVE(&dynamic_list, thread, list); 08454 AST_LIST_UNLOCK(&dynamic_list); 08455 08456 /* I am exiting here on my own volition, I need to clean up my own data structures 08457 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08458 */ 08459 pthread_cleanup_pop(1); 08460 08461 return NULL; 08462 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8330 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08331 { 08332 struct iax2_thread *thread = data; 08333 ast_mutex_destroy(&thread->lock); 08334 ast_cond_destroy(&thread->cond); 08335 free(thread); 08336 ast_atomic_dec_and_test(&iaxactivethreadcount); 08337 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8617 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08618 { 08619 int force = 0; 08620 int res; 08621 if (argc < 4) 08622 return RESULT_SHOWUSAGE; 08623 if ((argc > 4)) { 08624 if (!strcasecmp(argv[4], "forced")) 08625 force = 1; 08626 else 08627 return RESULT_SHOWUSAGE; 08628 } 08629 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08630 if (res < 0) 08631 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08632 else if (res < 1) 08633 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08634 else 08635 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08636 return RESULT_SUCCESS; 08637 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8519 of file chan_iax2.c.
References iax_prov_complete_template().
08520 { 08521 if (pos != 3) 08522 return NULL; 08523 return iax_prov_complete_template(line, word, pos, state); 08524 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8526 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08527 { 08528 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08529 is found for template */ 08530 struct iax_ie_data provdata; 08531 struct iax_ie_data ied; 08532 unsigned int sig; 08533 struct sockaddr_in sin; 08534 int callno; 08535 struct create_addr_info cai; 08536 08537 memset(&cai, 0, sizeof(cai)); 08538 08539 if (option_debug) 08540 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08541 08542 if (iax_provision_build(&provdata, &sig, template, force)) { 08543 if (option_debug) 08544 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08545 return 0; 08546 } 08547 08548 if (end) { 08549 memcpy(&sin, end, sizeof(sin)); 08550 cai.sockfd = sockfd; 08551 } else if (create_addr(dest, NULL, &sin, &cai)) 08552 return -1; 08553 08554 /* Build the rest of the message */ 08555 memset(&ied, 0, sizeof(ied)); 08556 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08557 08558 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08559 if (!callno) 08560 return -1; 08561 08562 ast_mutex_lock(&iaxsl[callno]); 08563 if (iaxs[callno]) { 08564 /* Schedule autodestruct in case they don't ever give us anything back */ 08565 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08566 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08567 ast_set_flag(iaxs[callno], IAX_PROVISION); 08568 /* Got a call number now, so go ahead and send the provisioning information */ 08569 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08570 } 08571 ast_mutex_unlock(&iaxsl[callno]); 08572 08573 return 1; 08574 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2124 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.
02125 { 02126 struct iax2_peer *peer; 02127 02128 if (argc != 4) 02129 return RESULT_SHOWUSAGE; 02130 if (!strcmp(argv[3],"all")) { 02131 reload_config(); 02132 ast_cli(fd, "OK cache is flushed.\n"); 02133 } else if ((peer = find_peer(argv[3], 0))) { 02134 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02135 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02136 expire_registry(peer_ref(peer)); 02137 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02138 } else { 02139 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02140 } 02141 peer_unref(peer); 02142 } else { 02143 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02144 } 02145 02146 return RESULT_SUCCESS; 02147 }
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 1504 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), iaxs, and iaxsl.
Referenced by socket_process().
01506 { 01507 for (;;) { 01508 if (iaxs[callno] && iaxs[callno]->owner) { 01509 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01510 /* Avoid deadlock by pausing and trying again */ 01511 ast_mutex_unlock(&iaxsl[callno]); 01512 usleep(1); 01513 ast_mutex_lock(&iaxsl[callno]); 01514 } else { 01515 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01516 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01517 break; 01518 } 01519 } else 01520 break; 01521 } 01522 return 0; 01523 }
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 1438 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), f, iaxs, and iaxsl.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), and __get_from_jb().
01439 { 01440 for (;;) { 01441 if (iaxs[callno] && iaxs[callno]->owner) { 01442 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01443 /* Avoid deadlock by pausing and trying again */ 01444 ast_mutex_unlock(&iaxsl[callno]); 01445 usleep(1); 01446 ast_mutex_lock(&iaxsl[callno]); 01447 } else { 01448 ast_queue_frame(iaxs[callno]->owner, f); 01449 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01450 break; 01451 } 01452 } else 01453 break; 01454 } 01455 return 0; 01456 }
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 1471 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), iaxs, and iaxsl.
Referenced by iax2_predestroy().
01472 { 01473 for (;;) { 01474 if (iaxs[callno] && iaxs[callno]->owner) { 01475 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01476 /* Avoid deadlock by pausing and trying again */ 01477 ast_mutex_unlock(&iaxsl[callno]); 01478 usleep(1); 01479 ast_mutex_lock(&iaxsl[callno]); 01480 } else { 01481 ast_queue_hangup(iaxs[callno]->owner); 01482 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01483 break; 01484 } 01485 } else 01486 break; 01487 } 01488 return 0; 01489 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3312 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
03313 { 03314 ast_log(LOG_NOTICE, "I should never be called!\n"); 03315 return &ast_null_frame; 03316 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5804 of file chan_iax2.c.
References ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, secret, and strsep().
Referenced by set_config().
05805 { 05806 struct iax2_registry *reg; 05807 char copy[256]; 05808 char *username, *hostname, *secret; 05809 char *porta; 05810 char *stringp=NULL; 05811 05812 if (!value) 05813 return -1; 05814 ast_copy_string(copy, value, sizeof(copy)); 05815 stringp=copy; 05816 username = strsep(&stringp, "@"); 05817 hostname = strsep(&stringp, "@"); 05818 if (!hostname) { 05819 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05820 return -1; 05821 } 05822 stringp=username; 05823 username = strsep(&stringp, ":"); 05824 secret = strsep(&stringp, ":"); 05825 stringp=hostname; 05826 hostname = strsep(&stringp, ":"); 05827 porta = strsep(&stringp, ":"); 05828 05829 if (porta && !atoi(porta)) { 05830 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05831 return -1; 05832 } 05833 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05834 return -1; 05835 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05836 free(reg); 05837 return -1; 05838 } 05839 ast_copy_string(reg->username, username, sizeof(reg->username)); 05840 if (secret) 05841 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05842 reg->expire = -1; 05843 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05844 reg->addr.sin_family = AF_INET; 05845 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05846 AST_LIST_LOCK(®istrations); 05847 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05848 AST_LIST_UNLOCK(®istrations); 05849 05850 return 0; 05851 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10044 of file chan_iax2.c.
References reload_config().
10045 { 10046 return reload_config(); 10047 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8746 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_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), fmt, globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.
08747 { 08748 int callno; 08749 int res; 08750 int fmt, native; 08751 struct sockaddr_in sin; 08752 struct ast_channel *c; 08753 struct parsed_dial_string pds; 08754 struct create_addr_info cai; 08755 char *tmpstr; 08756 08757 memset(&pds, 0, sizeof(pds)); 08758 tmpstr = ast_strdupa(data); 08759 parse_dial_string(tmpstr, &pds); 08760 08761 if (ast_strlen_zero(pds.peer)) { 08762 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 08763 return NULL; 08764 } 08765 08766 memset(&cai, 0, sizeof(cai)); 08767 cai.capability = iax2_capability; 08768 08769 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08770 08771 /* Populate our address from the given */ 08772 if (create_addr(pds.peer, NULL, &sin, &cai)) { 08773 *cause = AST_CAUSE_UNREGISTERED; 08774 return NULL; 08775 } 08776 08777 if (pds.port) 08778 sin.sin_port = htons(atoi(pds.port)); 08779 08780 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08781 if (callno < 1) { 08782 ast_log(LOG_WARNING, "Unable to create call\n"); 08783 *cause = AST_CAUSE_CONGESTION; 08784 return NULL; 08785 } 08786 08787 ast_mutex_lock(&iaxsl[callno]); 08788 08789 /* If this is a trunk, update it now */ 08790 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08791 if (ast_test_flag(&cai, IAX_TRUNK)) { 08792 int new_callno; 08793 if ((new_callno = make_trunk(callno, 1)) != -1) 08794 callno = new_callno; 08795 } 08796 iaxs[callno]->maxtime = cai.maxtime; 08797 if (cai.found) 08798 ast_string_field_set(iaxs[callno], host, pds.peer); 08799 08800 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08801 08802 ast_mutex_unlock(&iaxsl[callno]); 08803 08804 if (c) { 08805 /* Choose a format we can live with */ 08806 if (c->nativeformats & format) 08807 c->nativeformats &= format; 08808 else { 08809 native = c->nativeformats; 08810 fmt = format; 08811 res = ast_translator_best_choice(&fmt, &native); 08812 if (res < 0) { 08813 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08814 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08815 ast_hangup(c); 08816 return NULL; 08817 } 08818 c->nativeformats = native; 08819 } 08820 c->readformat = ast_best_codec(c->nativeformats); 08821 c->writeformat = c->readformat; 08822 } 08823 08824 return c; 08825 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 969 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), find_callno(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00970 { 00971 int res; 00972 00973 res = ast_sched_add(con, when, callback, data); 00974 signal_condition(&sched_lock, &sched_cond); 00975 00976 return res; 00977 }
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 4134 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), f, iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04135 { 04136 /* Queue a packet for delivery on a given private structure. Use "ts" for 04137 timestamp, or calculate if ts is 0. Send immediately without retransmission 04138 or delayed, with retransmission */ 04139 struct ast_iax2_full_hdr *fh; 04140 struct ast_iax2_mini_hdr *mh; 04141 struct ast_iax2_video_hdr *vh; 04142 struct { 04143 struct iax_frame fr2; 04144 unsigned char buffer[4096]; 04145 } frb; 04146 struct iax_frame *fr; 04147 int res; 04148 int sendmini=0; 04149 unsigned int lastsent; 04150 unsigned int fts; 04151 04152 frb.fr2.afdatalen = sizeof(frb.buffer); 04153 04154 if (!pvt) { 04155 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04156 return -1; 04157 } 04158 04159 lastsent = pvt->lastsent; 04160 04161 /* Calculate actual timestamp */ 04162 fts = calc_timestamp(pvt, ts, f); 04163 04164 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04165 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04166 * increment the "predicted timestamps" for voice, if we're predecting */ 04167 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04168 return 0; 04169 04170 04171 if ((ast_test_flag(pvt, IAX_TRUNK) || 04172 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04173 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04174 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04175 (f->frametype == AST_FRAME_VOICE) 04176 /* is a voice frame */ && 04177 (f->subclass == pvt->svoiceformat) 04178 /* is the same type */ ) { 04179 /* Force immediate rather than delayed transmission */ 04180 now = 1; 04181 /* Mark that mini-style frame is appropriate */ 04182 sendmini = 1; 04183 } 04184 if ( f->frametype == AST_FRAME_VIDEO ) { 04185 /* 04186 * If the lower 15 bits of the timestamp roll over, or if 04187 * the video format changed then send a full frame. 04188 * Otherwise send a mini video frame 04189 */ 04190 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04191 ((f->subclass & ~0x1) == pvt->svideoformat) 04192 ) { 04193 now = 1; 04194 sendmini = 1; 04195 } else { 04196 now = 0; 04197 sendmini = 0; 04198 } 04199 pvt->lastvsent = fts; 04200 } 04201 /* Allocate an iax_frame */ 04202 if (now) { 04203 fr = &frb.fr2; 04204 } else 04205 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)); 04206 if (!fr) { 04207 ast_log(LOG_WARNING, "Out of memory\n"); 04208 return -1; 04209 } 04210 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04211 iax_frame_wrap(fr, f); 04212 04213 fr->ts = fts; 04214 fr->callno = pvt->callno; 04215 fr->transfer = transfer; 04216 fr->final = final; 04217 if (!sendmini) { 04218 /* We need a full frame */ 04219 if (seqno > -1) 04220 fr->oseqno = seqno; 04221 else 04222 fr->oseqno = pvt->oseqno++; 04223 fr->iseqno = pvt->iseqno; 04224 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04225 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04226 fh->ts = htonl(fr->ts); 04227 fh->oseqno = fr->oseqno; 04228 if (transfer) { 04229 fh->iseqno = 0; 04230 } else 04231 fh->iseqno = fr->iseqno; 04232 /* Keep track of the last thing we've acknowledged */ 04233 if (!transfer) 04234 pvt->aseqno = fr->iseqno; 04235 fh->type = fr->af.frametype & 0xFF; 04236 if (fr->af.frametype == AST_FRAME_VIDEO) 04237 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04238 else 04239 fh->csub = compress_subclass(fr->af.subclass); 04240 if (transfer) { 04241 fr->dcallno = pvt->transfercallno; 04242 } else 04243 fr->dcallno = pvt->peercallno; 04244 fh->dcallno = htons(fr->dcallno); 04245 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04246 fr->data = fh; 04247 fr->retries = 0; 04248 /* Retry after 2x the ping time has passed */ 04249 fr->retrytime = pvt->pingtime * 2; 04250 if (fr->retrytime < MIN_RETRY_TIME) 04251 fr->retrytime = MIN_RETRY_TIME; 04252 if (fr->retrytime > MAX_RETRY_TIME) 04253 fr->retrytime = MAX_RETRY_TIME; 04254 /* Acks' don't get retried */ 04255 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04256 fr->retries = -1; 04257 else if (f->frametype == AST_FRAME_VOICE) 04258 pvt->svoiceformat = f->subclass; 04259 else if (f->frametype == AST_FRAME_VIDEO) 04260 pvt->svideoformat = f->subclass & ~0x1; 04261 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04262 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04263 if (iaxdebug) { 04264 if (fr->transfer) 04265 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04266 else 04267 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04268 } 04269 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04270 } else 04271 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04272 } 04273 04274 if (now) { 04275 res = send_packet(fr); 04276 } else 04277 res = iax2_transmit(fr); 04278 } else { 04279 if (ast_test_flag(pvt, IAX_TRUNK)) { 04280 iax2_trunk_queue(pvt, fr); 04281 res = 0; 04282 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04283 /* Video frame have no sequence number */ 04284 fr->oseqno = -1; 04285 fr->iseqno = -1; 04286 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04287 vh->zeros = 0; 04288 vh->callno = htons(0x8000 | fr->callno); 04289 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04290 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04291 fr->data = vh; 04292 fr->retries = -1; 04293 res = send_packet(fr); 04294 } else { 04295 /* Mini-frames have no sequence number */ 04296 fr->oseqno = -1; 04297 fr->iseqno = -1; 04298 /* Mini frame will do */ 04299 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04300 mh->callno = htons(fr->callno); 04301 mh->ts = htons(fr->ts & 0xFFFF); 04302 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04303 fr->data = mh; 04304 fr->retries = -1; 04305 if (pvt->transferring == TRANSFER_MEDIAPASS) 04306 fr->transfer = 1; 04307 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04308 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04309 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04310 } else 04311 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04312 } 04313 res = send_packet(fr); 04314 } 04315 } 04316 return res; 04317 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2655 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02656 { 02657 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02658 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2650 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.
02651 { 02652 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02653 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2643 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02644 { 02645 02646 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02647 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02648 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3286 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03287 { 03288 struct ast_option_header *h; 03289 int res; 03290 03291 switch (option) { 03292 case AST_OPTION_TXGAIN: 03293 case AST_OPTION_RXGAIN: 03294 /* these two cannot be sent, because they require a result */ 03295 errno = ENOSYS; 03296 return -1; 03297 default: 03298 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03299 return -1; 03300 03301 h->flag = AST_OPTION_FLAG_REQUEST; 03302 h->option = htons(option); 03303 memcpy(h->data, data, datalen); 03304 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03305 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03306 datalen + sizeof(*h), -1); 03307 free(h); 03308 return res; 03309 } 03310 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2328 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.
02329 { 02330 struct iax2_dpcache *dp; 02331 char tmp[1024], *pc; 02332 int s; 02333 int x,y; 02334 struct timeval tv; 02335 gettimeofday(&tv, NULL); 02336 ast_mutex_lock(&dpcache_lock); 02337 dp = dpcache; 02338 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02339 while(dp) { 02340 s = dp->expiry.tv_sec - tv.tv_sec; 02341 tmp[0] = '\0'; 02342 if (dp->flags & CACHE_FLAG_EXISTS) 02343 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02344 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02345 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02346 if (dp->flags & CACHE_FLAG_CANEXIST) 02347 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02348 if (dp->flags & CACHE_FLAG_PENDING) 02349 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02350 if (dp->flags & CACHE_FLAG_TIMEOUT) 02351 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02352 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02353 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02354 if (dp->flags & CACHE_FLAG_MATCHMORE) 02355 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02356 if (dp->flags & CACHE_FLAG_UNKNOWN) 02357 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02358 /* Trim trailing pipe */ 02359 if (!ast_strlen_zero(tmp)) 02360 tmp[strlen(tmp) - 1] = '\0'; 02361 else 02362 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02363 y=0; 02364 pc = strchr(dp->peercontext, '@'); 02365 if (!pc) 02366 pc = dp->peercontext; 02367 else 02368 pc++; 02369 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02370 if (dp->waiters[x] > -1) 02371 y++; 02372 if (s > 0) 02373 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02374 else 02375 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02376 dp = dp->next; 02377 } 02378 ast_mutex_unlock(&dpcache_lock); 02379 return RESULT_SUCCESS; 02380 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4661 of file chan_iax2.c.
References 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.
04662 { 04663 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04664 #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" 04665 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04666 int x; 04667 int numchans = 0; 04668 04669 if (argc != 3) 04670 return RESULT_SHOWUSAGE; 04671 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04672 for (x=0;x<IAX_MAX_CALLS;x++) { 04673 ast_mutex_lock(&iaxsl[x]); 04674 if (iaxs[x]) { 04675 int lag, jitter, localdelay; 04676 jb_info jbinfo; 04677 04678 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04679 jb_getinfo(iaxs[x]->jb, &jbinfo); 04680 jitter = jbinfo.jitter; 04681 localdelay = jbinfo.current - jbinfo.min; 04682 } else { 04683 jitter = -1; 04684 localdelay = 0; 04685 } 04686 lag = iaxs[x]->remote_rr.delay; 04687 ast_cli(fd, FORMAT, 04688 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04689 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04690 S_OR(iaxs[x]->username, "(None)"), 04691 iaxs[x]->callno, iaxs[x]->peercallno, 04692 iaxs[x]->oseqno, iaxs[x]->iseqno, 04693 lag, 04694 jitter, 04695 localdelay, 04696 ast_getformatname(iaxs[x]->voiceformat) ); 04697 numchans++; 04698 } 04699 ast_mutex_unlock(&iaxsl[x]); 04700 } 04701 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04702 return RESULT_SUCCESS; 04703 #undef FORMAT 04704 #undef FORMAT2 04705 #undef FORMATB 04706 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4572 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.
04573 { 04574 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04575 #if !defined(__FreeBSD__) 04576 #define FORMAT "%-15.15s %-15d %-15d\n" 04577 #else /* __FreeBSD__ */ 04578 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04579 #endif /* __FreeBSD__ */ 04580 struct iax_firmware *cur; 04581 if ((argc != 3) && (argc != 4)) 04582 return RESULT_SHOWUSAGE; 04583 ast_mutex_lock(&waresl.lock); 04584 04585 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04586 for (cur = waresl.wares;cur;cur = cur->next) { 04587 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04588 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04589 (int)ntohl(cur->fwh->datalen)); 04590 } 04591 ast_mutex_unlock(&waresl.lock); 04592 return RESULT_SUCCESS; 04593 #undef FORMAT 04594 #undef FORMAT2 04595 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4784 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04785 { 04786 int numchans = 0; 04787 if (argc != 3) 04788 return RESULT_SHOWUSAGE; 04789 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04790 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04791 numchans = ast_cli_netstats(NULL, fd, 1); 04792 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04793 return RESULT_SUCCESS; 04794 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2218 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.
02219 { 02220 char status[30]; 02221 char cbuf[256]; 02222 struct iax2_peer *peer; 02223 char codec_buf[512]; 02224 int x = 0, codec = 0, load_realtime = 0; 02225 02226 if (argc < 4) 02227 return RESULT_SHOWUSAGE; 02228 02229 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02230 02231 peer = find_peer(argv[3], load_realtime); 02232 if (peer) { 02233 ast_cli(fd,"\n\n"); 02234 ast_cli(fd, " * Name : %s\n", peer->name); 02235 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02236 ast_cli(fd, " Context : %s\n", peer->context); 02237 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02238 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02239 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02240 ast_cli(fd, " Expire : %d\n", peer->expire); 02241 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02242 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)); 02243 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02244 ast_cli(fd, " Username : %s\n", peer->username); 02245 ast_cli(fd, " Codecs : "); 02246 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02247 ast_cli(fd, "%s\n", codec_buf); 02248 02249 ast_cli(fd, " Codec Order : ("); 02250 for(x = 0; x < 32 ; x++) { 02251 codec = ast_codec_pref_index(&peer->prefs,x); 02252 if(!codec) 02253 break; 02254 ast_cli(fd, "%s", ast_getformatname(codec)); 02255 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02256 ast_cli(fd, "|"); 02257 } 02258 02259 if (!x) 02260 ast_cli(fd, "none"); 02261 ast_cli(fd, ")\n"); 02262 02263 ast_cli(fd, " Status : "); 02264 peer_status(peer, status, sizeof(status)); 02265 ast_cli(fd, "%s\n",status); 02266 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02267 ast_cli(fd,"\n"); 02268 peer_unref(peer); 02269 } else { 02270 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02271 ast_cli(fd,"\n"); 02272 } 02273 02274 return RESULT_SUCCESS; 02275 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4561 of file chan_iax2.c.
References __iax2_show_peers().
04562 { 04563 return __iax2_show_peers(0, fd, NULL, argc, argv); 04564 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4633 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.
04634 { 04635 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04636 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04637 struct iax2_registry *reg = NULL; 04638 04639 char host[80]; 04640 char perceived[80]; 04641 if (argc != 3) 04642 return RESULT_SHOWUSAGE; 04643 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04644 AST_LIST_LOCK(®istrations); 04645 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04646 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04647 if (reg->us.sin_addr.s_addr) 04648 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04649 else 04650 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04651 ast_cli(fd, FORMAT, host, 04652 (reg->dnsmgr) ? "Y" : "N", 04653 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04654 } 04655 AST_LIST_UNLOCK(®istrations); 04656 return RESULT_SUCCESS; 04657 #undef FORMAT 04658 #undef FORMAT2 04659 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2302 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.
02303 { 02304 struct iax_frame *cur; 02305 int cnt = 0, dead=0, final=0; 02306 02307 if (argc != 3) 02308 return RESULT_SHOWUSAGE; 02309 02310 AST_LIST_LOCK(&iaxq.queue); 02311 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02312 if (cur->retries < 0) 02313 dead++; 02314 if (cur->final) 02315 final++; 02316 cnt++; 02317 } 02318 AST_LIST_UNLOCK(&iaxq.queue); 02319 02320 ast_cli(fd, " IAX Statistics\n"); 02321 ast_cli(fd, "---------------------\n"); 02322 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02323 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02324 02325 return RESULT_SUCCESS; 02326 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4502 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.
04503 { 04504 struct iax2_thread *thread = NULL; 04505 time_t t; 04506 int threadcount = 0, dynamiccount = 0; 04507 char type; 04508 04509 if (argc != 3) 04510 return RESULT_SHOWUSAGE; 04511 04512 ast_cli(fd, "IAX2 Thread Information\n"); 04513 time(&t); 04514 ast_cli(fd, "Idle Threads:\n"); 04515 AST_LIST_LOCK(&idle_list); 04516 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04517 #ifdef DEBUG_SCHED_MULTITHREAD 04518 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04519 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04520 #else 04521 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04522 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04523 #endif 04524 threadcount++; 04525 } 04526 AST_LIST_UNLOCK(&idle_list); 04527 ast_cli(fd, "Active Threads:\n"); 04528 AST_LIST_LOCK(&active_list); 04529 AST_LIST_TRAVERSE(&active_list, thread, list) { 04530 if (thread->type == IAX_TYPE_DYNAMIC) 04531 type = 'D'; 04532 else 04533 type = 'P'; 04534 #ifdef DEBUG_SCHED_MULTITHREAD 04535 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04536 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04537 #else 04538 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04539 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04540 #endif 04541 threadcount++; 04542 } 04543 AST_LIST_UNLOCK(&active_list); 04544 ast_cli(fd, "Dynamic Threads:\n"); 04545 AST_LIST_LOCK(&dynamic_list); 04546 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04547 #ifdef DEBUG_SCHED_MULTITHREAD 04548 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04549 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04550 #else 04551 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04552 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04553 #endif 04554 dynamiccount++; 04555 } 04556 AST_LIST_UNLOCK(&dynamic_list); 04557 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04558 return RESULT_SUCCESS; 04559 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4319 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.
04320 { 04321 regex_t regexbuf; 04322 int havepattern = 0; 04323 04324 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04325 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04326 04327 struct iax2_user *user = NULL; 04328 char auth[90]; 04329 char *pstr = ""; 04330 struct ao2_iterator i; 04331 04332 switch (argc) { 04333 case 5: 04334 if (!strcasecmp(argv[3], "like")) { 04335 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04336 return RESULT_SHOWUSAGE; 04337 havepattern = 1; 04338 } else 04339 return RESULT_SHOWUSAGE; 04340 case 3: 04341 break; 04342 default: 04343 return RESULT_SHOWUSAGE; 04344 } 04345 04346 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04347 i = ao2_iterator_init(users, 0); 04348 for (user = ao2_iterator_next(&i); user; 04349 user_unref(user), user = ao2_iterator_next(&i)) { 04350 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04351 continue; 04352 04353 if (!ast_strlen_zero(user->secret)) { 04354 ast_copy_string(auth,user->secret,sizeof(auth)); 04355 } else if (!ast_strlen_zero(user->inkeys)) { 04356 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04357 } else 04358 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04359 04360 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04361 pstr = "REQ Only"; 04362 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04363 pstr = "Disabled"; 04364 else 04365 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04366 04367 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04368 user->contexts ? user->contexts->context : context, 04369 user->ha ? "Yes" : "No", pstr); 04370 } 04371 04372 if (havepattern) 04373 regfree(®exbuf); 04374 04375 return RESULT_SUCCESS; 04376 #undef FORMAT 04377 #undef FORMAT2 04378 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3318 of file chan_iax2.c.
References AST_FRAME_IAX, ast_random(), IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
03319 { 03320 int res; 03321 struct iax_ie_data ied0; 03322 struct iax_ie_data ied1; 03323 unsigned int transferid = (unsigned int)ast_random(); 03324 memset(&ied0, 0, sizeof(ied0)); 03325 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03326 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03327 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03328 03329 memset(&ied1, 0, sizeof(ied1)); 03330 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03331 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03332 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03333 03334 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03335 if (res) 03336 return -1; 03337 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03338 if (res) 03339 return -1; 03340 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03341 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03342 return 0; 03343 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2149 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02150 { 02151 if (argc != 4) 02152 return RESULT_SHOWUSAGE; 02153 02154 test_losspct = atoi(argv[3]); 02155 02156 return RESULT_SUCCESS; 02157 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3553 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03554 { 03555 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03556 struct iax_ie_data ied; 03557 char tmp[256], *context; 03558 ast_copy_string(tmp, dest, sizeof(tmp)); 03559 context = strchr(tmp, '@'); 03560 if (context) { 03561 *context = '\0'; 03562 context++; 03563 } 03564 memset(&ied, 0, sizeof(ied)); 03565 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03566 if (context) 03567 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03568 if (option_debug) 03569 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03570 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03571 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2614 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().
02615 { 02616 /* Lock the queue and place this packet at the end */ 02617 /* By setting this to 0, the network thread will send it for us, and 02618 queue retransmission if necessary */ 02619 fr->sentyet = 0; 02620 AST_LIST_LOCK(&iaxq.queue); 02621 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02622 iaxq.count++; 02623 AST_LIST_UNLOCK(&iaxq.queue); 02624 /* Wake up the network and scheduler thread */ 02625 if (netthreadid != AST_PTHREADT_NULL) 02626 pthread_kill(netthreadid, SIGURG); 02627 signal_condition(&sched_lock, &sched_cond); 02628 return 0; 02629 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6377 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06378 { 06379 /* Drop when trunk is about 5 seconds idle */ 06380 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06381 return 1; 06382 return 0; 06383 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3908 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
03909 { 03910 struct ast_frame *f; 03911 struct iax2_trunk_peer *tpeer; 03912 void *tmp, *ptr; 03913 struct ast_iax2_meta_trunk_entry *met; 03914 struct ast_iax2_meta_trunk_mini *mtm; 03915 03916 f = &fr->af; 03917 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03918 if (tpeer) { 03919 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03920 /* Need to reallocate space */ 03921 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03922 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03923 ast_mutex_unlock(&tpeer->lock); 03924 return -1; 03925 } 03926 03927 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03928 tpeer->trunkdata = tmp; 03929 if (option_debug) 03930 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); 03931 } else { 03932 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)); 03933 ast_mutex_unlock(&tpeer->lock); 03934 return -1; 03935 } 03936 } 03937 03938 /* Append to meta frame */ 03939 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03940 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03941 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03942 mtm->len = htons(f->datalen); 03943 mtm->mini.callno = htons(pvt->callno); 03944 mtm->mini.ts = htons(0xffff & fr->ts); 03945 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03946 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03947 } else { 03948 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03949 /* Store call number and length in meta header */ 03950 met->callno = htons(pvt->callno); 03951 met->len = htons(f->datalen); 03952 /* Advance pointers/decrease length past trunk entry header */ 03953 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03954 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03955 } 03956 /* Copy actual trunk data */ 03957 memcpy(ptr, f->data, f->datalen); 03958 tpeer->trunkdatalen += f->datalen; 03959 03960 tpeer->calls++; 03961 ast_mutex_unlock(&tpeer->lock); 03962 } 03963 return 0; 03964 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6294 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06295 { 06296 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06297 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4851 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, errno, error(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04852 { 04853 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04854 int res = -1; 04855 ast_mutex_lock(&iaxsl[callno]); 04856 if (iaxs[callno]) { 04857 /* If there's an outstanding error, return failure now */ 04858 if (!iaxs[callno]->error) { 04859 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04860 res = 0; 04861 /* Don't waste bandwidth sending null frames */ 04862 else if (f->frametype == AST_FRAME_NULL) 04863 res = 0; 04864 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04865 res = 0; 04866 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04867 res = 0; 04868 else 04869 /* Simple, just queue for transmission */ 04870 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04871 } else { 04872 if (option_debug) 04873 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04874 } 04875 } 04876 /* If it's already gone, just return */ 04877 ast_mutex_unlock(&iaxsl[callno]); 04878 return res; 04879 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1679 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().
01680 { 01681 int res = 0; 01682 struct iax_firmware *cur; 01683 if (!ast_strlen_zero(dev)) { 01684 ast_mutex_lock(&waresl.lock); 01685 cur = waresl.wares; 01686 while(cur) { 01687 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01688 res = ntohs(cur->fwh->version); 01689 break; 01690 } 01691 cur = cur->next; 01692 } 01693 ast_mutex_unlock(&waresl.lock); 01694 } 01695 return res; 01696 }
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 1698 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().
01699 { 01700 int res = -1; 01701 unsigned int bs = desc & 0xff; 01702 unsigned int start = (desc >> 8) & 0xffffff; 01703 unsigned int bytes; 01704 struct iax_firmware *cur; 01705 if (!ast_strlen_zero((char *)dev) && bs) { 01706 start *= bs; 01707 ast_mutex_lock(&waresl.lock); 01708 cur = waresl.wares; 01709 while(cur) { 01710 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01711 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01712 if (start < ntohl(cur->fwh->datalen)) { 01713 bytes = ntohl(cur->fwh->datalen) - start; 01714 if (bytes > bs) 01715 bytes = bs; 01716 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01717 } else { 01718 bytes = 0; 01719 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01720 } 01721 if (bytes == bs) 01722 res = 0; 01723 else 01724 res = 1; 01725 break; 01726 } 01727 cur = cur->next; 01728 } 01729 ast_mutex_unlock(&waresl.lock); 01730 } 01731 return res; 01732 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6565 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06566 { 06567 struct iax_dual *d; 06568 struct ast_channel *chan1m, *chan2m; 06569 pthread_t th; 06570 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06571 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06572 if (chan2m && chan1m) { 06573 /* Make formats okay */ 06574 chan1m->readformat = chan1->readformat; 06575 chan1m->writeformat = chan1->writeformat; 06576 ast_channel_masquerade(chan1m, chan1); 06577 /* Setup the extensions and such */ 06578 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06579 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06580 chan1m->priority = chan1->priority; 06581 06582 /* We make a clone of the peer channel too, so we can play 06583 back the announcement */ 06584 /* Make formats okay */ 06585 chan2m->readformat = chan2->readformat; 06586 chan2m->writeformat = chan2->writeformat; 06587 ast_channel_masquerade(chan2m, chan2); 06588 /* Setup the extensions and such */ 06589 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06590 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06591 chan2m->priority = chan2->priority; 06592 if (ast_do_masquerade(chan2m)) { 06593 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06594 ast_hangup(chan2m); 06595 return -1; 06596 } 06597 } else { 06598 if (chan1m) 06599 ast_hangup(chan1m); 06600 if (chan2m) 06601 ast_hangup(chan2m); 06602 return -1; 06603 } 06604 if ((d = ast_calloc(1, sizeof(*d)))) { 06605 pthread_attr_t attr; 06606 06607 pthread_attr_init(&attr); 06608 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06609 06610 d->chan1 = chan1m; 06611 d->chan2 = chan2m; 06612 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06613 pthread_attr_destroy(&attr); 06614 return 0; 06615 } 06616 pthread_attr_destroy(&attr); 06617 free(d); 06618 } 06619 return -1; 06620 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6545 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().
06546 { 06547 struct ast_channel *chan1, *chan2; 06548 struct iax_dual *d; 06549 struct ast_frame *f; 06550 int ext; 06551 int res; 06552 d = stuff; 06553 chan1 = d->chan1; 06554 chan2 = d->chan2; 06555 free(d); 06556 f = ast_read(chan1); 06557 if (f) 06558 ast_frfree(f); 06559 res = ast_park_call(chan1, chan2, 0, &ext); 06560 ast_hangup(chan2); 06561 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06562 return NULL; 06563 }
Definition at line 1222 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().
01223 { 01224 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01225 if (new) { 01226 size_t afdatalen = new->afdatalen; 01227 memcpy(new, fr, sizeof(*new)); 01228 iax_frame_wrap(new, &fr->af); 01229 new->afdatalen = afdatalen; 01230 new->data = NULL; 01231 new->datalen = 0; 01232 new->direction = DIRECTION_INGRESS; 01233 new->retrans = -1; 01234 } 01235 return new; 01236 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 877 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.
Referenced by iax2_process_thread().
00878 { 00879 if (thread->type == IAX_TYPE_DYNAMIC) { 00880 AST_LIST_LOCK(&dynamic_list); 00881 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00882 AST_LIST_UNLOCK(&dynamic_list); 00883 } else { 00884 AST_LIST_LOCK(&idle_list); 00885 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00886 AST_LIST_UNLOCK(&idle_list); 00887 } 00888 00889 return; 00890 }
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 10859 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), 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_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, netsock, option_verbose, outsock, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
10860 { 10861 char *config = "iax.conf"; 10862 int res = 0; 10863 int x; 10864 struct iax2_registry *reg = NULL; 10865 10866 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 10867 if (!peers) 10868 return AST_MODULE_LOAD_FAILURE; 10869 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 10870 if (!users) { 10871 ao2_ref(peers, -1); 10872 return AST_MODULE_LOAD_FAILURE; 10873 } 10874 10875 ast_custom_function_register(&iaxpeer_function); 10876 10877 iax_set_output(iax_debug_output); 10878 iax_set_error(iax_error_output); 10879 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10880 10881 #ifdef HAVE_ZAPTEL 10882 #ifdef ZT_TIMERACK 10883 timingfd = open("/dev/zap/timer", O_RDWR); 10884 if (timingfd < 0) 10885 #endif 10886 timingfd = open("/dev/zap/pseudo", O_RDWR); 10887 if (timingfd < 0) 10888 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10889 #endif 10890 10891 memset(iaxs, 0, sizeof(iaxs)); 10892 10893 for (x=0;x<IAX_MAX_CALLS;x++) 10894 ast_mutex_init(&iaxsl[x]); 10895 10896 ast_cond_init(&sched_cond, NULL); 10897 10898 io = io_context_create(); 10899 sched = sched_context_create(); 10900 10901 if (!io || !sched) { 10902 ast_log(LOG_ERROR, "Out of memory\n"); 10903 return -1; 10904 } 10905 10906 netsock = ast_netsock_list_alloc(); 10907 if (!netsock) { 10908 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10909 return -1; 10910 } 10911 ast_netsock_init(netsock); 10912 10913 outsock = ast_netsock_list_alloc(); 10914 if (!outsock) { 10915 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10916 return -1; 10917 } 10918 ast_netsock_init(outsock); 10919 10920 ast_mutex_init(&waresl.lock); 10921 10922 AST_LIST_HEAD_INIT(&iaxq.queue); 10923 10924 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10925 10926 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10927 10928 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10929 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10930 10931 if(set_config(config, 0) == -1) 10932 return AST_MODULE_LOAD_DECLINE; 10933 10934 if (ast_channel_register(&iax2_tech)) { 10935 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10936 __unload_module(); 10937 return -1; 10938 } 10939 10940 if (ast_register_switch(&iax2_switch)) 10941 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10942 10943 res = start_network_thread(); 10944 if (!res) { 10945 if (option_verbose > 1) 10946 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10947 } else { 10948 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10949 ast_netsock_release(netsock); 10950 ast_netsock_release(outsock); 10951 } 10952 10953 AST_LIST_LOCK(®istrations); 10954 AST_LIST_TRAVERSE(®istrations, reg, entry) 10955 iax2_do_register(reg); 10956 AST_LIST_UNLOCK(®istrations); 10957 10958 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 10959 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 10960 10961 reload_firmware(0); 10962 iax_provision_reload(); 10963 return res; 10964 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3345 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03346 { 03347 ast_mutex_lock(&iaxsl[callno0]); 03348 while (ast_mutex_trylock(&iaxsl[callno1])) { 03349 ast_mutex_unlock(&iaxsl[callno0]); 03350 usleep(10); 03351 ast_mutex_lock(&iaxsl[callno0]); 03352 } 03353 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1290 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, chan_iax2_pvt::callno, iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), and TRUNK_CALL_START.
Referenced by iax2_request(), and socket_process().
01291 { 01292 int x; 01293 int res= 0; 01294 struct timeval now; 01295 if (iaxs[callno]->oseqno) { 01296 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01297 return -1; 01298 } 01299 if (callno & TRUNK_CALL_START) { 01300 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01301 return -1; 01302 } 01303 gettimeofday(&now, NULL); 01304 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01305 ast_mutex_lock(&iaxsl[x]); 01306 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01307 iaxs[x] = iaxs[callno]; 01308 iaxs[x]->callno = x; 01309 iaxs[callno] = NULL; 01310 /* Update the two timers that should have been started */ 01311 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01312 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01313 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01314 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01315 if (locked) 01316 ast_mutex_unlock(&iaxsl[callno]); 01317 res = x; 01318 if (!locked) 01319 ast_mutex_unlock(&iaxsl[x]); 01320 break; 01321 } 01322 ast_mutex_unlock(&iaxsl[x]); 01323 } 01324 if (x >= IAX_MAX_CALLS - 1) { 01325 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01326 return -1; 01327 } 01328 if (option_debug) 01329 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01330 /* We move this call from a non-trunked to a trunked call */ 01331 update_max_trunk(); 01332 update_max_nontrunk(); 01333 return res; 01334 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4565 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04566 { 04567 ast_cli_netstats(s, -1, 0); 04568 astman_append(s, "\r\n"); 04569 return RESULT_SUCCESS; 04570 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4598 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04599 { 04600 char *a[] = { "iax2", "show", "users" }; 04601 int ret; 04602 const char *id = astman_get_header(m,"ActionID"); 04603 04604 if (!ast_strlen_zero(id)) 04605 astman_append(s, "ActionID: %s\r\n",id); 04606 ret = __iax2_show_peers(1, -1, s, 3, a ); 04607 astman_append(s, "\r\n\r\n" ); 04608 return ret; 04609 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur | |||
) | [static] |
Definition at line 1242 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by ao2_callback(), ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01243 { 01244 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01245 (cur->addr.sin_port == sin->sin_port)) { 01246 /* This is the main host */ 01247 if ((cur->peercallno == callno) || 01248 ((dcallno == cur->callno) && !cur->peercallno)) { 01249 /* That's us. Be sure we keep track of the peer call number */ 01250 return 1; 01251 } 01252 } 01253 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01254 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01255 /* We're transferring */ 01256 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01257 return 1; 01258 } 01259 return 0; 01260 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3972 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03973 { 03974 #if 0 03975 /* Debug with "fake encryption" */ 03976 int x; 03977 if (len % 16) 03978 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03979 for (x=0;x<len;x++) 03980 dst[x] = src[x] ^ 0xff; 03981 #else 03982 unsigned char lastblock[16] = { 0 }; 03983 int x; 03984 while(len > 0) { 03985 aes_decrypt(src, dst, dcx); 03986 for (x=0;x<16;x++) 03987 dst[x] ^= lastblock[x]; 03988 memcpy(lastblock, src, sizeof(lastblock)); 03989 dst += 16; 03990 src += 16; 03991 len -= 16; 03992 } 03993 #endif 03994 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3996 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03997 { 03998 #if 0 03999 /* Debug with "fake encryption" */ 04000 int x; 04001 if (len % 16) 04002 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04003 for (x=0;x<len;x++) 04004 dst[x] = src[x] ^ 0xff; 04005 #else 04006 unsigned char curblock[16] = { 0 }; 04007 int x; 04008 while(len > 0) { 04009 for (x=0;x<16;x++) 04010 curblock[x] ^= src[x]; 04011 aes_encrypt(curblock, dst, ecx); 04012 memcpy(curblock, dst, sizeof(curblock)); 04013 dst += 16; 04014 src += 16; 04015 len -= 16; 04016 } 04017 #endif 04018 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5176 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05177 { 05178 /* Select exactly one common encryption if there are any */ 05179 p->encmethods &= enc; 05180 if (p->encmethods) { 05181 if (p->encmethods & IAX_ENCRYPT_AES128) 05182 p->encmethods = IAX_ENCRYPT_AES128; 05183 else 05184 p->encmethods = 0; 05185 } 05186 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8855 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, option_debug, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
08856 { 08857 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08858 from the network, and queue them for delivery to the channels */ 08859 int res, count, wakeup; 08860 struct iax_frame *f; 08861 08862 if (timingfd > -1) 08863 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08864 08865 for(;;) { 08866 pthread_testcancel(); 08867 08868 /* Go through the queue, sending messages which have not yet been 08869 sent, and scheduling retransmissions if appropriate */ 08870 AST_LIST_LOCK(&iaxq.queue); 08871 count = 0; 08872 wakeup = -1; 08873 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08874 if (f->sentyet) 08875 continue; 08876 08877 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08878 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08879 wakeup = 1; 08880 continue; 08881 } 08882 08883 f->sentyet++; 08884 08885 if (iaxs[f->callno]) { 08886 send_packet(f); 08887 count++; 08888 } 08889 08890 ast_mutex_unlock(&iaxsl[f->callno]); 08891 08892 if (f->retries < 0) { 08893 /* This is not supposed to be retransmitted */ 08894 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 08895 iaxq.count--; 08896 /* Free the iax frame */ 08897 iax_frame_free(f); 08898 } else { 08899 /* We need reliable delivery. Schedule a retransmission */ 08900 f->retries++; 08901 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 08902 } 08903 } 08904 AST_LIST_TRAVERSE_SAFE_END 08905 AST_LIST_UNLOCK(&iaxq.queue); 08906 08907 pthread_testcancel(); 08908 08909 if (option_debug && count >= 20) 08910 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08911 08912 /* Now do the IO, and run scheduled tasks */ 08913 res = ast_io_wait(io, wakeup); 08914 if (res >= 0) { 08915 if (option_debug && res >= 20) 08916 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08917 } 08918 } 08919 return NULL; 08920 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1184 of file chan_iax2.c.
References ast_calloc, ast_string_field_init, ast_string_field_set, exten, free, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, and jb_conf::resync_threshold.
Referenced by find_callno().
01185 { 01186 struct chan_iax2_pvt *tmp; 01187 jb_conf jbconf; 01188 01189 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01190 return NULL; 01191 01192 if (ast_string_field_init(tmp, 32)) { 01193 free(tmp); 01194 tmp = NULL; 01195 return NULL; 01196 } 01197 01198 tmp->prefs = prefs; 01199 tmp->callno = 0; 01200 tmp->peercallno = 0; 01201 tmp->transfercallno = 0; 01202 tmp->bridgecallno = 0; 01203 tmp->pingid = -1; 01204 tmp->lagid = -1; 01205 tmp->autoid = -1; 01206 tmp->authid = -1; 01207 tmp->initid = -1; 01208 01209 ast_string_field_set(tmp,exten, "s"); 01210 ast_string_field_set(tmp,host, host); 01211 01212 tmp->jb = jb_new(); 01213 tmp->jbid = -1; 01214 jbconf.max_jitterbuf = maxjitterbuffer; 01215 jbconf.resync_threshold = resyncthreshold; 01216 jbconf.max_contig_interp = maxjitterinterps; 01217 jb_setconf(tmp->jb,&jbconf); 01218 01219 return tmp; 01220 }
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 3065 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().
03066 { 03067 if (ast_strlen_zero(data)) 03068 return; 03069 03070 pds->peer = strsep(&data, "/"); 03071 pds->exten = strsep(&data, "/"); 03072 pds->options = data; 03073 03074 if (pds->exten) { 03075 data = pds->exten; 03076 pds->exten = strsep(&data, "@"); 03077 pds->context = data; 03078 } 03079 03080 if (strchr(pds->peer, '@')) { 03081 data = pds->peer; 03082 pds->username = strsep(&data, "@"); 03083 pds->peer = data; 03084 } 03085 03086 if (pds->username) { 03087 data = pds->username; 03088 pds->username = strsep(&data, ":"); 03089 pds->password = data; 03090 } 03091 03092 data = pds->peer; 03093 pds->peer = strsep(&data, ":"); 03094 pds->port = data; 03095 03096 /* check for a key name wrapped in [] in the secret position, if found, 03097 move it to the key field instead 03098 */ 03099 if (pds->password && (pds->password[0] == '[')) { 03100 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03101 pds->password = NULL; 03102 } 03103 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1083 of file chan_iax2.c.
Referenced by load_module().
01084 { 01085 struct iax2_peer *peer = obj, *peer2 = arg; 01086 01087 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01088 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9553 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09554 { 09555 struct iax2_peer *peer = obj; 09556 09557 ast_set_flag(peer, IAX_DELME); 09558 09559 return 0; 09560 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9078 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().
09079 { 09080 struct iax2_peer *peer = obj; 09081 09082 ast_free_ha(peer->ha); 09083 09084 if (peer->callno > 0) { 09085 ast_mutex_lock(&iaxsl[peer->callno]); 09086 iax2_destroy(peer->callno); 09087 ast_mutex_unlock(&iaxsl[peer->callno]); 09088 } 09089 09090 register_peer_exten(peer, 0); 09091 09092 if (peer->dnsmgr) 09093 ast_dnsmgr_release(peer->dnsmgr); 09094 09095 ast_string_field_free_memory(peer); 09096 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1073 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01074 { 01075 const struct iax2_peer *peer = obj; 01076 01077 return ast_str_hash(peer->name); 01078 }
Definition at line 1130 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), reg_source_db(), socket_process(), and update_registry().
01131 { 01132 ao2_ref(peer, +1); 01133 return peer; 01134 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10848 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
10849 { 10850 struct iax2_peer *peer = obj; 10851 10852 if (peer->sockfd < 0) 10853 peer->sockfd = defaultsockfd; 10854 10855 return 0; 10856 }
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 9005 of file chan_iax2.c.
References ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, netsock, option_debug, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
09006 { 09007 struct sockaddr_in sin; 09008 int nonlocal = 1; 09009 int port = IAX_DEFAULT_PORTNO; 09010 int sockfd = defaultsockfd; 09011 char *tmp; 09012 char *addr; 09013 char *portstr; 09014 09015 if (!(tmp = ast_strdupa(srcaddr))) 09016 return -1; 09017 09018 addr = strsep(&tmp, ":"); 09019 portstr = tmp; 09020 09021 if (portstr) { 09022 port = atoi(portstr); 09023 if (port < 1) 09024 port = IAX_DEFAULT_PORTNO; 09025 } 09026 09027 if (!ast_get_ip(&sin, addr)) { 09028 struct ast_netsock *sock; 09029 int res; 09030 09031 sin.sin_port = 0; 09032 sin.sin_family = AF_INET; 09033 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09034 if (res == 0) { 09035 /* ip address valid. */ 09036 sin.sin_port = htons(port); 09037 if (!(sock = ast_netsock_find(netsock, &sin))) 09038 sock = ast_netsock_find(outsock, &sin); 09039 if (sock) { 09040 sockfd = ast_netsock_sockfd(sock); 09041 nonlocal = 0; 09042 } else { 09043 unsigned int orig_saddr = sin.sin_addr.s_addr; 09044 /* INADDR_ANY matches anyway! */ 09045 sin.sin_addr.s_addr = INADDR_ANY; 09046 if (ast_netsock_find(netsock, &sin)) { 09047 sin.sin_addr.s_addr = orig_saddr; 09048 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09049 if (sock) { 09050 sockfd = ast_netsock_sockfd(sock); 09051 ast_netsock_unref(sock); 09052 nonlocal = 0; 09053 } else { 09054 nonlocal = 2; 09055 } 09056 } 09057 } 09058 } 09059 } 09060 09061 peer->sockfd = sockfd; 09062 09063 if (nonlocal == 1) { 09064 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09065 srcaddr, peer->name); 09066 return -1; 09067 } else if (nonlocal == 2) { 09068 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09069 srcaddr, peer->name); 09070 return -1; 09071 } else { 09072 if (option_debug) 09073 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09074 return 0; 09075 } 09076 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2195 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().
02196 { 02197 int res = 0; 02198 if (peer->maxms) { 02199 if (peer->lastms < 0) { 02200 ast_copy_string(status, "UNREACHABLE", statuslen); 02201 } else if (peer->lastms > peer->maxms) { 02202 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02203 res = 1; 02204 } else if (peer->lastms) { 02205 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02206 res = 1; 02207 } else { 02208 ast_copy_string(status, "UNKNOWN", statuslen); 02209 } 02210 } else { 02211 ast_copy_string(status, "Unmonitored", statuslen); 02212 res = -1; 02213 } 02214 return res; 02215 }
Definition at line 1136 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01137 { 01138 ao2_ref(peer, -1); 01139 return NULL; 01140 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10012 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10013 { 10014 struct ao2_iterator i; 10015 struct iax2_peer *peer; 10016 10017 i = ao2_iterator_init(peers, 0); 10018 while ((peer = ao2_iterator_next(&i))) { 10019 iax2_poke_peer(peer, 0); 10020 peer_unref(peer); 10021 } 10022 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9611 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09612 { 09613 struct iax2_peer *peer; 09614 struct ao2_iterator i; 09615 09616 i = ao2_iterator_init(peers, 0); 09617 while ((peer = ao2_iterator_next(&i))) { 09618 if (ast_test_flag(peer, IAX_DELME)) 09619 unlink_peer(peer); 09620 peer_unref(peer); 09621 } 09622 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9597 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().
09598 { 09599 struct iax2_user *user; 09600 struct ao2_iterator i; 09601 09602 i = ao2_iterator_init(users, 0); 09603 while ((user = ao2_iterator_next(&i))) { 09604 if (ast_test_flag(user, IAX_DELME)) 09605 ao2_unlink(users, user); 09606 user_unref(user); 09607 } 09608 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5158 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
05159 { 05160 struct ast_iax2_full_hdr fh; 05161 fh.scallno = htons(src | IAX_FLAG_FULL); 05162 fh.dcallno = htons(dst); 05163 fh.ts = 0; 05164 fh.oseqno = 0; 05165 fh.iseqno = 0; 05166 fh.type = AST_FRAME_IAX; 05167 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05168 if (iaxdebug) 05169 iax_showframe(NULL, &fh, 0, sin, 0); 05170 if (option_debug) 05171 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05172 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05173 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05174 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2676 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02677 { 02678 struct ast_variable *var = NULL; 02679 struct ast_variable *tmp; 02680 struct iax2_peer *peer=NULL; 02681 time_t regseconds = 0, nowtime; 02682 int dynamic=0; 02683 02684 if (peername) { 02685 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02686 if (!var && sin) 02687 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02688 } else if (sin) { 02689 char porta[25]; 02690 sprintf(porta, "%d", ntohs(sin->sin_port)); 02691 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02692 if (var) { 02693 /* We'll need the peer name in order to build the structure! */ 02694 for (tmp = var; tmp; tmp = tmp->next) { 02695 if (!strcasecmp(tmp->name, "name")) 02696 peername = tmp->value; 02697 } 02698 } 02699 } 02700 if (!var && peername) { /* Last ditch effort */ 02701 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02702 /*!\note 02703 * If this one loaded something, then we need to ensure that the host 02704 * field matched. The only reason why we can't have this as a criteria 02705 * is because we only have the IP address and the host field might be 02706 * set as a name (and the reverse PTR might not match). 02707 */ 02708 if (var && sin) { 02709 for (tmp = var; tmp; tmp = tmp->next) { 02710 if (!strcasecmp(tmp->name, "host")) { 02711 struct ast_hostent ahp; 02712 struct hostent *hp; 02713 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02714 /* No match */ 02715 ast_variables_destroy(var); 02716 var = NULL; 02717 } 02718 break; 02719 } 02720 } 02721 } 02722 } 02723 if (!var) 02724 return NULL; 02725 02726 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02727 02728 if (!peer) { 02729 ast_variables_destroy(var); 02730 return NULL; 02731 } 02732 02733 for (tmp = var; tmp; tmp = tmp->next) { 02734 /* Make sure it's not a user only... */ 02735 if (!strcasecmp(tmp->name, "type")) { 02736 if (strcasecmp(tmp->value, "friend") && 02737 strcasecmp(tmp->value, "peer")) { 02738 /* Whoops, we weren't supposed to exist! */ 02739 peer = peer_unref(peer); 02740 break; 02741 } 02742 } else if (!strcasecmp(tmp->name, "regseconds")) { 02743 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02744 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02745 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02746 } else if (!strcasecmp(tmp->name, "port")) { 02747 peer->addr.sin_port = htons(atoi(tmp->value)); 02748 } else if (!strcasecmp(tmp->name, "host")) { 02749 if (!strcasecmp(tmp->value, "dynamic")) 02750 dynamic = 1; 02751 } 02752 } 02753 02754 ast_variables_destroy(var); 02755 02756 if (!peer) 02757 return NULL; 02758 02759 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02760 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02761 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02762 if (peer->expire > -1) { 02763 if (!ast_sched_del(sched, peer->expire)) { 02764 peer->expire = -1; 02765 peer_unref(peer); 02766 } 02767 } 02768 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02769 if (peer->expire == -1) 02770 peer_unref(peer); 02771 } 02772 ao2_link(peers, peer); 02773 if (ast_test_flag(peer, IAX_DYNAMIC)) 02774 reg_source_db(peer); 02775 } else { 02776 ast_set_flag(peer, IAX_TEMPONLY); 02777 } 02778 02779 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02780 time(&nowtime); 02781 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02782 memset(&peer->addr, 0, sizeof(peer->addr)); 02783 realtime_update_peer(peer->name, &peer->addr, 0); 02784 if (option_debug) 02785 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02786 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02787 } 02788 else { 02789 if (option_debug) 02790 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02791 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02792 } 02793 } 02794 02795 return peer; 02796 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2869 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02870 { 02871 char port[10]; 02872 char regseconds[20]; 02873 02874 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02875 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02876 ast_update_realtime("iaxpeers", "name", peername, 02877 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02878 "regseconds", regseconds, NULL); 02879 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2798 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02799 { 02800 struct ast_variable *var; 02801 struct ast_variable *tmp; 02802 struct iax2_user *user=NULL; 02803 02804 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02805 if (!var) 02806 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02807 if (!var && sin) { 02808 char porta[6]; 02809 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02810 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02811 if (!var) 02812 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02813 } 02814 if (!var) { /* Last ditch effort */ 02815 var = ast_load_realtime("iaxusers", "name", username, NULL); 02816 /*!\note 02817 * If this one loaded something, then we need to ensure that the host 02818 * field matched. The only reason why we can't have this as a criteria 02819 * is because we only have the IP address and the host field might be 02820 * set as a name (and the reverse PTR might not match). 02821 */ 02822 if (var) { 02823 for (tmp = var; tmp; tmp = tmp->next) { 02824 if (!strcasecmp(tmp->name, "host")) { 02825 struct ast_hostent ahp; 02826 struct hostent *hp; 02827 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02828 /* No match */ 02829 ast_variables_destroy(var); 02830 var = NULL; 02831 } 02832 break; 02833 } 02834 } 02835 } 02836 } 02837 if (!var) 02838 return NULL; 02839 02840 tmp = var; 02841 while(tmp) { 02842 /* Make sure it's not a peer only... */ 02843 if (!strcasecmp(tmp->name, "type")) { 02844 if (strcasecmp(tmp->value, "friend") && 02845 strcasecmp(tmp->value, "user")) { 02846 return NULL; 02847 } 02848 } 02849 tmp = tmp->next; 02850 } 02851 02852 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02853 02854 ast_variables_destroy(var); 02855 02856 if (!user) 02857 return NULL; 02858 02859 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02860 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02861 ao2_link(users, user); 02862 } else { 02863 ast_set_flag(user, IAX_TEMPONLY); 02864 } 02865 02866 return user; 02867 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5933 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
05934 { 05935 char data[80]; 05936 struct in_addr in; 05937 char *c, *d; 05938 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05939 c = strchr(data, ':'); 05940 if (c) { 05941 *c = '\0'; 05942 c++; 05943 if (inet_aton(data, &in)) { 05944 d = strchr(c, ':'); 05945 if (d) { 05946 *d = '\0'; 05947 d++; 05948 if (option_verbose > 2) 05949 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05950 ast_inet_ntoa(in), atoi(c), atoi(d)); 05951 iax2_poke_peer(p, 0); 05952 p->expiry = atoi(d); 05953 memset(&p->addr, 0, sizeof(p->addr)); 05954 p->addr.sin_family = AF_INET; 05955 p->addr.sin_addr = in; 05956 p->addr.sin_port = htons(atoi(c)); 05957 if (p->expire > -1) { 05958 if (!ast_sched_del(sched, p->expire)) { 05959 p->expire = -1; 05960 peer_unref(p); 05961 } 05962 } 05963 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05964 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 05965 if (p->expire == -1) 05966 peer_unref(p); 05967 if (iax2_regfunk) 05968 iax2_regfunk(p->name, 1); 05969 register_peer_exten(p, 1); 05970 } 05971 05972 } 05973 } 05974 } 05975 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5853 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().
05854 { 05855 char multi[256]; 05856 char *stringp, *ext; 05857 if (!ast_strlen_zero(regcontext)) { 05858 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05859 stringp = multi; 05860 while((ext = strsep(&stringp, "&"))) { 05861 if (onoff) { 05862 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05863 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05864 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05865 } else 05866 ast_context_remove_extension(regcontext, ext, 1, NULL); 05867 } 05868 } 05869 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5322 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, iaxs, iaxsl, ies, inaddrcmp(), key(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by handle_request_register(), and socket_process().
05323 { 05324 char requeststr[256] = ""; 05325 char peer[256] = ""; 05326 char md5secret[256] = ""; 05327 char rsasecret[256] = ""; 05328 char secret[256] = ""; 05329 struct iax2_peer *p = NULL; 05330 struct ast_key *key; 05331 char *keyn; 05332 int x; 05333 int expire = 0; 05334 int res = -1; 05335 05336 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05337 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05338 if (ies->username) 05339 ast_copy_string(peer, ies->username, sizeof(peer)); 05340 if (ies->password) 05341 ast_copy_string(secret, ies->password, sizeof(secret)); 05342 if (ies->md5_result) 05343 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05344 if (ies->rsa_result) 05345 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05346 if (ies->refresh) 05347 expire = ies->refresh; 05348 05349 if (ast_strlen_zero(peer)) { 05350 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05351 return -1; 05352 } 05353 05354 /* SLD: first call to lookup peer during registration */ 05355 ast_mutex_unlock(&iaxsl[callno]); 05356 p = find_peer(peer, 1); 05357 ast_mutex_lock(&iaxsl[callno]); 05358 if (!p || !iaxs[callno]) { 05359 if (authdebug && !p) 05360 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05361 goto return_unref; 05362 } 05363 05364 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05365 if (authdebug) 05366 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05367 goto return_unref; 05368 } 05369 05370 if (!ast_apply_ha(p->ha, sin)) { 05371 if (authdebug) 05372 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05373 goto return_unref; 05374 } 05375 if (!inaddrcmp(&p->addr, sin)) 05376 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05377 ast_string_field_set(iaxs[callno], secret, p->secret); 05378 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05379 /* Check secret against what we have on file */ 05380 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05381 if (!ast_strlen_zero(p->inkeys)) { 05382 char tmpkeys[256]; 05383 char *stringp=NULL; 05384 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05385 stringp=tmpkeys; 05386 keyn = strsep(&stringp, ":"); 05387 while(keyn) { 05388 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05389 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05390 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05391 break; 05392 } else if (!key) 05393 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05394 keyn = strsep(&stringp, ":"); 05395 } 05396 if (!keyn) { 05397 if (authdebug) 05398 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05399 goto return_unref; 05400 } 05401 } else { 05402 if (authdebug) 05403 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05404 goto return_unref; 05405 } 05406 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05407 struct MD5Context md5; 05408 unsigned char digest[16]; 05409 char *tmppw, *stringp; 05410 05411 tmppw = ast_strdupa(p->secret); 05412 stringp = tmppw; 05413 while((tmppw = strsep(&stringp, ";"))) { 05414 MD5Init(&md5); 05415 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05416 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05417 MD5Final(digest, &md5); 05418 for (x=0;x<16;x++) 05419 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05420 if (!strcasecmp(requeststr, md5secret)) 05421 break; 05422 } 05423 if (tmppw) { 05424 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05425 } else { 05426 if (authdebug) 05427 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05428 goto return_unref; 05429 } 05430 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05431 /* They've provided a plain text password and we support that */ 05432 if (strcmp(secret, p->secret)) { 05433 if (authdebug) 05434 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05435 goto return_unref; 05436 } else 05437 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05438 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05439 if (authdebug) 05440 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05441 goto return_unref; 05442 } 05443 ast_string_field_set(iaxs[callno], peer, peer); 05444 /* Choose lowest expiry number */ 05445 if (expire && (expire < iaxs[callno]->expiry)) 05446 iaxs[callno]->expiry = expire; 05447 05448 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05449 05450 res = 0; 05451 05452 return_unref: 05453 if (p) 05454 peer_unref(p); 05455 05456 return res; 05457 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6112 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, peer_unref(), and send_command().
Referenced by socket_process().
06113 { 06114 struct iax_ie_data ied; 06115 struct iax2_peer *p; 06116 char challenge[10]; 06117 const char *peer_name; 06118 int res = -1; 06119 06120 peer_name = ast_strdupa(iaxs[callno]->peer); 06121 06122 /* SLD: third call to find_peer in registration */ 06123 ast_mutex_unlock(&iaxsl[callno]); 06124 p = find_peer(peer_name, 1); 06125 ast_mutex_lock(&iaxsl[callno]); 06126 if (!iaxs[callno]) 06127 goto return_unref; 06128 if (!p) { 06129 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06130 goto return_unref; 06131 } 06132 06133 memset(&ied, 0, sizeof(ied)); 06134 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06135 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06136 /* Build the challenge */ 06137 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06138 ast_string_field_set(iaxs[callno], challenge, challenge); 06139 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06140 } 06141 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06142 06143 res = 0; 06144 06145 return_unref: 06146 peer_unref(p); 06147 06148 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 06149 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6151 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_process().
06152 { 06153 struct iax2_registry *reg; 06154 /* Start pessimistic */ 06155 struct iax_ie_data ied; 06156 char peer[256] = ""; 06157 char challenge[256] = ""; 06158 int res; 06159 int authmethods = 0; 06160 if (ies->authmethods) 06161 authmethods = ies->authmethods; 06162 if (ies->username) 06163 ast_copy_string(peer, ies->username, sizeof(peer)); 06164 if (ies->challenge) 06165 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06166 memset(&ied, 0, sizeof(ied)); 06167 reg = iaxs[callno]->reg; 06168 if (reg) { 06169 if (inaddrcmp(®->addr, sin)) { 06170 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06171 return -1; 06172 } 06173 if (ast_strlen_zero(reg->secret)) { 06174 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06175 reg->regstate = REG_STATE_NOAUTH; 06176 return -1; 06177 } 06178 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06179 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06180 if (reg->secret[0] == '[') { 06181 char tmpkey[256]; 06182 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06183 tmpkey[strlen(tmpkey) - 1] = '\0'; 06184 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06185 } else 06186 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06187 if (!res) { 06188 reg->regstate = REG_STATE_AUTHSENT; 06189 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06190 } else 06191 return -1; 06192 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06193 } else 06194 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06195 return -1; 06196 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4611 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
04612 { 04613 switch(regstate) { 04614 case REG_STATE_UNREGISTERED: 04615 return "Unregistered"; 04616 case REG_STATE_REGSENT: 04617 return "Request Sent"; 04618 case REG_STATE_AUTHSENT: 04619 return "Auth. Sent"; 04620 case REG_STATE_REGISTERED: 04621 return "Registered"; 04622 case REG_STATE_REJECTED: 04623 return "Rejected"; 04624 case REG_STATE_TIMEOUT: 04625 return "Timeout"; 04626 case REG_STATE_NOAUTH: 04627 return "No Authentication"; 04628 default: 04629 return "Unknown"; 04630 } 04631 }
static int reload | ( | void | ) | [static] |
Definition at line 10049 of file chan_iax2.c.
References reload_config().
10050 { 10051 return reload_config(); 10052 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10023 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().
10024 { 10025 char *config = "iax.conf"; 10026 struct iax2_registry *reg; 10027 10028 if (set_config(config, 1) > 0) { 10029 prune_peers(); 10030 prune_users(); 10031 AST_LIST_LOCK(®istrations); 10032 AST_LIST_TRAVERSE(®istrations, reg, entry) 10033 iax2_do_register(reg); 10034 AST_LIST_UNLOCK(®istrations); 10035 /* Qualify hosts, too */ 10036 poke_all_peers(); 10037 } 10038 reload_firmware(0); 10039 iax_provision_reload(); 10040 10041 return 0; 10042 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1735 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().
01736 { 01737 struct iax_firmware *cur, *curl, *curp; 01738 DIR *fwd; 01739 struct dirent *de; 01740 char dir[256]; 01741 char fn[256]; 01742 /* Mark all as dead */ 01743 ast_mutex_lock(&waresl.lock); 01744 cur = waresl.wares; 01745 while(cur) { 01746 cur->dead = 1; 01747 cur = cur->next; 01748 } 01749 01750 /* Now that we've freed them, load the new ones */ 01751 if (!unload) { 01752 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01753 fwd = opendir(dir); 01754 if (fwd) { 01755 while((de = readdir(fwd))) { 01756 if (de->d_name[0] != '.') { 01757 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01758 if (!try_firmware(fn)) { 01759 if (option_verbose > 1) 01760 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01761 } 01762 } 01763 } 01764 closedir(fwd); 01765 } else 01766 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01767 } 01768 01769 /* Clean up leftovers */ 01770 cur = waresl.wares; 01771 curp = NULL; 01772 while(cur) { 01773 curl = cur; 01774 cur = cur->next; 01775 if (curl->dead) { 01776 if (curp) { 01777 curp->next = cur; 01778 } else { 01779 waresl.wares = cur; 01780 } 01781 destroy_firmware(curl); 01782 } else { 01783 curp = cur; 01784 } 01785 } 01786 ast_mutex_unlock(&waresl.lock); 01787 }
Definition at line 6655 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
06656 { 06657 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06658 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06659 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06660 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06661 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06662 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06663 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06664 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8827 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), option_debug, and sched.
Referenced by start_network_thread().
08828 { 08829 int count; 08830 int res; 08831 struct timeval tv; 08832 struct timespec ts; 08833 08834 for (;;) { 08835 res = ast_sched_wait(sched); 08836 if ((res > 1000) || (res < 0)) 08837 res = 1000; 08838 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08839 ts.tv_sec = tv.tv_sec; 08840 ts.tv_nsec = tv.tv_usec * 1000; 08841 08842 pthread_testcancel(); 08843 ast_mutex_lock(&sched_lock); 08844 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08845 ast_mutex_unlock(&sched_lock); 08846 pthread_testcancel(); 08847 08848 count = ast_sched_runq(sched); 08849 if (option_debug && count >= 20) 08850 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08851 } 08852 return NULL; 08853 }
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 2529 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), AST_SCHED_DEL, ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02530 { 02531 int type, len; 02532 int ret; 02533 int needfree = 0; 02534 struct ast_channel *owner = NULL; 02535 struct ast_channel *bridge = NULL; 02536 02537 /* Attempt to recover wrapped timestamps */ 02538 unwrap_timestamp(fr); 02539 02540 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02541 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02542 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02543 else { 02544 #if 0 02545 if (option_debug) 02546 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02547 #endif 02548 fr->af.delivery = ast_tv(0,0); 02549 } 02550 02551 type = JB_TYPE_CONTROL; 02552 len = 0; 02553 02554 if(fr->af.frametype == AST_FRAME_VOICE) { 02555 type = JB_TYPE_VOICE; 02556 len = ast_codec_get_samples(&fr->af) / 8; 02557 } else if(fr->af.frametype == AST_FRAME_CNG) { 02558 type = JB_TYPE_SILENCE; 02559 } 02560 02561 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02562 if (tsout) 02563 *tsout = fr->ts; 02564 __do_deliver(fr); 02565 return -1; 02566 } 02567 02568 if ((owner = iaxs[fr->callno]->owner)) 02569 bridge = ast_bridged_channel(owner); 02570 02571 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02572 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02573 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02574 jb_frame frame; 02575 02576 /* deliver any frames in the jb */ 02577 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02578 __do_deliver(frame.data); 02579 /* __do_deliver() can make the call disappear */ 02580 if (!iaxs[fr->callno]) 02581 return -1; 02582 } 02583 02584 jb_reset(iaxs[fr->callno]->jb); 02585 02586 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02587 02588 /* deliver this frame now */ 02589 if (tsout) 02590 *tsout = fr->ts; 02591 __do_deliver(fr); 02592 return -1; 02593 } 02594 02595 /* insert into jitterbuffer */ 02596 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02597 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02598 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02599 if (ret == JB_DROP) { 02600 needfree++; 02601 } else if (ret == JB_SCHED) { 02602 update_jbsched(iaxs[fr->callno]); 02603 } 02604 if (tsout) 02605 *tsout = fr->ts; 02606 if (needfree) { 02607 /* Free our iax frame */ 02608 iax2_frame_free(fr); 02609 return -1; 02610 } 02611 return 0; 02612 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4895 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().
04896 { 04897 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04898 }
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 4914 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().
04915 { 04916 int call_num = i->callno; 04917 /* It is assumed that the callno has already been locked */ 04918 iax2_predestroy(i->callno); 04919 if (!iaxs[call_num]) 04920 return -1; 04921 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04922 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4924 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04925 { 04926 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04927 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4900 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().
04901 { 04902 int res; 04903 ast_mutex_lock(&iaxsl[callno]); 04904 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04905 ast_mutex_unlock(&iaxsl[callno]); 04906 return res; 04907 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 4929 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04930 { 04931 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04932 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1027 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
01028 { 01029 #ifdef SCHED_MULTITHREADED 01030 if (schedule_action(__send_lagrq, data)) 01031 #endif 01032 __send_lagrq(data); 01033 return 0; 01034 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1860 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_backtrace(), ast_inet_ntoa(), ast_log(), errno, error(), f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, LOG_ERROR, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01861 { 01862 int res; 01863 int callno; 01864 01865 if( f == NULL ) { 01866 ast_log(LOG_ERROR, "send_packet( NULL )\n"); 01867 ast_backtrace(); 01868 return -1; 01869 } 01870 01871 callno = f->callno; 01872 01873 /* Don't send if there was an error, but return error instead */ 01874 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01875 return -1; 01876 01877 /* Called with iaxsl held */ 01878 if (option_debug > 2 && iaxdebug) 01879 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)); 01880 if (f->transfer) { 01881 if (iaxdebug) 01882 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01883 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01884 sizeof(iaxs[callno]->transfer)); 01885 } else { 01886 if (iaxdebug) 01887 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01888 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01889 sizeof(iaxs[callno]->addr)); 01890 } 01891 if (res < 0) { 01892 if (option_debug && iaxdebug) 01893 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01894 handle_error(); 01895 } else 01896 res = 0; 01897 return res; 01898 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 992 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00993 { 00994 #ifdef SCHED_MULTITHREADED 00995 if (schedule_action(__send_ping, data)) 00996 #endif 00997 __send_ping(data); 00998 return 0; 00999 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6333 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, option_debug, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06334 { 06335 int res = 0; 06336 struct iax_frame *fr; 06337 struct ast_iax2_meta_hdr *meta; 06338 struct ast_iax2_meta_trunk_hdr *mth; 06339 int calls = 0; 06340 06341 /* Point to frame */ 06342 fr = (struct iax_frame *)tpeer->trunkdata; 06343 /* Point to meta data */ 06344 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06345 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06346 if (tpeer->trunkdatalen) { 06347 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06348 meta->zeros = 0; 06349 meta->metacmd = IAX_META_TRUNK; 06350 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06351 meta->cmddata = IAX_META_TRUNK_MINI; 06352 else 06353 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06354 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06355 /* And the rest of the ast_iax2 header */ 06356 fr->direction = DIRECTION_OUTGRESS; 06357 fr->retrans = -1; 06358 fr->transfer = 0; 06359 /* Any appropriate call will do */ 06360 fr->data = fr->afdata; 06361 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06362 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06363 calls = tpeer->calls; 06364 #if 0 06365 if (option_debug) 06366 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)); 06367 #endif 06368 /* Reset transmit trunk side data */ 06369 tpeer->trunkdatalen = 0; 06370 tpeer->calls = 0; 06371 } 06372 if (res < 0) 06373 return res; 06374 return calls; 06375 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9655 of file chan_iax2.c.
References __ao2_link(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), peers, portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09656 { 09657 struct ast_config *cfg, *ucfg; 09658 int capability=iax2_capability; 09659 struct ast_variable *v; 09660 char *cat; 09661 const char *utype; 09662 const char *tosval; 09663 int format; 09664 int portno = IAX_DEFAULT_PORTNO; 09665 int x; 09666 struct iax2_user *user; 09667 struct iax2_peer *peer; 09668 struct ast_netsock *ns; 09669 #if 0 09670 static unsigned short int last_port=0; 09671 #endif 09672 09673 cfg = ast_config_load(config_file); 09674 09675 if (!cfg) { 09676 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09677 return -1; 09678 } 09679 09680 if (reload) { 09681 set_config_destroy(); 09682 } 09683 09684 /* Reset global codec prefs */ 09685 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09686 09687 /* Reset Global Flags */ 09688 memset(&globalflags, 0, sizeof(globalflags)); 09689 ast_set_flag(&globalflags, IAX_RTUPDATE); 09690 09691 #ifdef SO_NO_CHECK 09692 nochecksums = 0; 09693 #endif 09694 09695 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09696 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09697 09698 maxauthreq = 3; 09699 09700 v = ast_variable_browse(cfg, "general"); 09701 09702 /* Seed initial tos value */ 09703 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09704 if (tosval) { 09705 if (ast_str2tos(tosval, &tos)) 09706 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09707 } 09708 while(v) { 09709 if (!strcasecmp(v->name, "bindport")){ 09710 if (reload) 09711 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09712 else 09713 portno = atoi(v->value); 09714 } else if (!strcasecmp(v->name, "pingtime")) 09715 ping_time = atoi(v->value); 09716 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09717 if (reload) { 09718 if (atoi(v->value) != iaxthreadcount) 09719 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09720 } else { 09721 iaxthreadcount = atoi(v->value); 09722 if (iaxthreadcount < 1) { 09723 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09724 iaxthreadcount = 1; 09725 } else if (iaxthreadcount > 256) { 09726 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09727 iaxthreadcount = 256; 09728 } 09729 } 09730 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09731 if (reload) { 09732 AST_LIST_LOCK(&dynamic_list); 09733 iaxmaxthreadcount = atoi(v->value); 09734 AST_LIST_UNLOCK(&dynamic_list); 09735 } else { 09736 iaxmaxthreadcount = atoi(v->value); 09737 if (iaxmaxthreadcount < 0) { 09738 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09739 iaxmaxthreadcount = 0; 09740 } else if (iaxmaxthreadcount > 256) { 09741 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09742 iaxmaxthreadcount = 256; 09743 } 09744 } 09745 } else if (!strcasecmp(v->name, "nochecksums")) { 09746 #ifdef SO_NO_CHECK 09747 if (ast_true(v->value)) 09748 nochecksums = 1; 09749 else 09750 nochecksums = 0; 09751 #else 09752 if (ast_true(v->value)) 09753 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09754 #endif 09755 } 09756 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09757 maxjitterbuffer = atoi(v->value); 09758 else if (!strcasecmp(v->name, "resyncthreshold")) 09759 resyncthreshold = atoi(v->value); 09760 else if (!strcasecmp(v->name, "maxjitterinterps")) 09761 maxjitterinterps = atoi(v->value); 09762 else if (!strcasecmp(v->name, "lagrqtime")) 09763 lagrq_time = atoi(v->value); 09764 else if (!strcasecmp(v->name, "maxregexpire")) 09765 max_reg_expire = atoi(v->value); 09766 else if (!strcasecmp(v->name, "minregexpire")) 09767 min_reg_expire = atoi(v->value); 09768 else if (!strcasecmp(v->name, "bindaddr")) { 09769 if (reload) { 09770 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09771 } else { 09772 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09773 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09774 } else { 09775 if (option_verbose > 1) { 09776 if (strchr(v->value, ':')) 09777 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09778 else 09779 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09780 } 09781 if (defaultsockfd < 0) 09782 defaultsockfd = ast_netsock_sockfd(ns); 09783 ast_netsock_unref(ns); 09784 } 09785 } 09786 } else if (!strcasecmp(v->name, "authdebug")) 09787 authdebug = ast_true(v->value); 09788 else if (!strcasecmp(v->name, "encryption")) 09789 iax2_encryption = get_encrypt_methods(v->value); 09790 else if (!strcasecmp(v->name, "notransfer")) { 09791 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09792 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09793 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09794 } else if (!strcasecmp(v->name, "transfer")) { 09795 if (!strcasecmp(v->value, "mediaonly")) { 09796 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09797 } else if (ast_true(v->value)) { 09798 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09799 } else 09800 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09801 } else if (!strcasecmp(v->name, "codecpriority")) { 09802 if(!strcasecmp(v->value, "caller")) 09803 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09804 else if(!strcasecmp(v->value, "disabled")) 09805 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09806 else if(!strcasecmp(v->value, "reqonly")) { 09807 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09808 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09809 } 09810 } else if (!strcasecmp(v->name, "jitterbuffer")) 09811 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09812 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09813 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09814 else if (!strcasecmp(v->name, "delayreject")) 09815 delayreject = ast_true(v->value); 09816 else if (!strcasecmp(v->name, "rtcachefriends")) 09817 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09818 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09819 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09820 else if (!strcasecmp(v->name, "rtupdate")) 09821 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09822 else if (!strcasecmp(v->name, "trunktimestamps")) 09823 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09824 else if (!strcasecmp(v->name, "rtautoclear")) { 09825 int i = atoi(v->value); 09826 if(i > 0) 09827 global_rtautoclear = i; 09828 else 09829 i = 0; 09830 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09831 } else if (!strcasecmp(v->name, "trunkfreq")) { 09832 trunkfreq = atoi(v->value); 09833 if (trunkfreq < 10) 09834 trunkfreq = 10; 09835 } else if (!strcasecmp(v->name, "autokill")) { 09836 if (sscanf(v->value, "%d", &x) == 1) { 09837 if (x >= 0) 09838 autokill = x; 09839 else 09840 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09841 } else if (ast_true(v->value)) { 09842 autokill = DEFAULT_MAXMS; 09843 } else { 09844 autokill = 0; 09845 } 09846 } else if (!strcasecmp(v->name, "bandwidth")) { 09847 if (!strcasecmp(v->value, "low")) { 09848 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09849 } else if (!strcasecmp(v->value, "medium")) { 09850 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09851 } else if (!strcasecmp(v->value, "high")) { 09852 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09853 } else 09854 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09855 } else if (!strcasecmp(v->name, "allow")) { 09856 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09857 } else if (!strcasecmp(v->name, "disallow")) { 09858 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09859 } else if (!strcasecmp(v->name, "register")) { 09860 iax2_register(v->value, v->lineno); 09861 } else if (!strcasecmp(v->name, "iaxcompat")) { 09862 iaxcompat = ast_true(v->value); 09863 } else if (!strcasecmp(v->name, "regcontext")) { 09864 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09865 /* Create context if it doesn't exist already */ 09866 if (!ast_context_find(regcontext)) 09867 ast_context_create(NULL, regcontext, "IAX2"); 09868 } else if (!strcasecmp(v->name, "tos")) { 09869 if (ast_str2tos(v->value, &tos)) 09870 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09871 } else if (!strcasecmp(v->name, "accountcode")) { 09872 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09873 } else if (!strcasecmp(v->name, "mohinterpret")) { 09874 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09875 } else if (!strcasecmp(v->name, "mohsuggest")) { 09876 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09877 } else if (!strcasecmp(v->name, "amaflags")) { 09878 format = ast_cdr_amaflags2int(v->value); 09879 if (format < 0) { 09880 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09881 } else { 09882 amaflags = format; 09883 } 09884 } else if (!strcasecmp(v->name, "language")) { 09885 ast_copy_string(language, v->value, sizeof(language)); 09886 } else if (!strcasecmp(v->name, "maxauthreq")) { 09887 maxauthreq = atoi(v->value); 09888 if (maxauthreq < 0) 09889 maxauthreq = 0; 09890 } else if (!strcasecmp(v->name, "adsi")) { 09891 adsi = ast_true(v->value); 09892 } /*else if (strcasecmp(v->name,"type")) */ 09893 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09894 v = v->next; 09895 } 09896 09897 if (defaultsockfd < 0) { 09898 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09899 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09900 } else { 09901 if (option_verbose > 1) 09902 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09903 defaultsockfd = ast_netsock_sockfd(ns); 09904 ast_netsock_unref(ns); 09905 } 09906 } 09907 if (reload) { 09908 ast_netsock_release(outsock); 09909 outsock = ast_netsock_list_alloc(); 09910 if (!outsock) { 09911 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09912 return -1; 09913 } 09914 ast_netsock_init(outsock); 09915 } 09916 09917 if (min_reg_expire > max_reg_expire) { 09918 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09919 min_reg_expire, max_reg_expire, max_reg_expire); 09920 min_reg_expire = max_reg_expire; 09921 } 09922 iax2_capability = capability; 09923 09924 ucfg = ast_config_load("users.conf"); 09925 if (ucfg) { 09926 struct ast_variable *gen; 09927 int genhasiax; 09928 int genregisteriax; 09929 const char *hasiax, *registeriax; 09930 09931 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09932 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09933 gen = ast_variable_browse(ucfg, "general"); 09934 cat = ast_category_browse(ucfg, NULL); 09935 while (cat) { 09936 if (strcasecmp(cat, "general")) { 09937 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09938 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09939 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09940 /* Start with general parameters, then specific parameters, user and peer */ 09941 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09942 if (user) { 09943 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09944 user = user_unref(user); 09945 } 09946 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09947 if (peer) { 09948 if (ast_test_flag(peer, IAX_DYNAMIC)) 09949 reg_source_db(peer); 09950 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09951 peer = peer_unref(peer); 09952 } 09953 } 09954 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09955 char tmp[256]; 09956 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09957 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09958 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09959 if (!host) 09960 host = ast_variable_retrieve(ucfg, "general", "host"); 09961 if (!username) 09962 username = ast_variable_retrieve(ucfg, "general", "username"); 09963 if (!secret) 09964 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09965 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09966 if (!ast_strlen_zero(secret)) 09967 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09968 else 09969 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09970 iax2_register(tmp, 0); 09971 } 09972 } 09973 } 09974 cat = ast_category_browse(ucfg, cat); 09975 } 09976 ast_config_destroy(ucfg); 09977 } 09978 09979 cat = ast_category_browse(cfg, NULL); 09980 while(cat) { 09981 if (strcasecmp(cat, "general")) { 09982 utype = ast_variable_retrieve(cfg, cat, "type"); 09983 if (utype) { 09984 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 09985 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 09986 if (user) { 09987 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09988 user = user_unref(user); 09989 } 09990 } 09991 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 09992 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 09993 if (peer) { 09994 if (ast_test_flag(peer, IAX_DYNAMIC)) 09995 reg_source_db(peer); 09996 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09997 peer = peer_unref(peer); 09998 } 09999 } else if (strcasecmp(utype, "user")) { 10000 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10001 } 10002 } else 10003 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10004 } 10005 cat = ast_category_browse(cfg, cat); 10006 } 10007 ast_config_destroy(cfg); 10008 set_timing(); 10009 return 1; 10010 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9639 of file chan_iax2.c.
References ast_clear_flag, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09640 { 09641 strcpy(accountcode, ""); 09642 strcpy(language, ""); 09643 strcpy(mohinterpret, "default"); 09644 strcpy(mohsuggest, ""); 09645 amaflags = 0; 09646 delayreject = 0; 09647 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09648 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09649 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09650 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09651 delete_users(); 09652 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9624 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09625 { 09626 #ifdef HAVE_ZAPTEL 09627 int bs = trunkfreq * 8; 09628 if (timingfd > -1) { 09629 if ( 09630 #ifdef ZT_TIMERACK 09631 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09632 #endif 09633 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09634 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09635 } 09636 #endif 09637 }
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 6807 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, decrypt_frame(), dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_STATE_UNCHANGED, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), chan_iax2_pvt::state, stop_stuff(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames().
06808 { 06809 struct sockaddr_in sin; 06810 int res; 06811 int updatehistory=1; 06812 int new = NEW_PREVENT; 06813 void *ptr; 06814 int dcallno = 0; 06815 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06816 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06817 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06818 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06819 struct ast_iax2_meta_trunk_hdr *mth; 06820 struct ast_iax2_meta_trunk_entry *mte; 06821 struct ast_iax2_meta_trunk_mini *mtm; 06822 struct iax_frame *fr; 06823 struct iax_frame *cur; 06824 struct ast_frame f = { 0, }; 06825 struct ast_channel *c; 06826 struct iax2_dpcache *dp; 06827 struct iax2_peer *peer; 06828 struct iax2_trunk_peer *tpeer; 06829 struct timeval rxtrunktime; 06830 struct iax_ies ies; 06831 struct iax_ie_data ied0, ied1; 06832 int format; 06833 int fd; 06834 int exists; 06835 int minivid = 0; 06836 unsigned int ts; 06837 char empty[32]=""; /* Safety measure */ 06838 struct iax_frame *duped_fr; 06839 char host_pref_buf[128]; 06840 char caller_pref_buf[128]; 06841 struct ast_codec_pref pref; 06842 char *using_prefs = "mine"; 06843 06844 /* allocate an iax_frame with 4096 bytes of data buffer */ 06845 fr = alloca(sizeof(*fr) + 4096); 06846 fr->callno = 0; 06847 fr->afdatalen = 4096; /* From alloca() above */ 06848 06849 /* Copy frequently used parameters to the stack */ 06850 res = thread->buf_len; 06851 fd = thread->iofd; 06852 memcpy(&sin, &thread->iosin, sizeof(sin)); 06853 06854 if (res < sizeof(*mh)) { 06855 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06856 return 1; 06857 } 06858 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06859 if (res < sizeof(*vh)) { 06860 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)); 06861 return 1; 06862 } 06863 06864 /* This is a video frame, get call number */ 06865 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd); 06866 minivid = 1; 06867 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06868 unsigned char metatype; 06869 06870 if (res < sizeof(*meta)) { 06871 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)); 06872 return 1; 06873 } 06874 06875 /* This is a meta header */ 06876 switch(meta->metacmd) { 06877 case IAX_META_TRUNK: 06878 if (res < (sizeof(*meta) + sizeof(*mth))) { 06879 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06880 sizeof(*meta) + sizeof(*mth)); 06881 return 1; 06882 } 06883 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06884 ts = ntohl(mth->ts); 06885 metatype = meta->cmddata; 06886 res -= (sizeof(*meta) + sizeof(*mth)); 06887 ptr = mth->data; 06888 tpeer = find_tpeer(&sin, fd); 06889 if (!tpeer) { 06890 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)); 06891 return 1; 06892 } 06893 tpeer->trunkact = ast_tvnow(); 06894 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06895 tpeer->rxtrunktime = tpeer->trunkact; 06896 rxtrunktime = tpeer->rxtrunktime; 06897 ast_mutex_unlock(&tpeer->lock); 06898 while(res >= sizeof(*mte)) { 06899 /* Process channels */ 06900 unsigned short callno, trunked_ts, len; 06901 06902 if (metatype == IAX_META_TRUNK_MINI) { 06903 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06904 ptr += sizeof(*mtm); 06905 res -= sizeof(*mtm); 06906 len = ntohs(mtm->len); 06907 callno = ntohs(mtm->mini.callno); 06908 trunked_ts = ntohs(mtm->mini.ts); 06909 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06910 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06911 ptr += sizeof(*mte); 06912 res -= sizeof(*mte); 06913 len = ntohs(mte->len); 06914 callno = ntohs(mte->callno); 06915 trunked_ts = 0; 06916 } else { 06917 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06918 break; 06919 } 06920 /* Stop if we don't have enough data */ 06921 if (len > res) 06922 break; 06923 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd); 06924 if (fr->callno) { 06925 ast_mutex_lock(&iaxsl[fr->callno]); 06926 /* If it's a valid call, deliver the contents. If not, we 06927 drop it, since we don't have a scallno to use for an INVAL */ 06928 /* Process as a mini frame */ 06929 memset(&f, 0, sizeof(f)); 06930 f.frametype = AST_FRAME_VOICE; 06931 if (iaxs[fr->callno]) { 06932 if (iaxs[fr->callno]->voiceformat > 0) { 06933 f.subclass = iaxs[fr->callno]->voiceformat; 06934 f.datalen = len; 06935 if (f.datalen >= 0) { 06936 if (f.datalen) 06937 f.data = ptr; 06938 if(trunked_ts) { 06939 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06940 } else 06941 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06942 /* Don't pass any packets until we're started */ 06943 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06944 /* Common things */ 06945 f.src = "IAX2"; 06946 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06947 f.samples = ast_codec_get_samples(&f); 06948 iax_frame_wrap(fr, &f); 06949 duped_fr = iaxfrdup2(fr); 06950 if (duped_fr) { 06951 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06952 } 06953 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06954 if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06955 iaxs[fr->callno]->last = fr->ts; 06956 #if 1 06957 if (option_debug && iaxdebug) 06958 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06959 #endif 06960 } 06961 } 06962 } else { 06963 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06964 } 06965 } else { 06966 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06967 iax2_vnak(fr->callno); 06968 } 06969 } 06970 ast_mutex_unlock(&iaxsl[fr->callno]); 06971 } 06972 ptr += len; 06973 res -= len; 06974 } 06975 06976 } 06977 return 1; 06978 } 06979 06980 #ifdef DEBUG_SUPPORT 06981 if (iaxdebug && (res >= sizeof(*fh))) 06982 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06983 #endif 06984 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06985 if (res < sizeof(*fh)) { 06986 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)); 06987 return 1; 06988 } 06989 06990 /* Get the destination call number */ 06991 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06992 /* Retrieve the type and subclass */ 06993 f.frametype = fh->type; 06994 if (f.frametype == AST_FRAME_VIDEO) { 06995 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06996 } else { 06997 f.subclass = uncompress_subclass(fh->csub); 06998 } 06999 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07000 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07001 (f.subclass == IAX_COMMAND_REGREL))) 07002 new = NEW_ALLOW; 07003 } else { 07004 /* Don't know anything about it yet */ 07005 f.frametype = AST_FRAME_NULL; 07006 f.subclass = 0; 07007 } 07008 07009 if (!fr->callno) 07010 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd); 07011 07012 if (fr->callno > 0) 07013 ast_mutex_lock(&iaxsl[fr->callno]); 07014 07015 if (!fr->callno || !iaxs[fr->callno]) { 07016 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07017 frame, reply with an inval */ 07018 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07019 /* We can only raw hangup control frames */ 07020 if (((f.subclass != IAX_COMMAND_INVAL) && 07021 (f.subclass != IAX_COMMAND_TXCNT) && 07022 (f.subclass != IAX_COMMAND_TXACC) && 07023 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07024 (f.frametype != AST_FRAME_IAX)) 07025 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07026 fd); 07027 } 07028 if (fr->callno > 0) 07029 ast_mutex_unlock(&iaxsl[fr->callno]); 07030 return 1; 07031 } 07032 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07033 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07034 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07035 ast_mutex_unlock(&iaxsl[fr->callno]); 07036 return 1; 07037 } 07038 #ifdef DEBUG_SUPPORT 07039 else if (iaxdebug) 07040 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07041 #endif 07042 } 07043 07044 /* count this frame */ 07045 iaxs[fr->callno]->frames_received++; 07046 07047 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07048 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07049 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 07050 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 07051 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07052 if (option_debug && iaxdebug) 07053 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07054 /* Check if it's out of order (and not an ACK or INVAL) */ 07055 fr->oseqno = fh->oseqno; 07056 fr->iseqno = fh->iseqno; 07057 fr->ts = ntohl(fh->ts); 07058 #ifdef IAXTESTS 07059 if (test_resync) { 07060 if (option_debug) 07061 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07062 fr->ts += test_resync; 07063 } 07064 #endif /* IAXTESTS */ 07065 #if 0 07066 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07067 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07068 (f.subclass == IAX_COMMAND_NEW || 07069 f.subclass == IAX_COMMAND_AUTHREQ || 07070 f.subclass == IAX_COMMAND_ACCEPT || 07071 f.subclass == IAX_COMMAND_REJECT)) ) ) 07072 #endif 07073 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07074 updatehistory = 0; 07075 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07076 (iaxs[fr->callno]->iseqno || 07077 ((f.subclass != IAX_COMMAND_TXCNT) && 07078 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07079 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07080 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07081 (f.subclass != IAX_COMMAND_TXACC)) || 07082 (f.frametype != AST_FRAME_IAX))) { 07083 if ( 07084 ((f.subclass != IAX_COMMAND_ACK) && 07085 (f.subclass != IAX_COMMAND_INVAL) && 07086 (f.subclass != IAX_COMMAND_TXCNT) && 07087 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07088 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07089 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07090 (f.subclass != IAX_COMMAND_TXACC) && 07091 (f.subclass != IAX_COMMAND_VNAK)) || 07092 (f.frametype != AST_FRAME_IAX)) { 07093 /* If it's not an ACK packet, it's out of order. */ 07094 if (option_debug) 07095 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07096 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07097 /* Check to see if we need to request retransmission, 07098 * and take sequence number wraparound into account */ 07099 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07100 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07101 if ((f.frametype != AST_FRAME_IAX) || 07102 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07103 if (option_debug) 07104 ast_log(LOG_DEBUG, "Acking anyway\n"); 07105 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07106 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07107 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07108 } 07109 } else { 07110 /* Send a VNAK requesting retransmission */ 07111 iax2_vnak(fr->callno); 07112 } 07113 ast_mutex_unlock(&iaxsl[fr->callno]); 07114 return 1; 07115 } 07116 } else { 07117 /* Increment unless it's an ACK or VNAK */ 07118 if (((f.subclass != IAX_COMMAND_ACK) && 07119 (f.subclass != IAX_COMMAND_INVAL) && 07120 (f.subclass != IAX_COMMAND_TXCNT) && 07121 (f.subclass != IAX_COMMAND_TXACC) && 07122 (f.subclass != IAX_COMMAND_VNAK)) || 07123 (f.frametype != AST_FRAME_IAX)) 07124 iaxs[fr->callno]->iseqno++; 07125 } 07126 /* A full frame */ 07127 if (res < sizeof(*fh)) { 07128 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07129 ast_mutex_unlock(&iaxsl[fr->callno]); 07130 return 1; 07131 } 07132 /* Ensure text frames are NULL-terminated */ 07133 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07134 if (res < thread->buf_size) 07135 thread->buf[res++] = '\0'; 07136 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07137 thread->buf[res - 1] = '\0'; 07138 } 07139 f.datalen = res - sizeof(*fh); 07140 07141 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07142 from the real peer, not the transfer peer */ 07143 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07144 ((f.subclass != IAX_COMMAND_INVAL) || 07145 (f.frametype != AST_FRAME_IAX))) { 07146 unsigned char x; 07147 int call_to_destroy; 07148 /* XXX This code is not very efficient. Surely there is a better way which still 07149 properly handles boundary conditions? XXX */ 07150 /* First we have to qualify that the ACKed value is within our window */ 07151 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07152 if (fr->iseqno == x) 07153 break; 07154 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07155 /* The acknowledgement is within our window. Time to acknowledge everything 07156 that it says to */ 07157 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07158 /* Ack the packet with the given timestamp */ 07159 if (option_debug && iaxdebug) 07160 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07161 call_to_destroy = 0; 07162 AST_LIST_LOCK(&iaxq.queue); 07163 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07164 /* If it's our call, and our timestamp, mark -1 retries */ 07165 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07166 cur->retries = -1; 07167 /* Destroy call if this is the end */ 07168 if (cur->final) 07169 call_to_destroy = fr->callno; 07170 } 07171 } 07172 AST_LIST_UNLOCK(&iaxq.queue); 07173 if (call_to_destroy) { 07174 if (iaxdebug && option_debug) 07175 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07176 iax2_destroy(call_to_destroy); 07177 } 07178 } 07179 /* Note how much we've received acknowledgement for */ 07180 if (iaxs[fr->callno]) 07181 iaxs[fr->callno]->rseqno = fr->iseqno; 07182 else { 07183 /* Stop processing now */ 07184 ast_mutex_unlock(&iaxsl[fr->callno]); 07185 return 1; 07186 } 07187 } else if (option_debug) 07188 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07189 } 07190 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07191 ((f.frametype != AST_FRAME_IAX) || 07192 ((f.subclass != IAX_COMMAND_TXACC) && 07193 (f.subclass != IAX_COMMAND_TXCNT)))) { 07194 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07195 ast_mutex_unlock(&iaxsl[fr->callno]); 07196 return 1; 07197 } 07198 07199 if (f.datalen) { 07200 if (f.frametype == AST_FRAME_IAX) { 07201 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07202 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07203 ast_mutex_unlock(&iaxsl[fr->callno]); 07204 return 1; 07205 } 07206 f.data = NULL; 07207 f.datalen = 0; 07208 } else 07209 f.data = thread->buf + sizeof(*fh); 07210 } else { 07211 if (f.frametype == AST_FRAME_IAX) 07212 f.data = NULL; 07213 else 07214 f.data = empty; 07215 memset(&ies, 0, sizeof(ies)); 07216 } 07217 07218 /* when we receive the first full frame for a new incoming channel, 07219 it is safe to start the PBX on the channel because we have now 07220 completed a 3-way handshake with the peer */ 07221 if ((f.frametype == AST_FRAME_VOICE) || 07222 (f.frametype == AST_FRAME_VIDEO) || 07223 (f.frametype == AST_FRAME_IAX)) { 07224 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07225 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07226 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07227 ast_mutex_unlock(&iaxsl[fr->callno]); 07228 return 1; 07229 } 07230 } 07231 } 07232 07233 if (f.frametype == AST_FRAME_VOICE) { 07234 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07235 iaxs[fr->callno]->voiceformat = f.subclass; 07236 if (option_debug) 07237 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07238 if (iaxs[fr->callno]->owner) { 07239 int orignative; 07240 retryowner: 07241 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07242 ast_mutex_unlock(&iaxsl[fr->callno]); 07243 usleep(1); 07244 ast_mutex_lock(&iaxsl[fr->callno]); 07245 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07246 } 07247 if (iaxs[fr->callno]) { 07248 if (iaxs[fr->callno]->owner) { 07249 orignative = iaxs[fr->callno]->owner->nativeformats; 07250 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07251 if (iaxs[fr->callno]->owner->readformat) 07252 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07253 iaxs[fr->callno]->owner->nativeformats = orignative; 07254 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07255 } 07256 } else { 07257 if (option_debug) 07258 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07259 ast_mutex_unlock(&iaxsl[fr->callno]); 07260 return 1; 07261 } 07262 } 07263 } 07264 } 07265 if (f.frametype == AST_FRAME_VIDEO) { 07266 if (f.subclass != iaxs[fr->callno]->videoformat) { 07267 if (option_debug) 07268 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07269 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07270 } 07271 } 07272 if (f.frametype == AST_FRAME_IAX) { 07273 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07274 /* Handle the IAX pseudo frame itself */ 07275 if (option_debug && iaxdebug) 07276 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07277 07278 /* Update last ts unless the frame's timestamp originated with us. */ 07279 if (iaxs[fr->callno]->last < fr->ts && 07280 f.subclass != IAX_COMMAND_ACK && 07281 f.subclass != IAX_COMMAND_PONG && 07282 f.subclass != IAX_COMMAND_LAGRP) { 07283 iaxs[fr->callno]->last = fr->ts; 07284 if (option_debug && iaxdebug) 07285 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07286 } 07287 07288 switch(f.subclass) { 07289 case IAX_COMMAND_ACK: 07290 /* Do nothing */ 07291 break; 07292 case IAX_COMMAND_QUELCH: 07293 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07294 /* Generate Manager Hold event, if necessary*/ 07295 if (iaxs[fr->callno]->owner) { 07296 manager_event(EVENT_FLAG_CALL, "Hold", 07297 "Channel: %s\r\n" 07298 "Uniqueid: %s\r\n", 07299 iaxs[fr->callno]->owner->name, 07300 iaxs[fr->callno]->owner->uniqueid); 07301 } 07302 07303 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07304 if (ies.musiconhold) { 07305 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07306 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07307 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07308 S_OR(mohsuggest, NULL), 07309 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07310 if (!iaxs[fr->callno]) { 07311 ast_mutex_unlock(&iaxsl[fr->callno]); 07312 return 1; 07313 } 07314 } 07315 } 07316 } 07317 break; 07318 case IAX_COMMAND_UNQUELCH: 07319 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07320 /* Generate Manager Unhold event, if necessary*/ 07321 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07322 manager_event(EVENT_FLAG_CALL, "Unhold", 07323 "Channel: %s\r\n" 07324 "Uniqueid: %s\r\n", 07325 iaxs[fr->callno]->owner->name, 07326 iaxs[fr->callno]->owner->uniqueid); 07327 } 07328 07329 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07330 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07331 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07332 if (!iaxs[fr->callno]) { 07333 ast_mutex_unlock(&iaxsl[fr->callno]); 07334 return 1; 07335 } 07336 } 07337 } 07338 break; 07339 case IAX_COMMAND_TXACC: 07340 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07341 /* Ack the packet with the given timestamp */ 07342 AST_LIST_LOCK(&iaxq.queue); 07343 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07344 /* Cancel any outstanding txcnt's */ 07345 if ((fr->callno == cur->callno) && (cur->transfer)) 07346 cur->retries = -1; 07347 } 07348 AST_LIST_UNLOCK(&iaxq.queue); 07349 memset(&ied1, 0, sizeof(ied1)); 07350 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07351 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07352 iaxs[fr->callno]->transferring = TRANSFER_READY; 07353 } 07354 break; 07355 case IAX_COMMAND_NEW: 07356 /* Ignore if it's already up */ 07357 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07358 break; 07359 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07360 ast_mutex_unlock(&iaxsl[fr->callno]); 07361 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07362 ast_mutex_lock(&iaxsl[fr->callno]); 07363 if (!iaxs[fr->callno]) { 07364 ast_mutex_unlock(&iaxsl[fr->callno]); 07365 return 1; 07366 } 07367 } 07368 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07369 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07370 int new_callno; 07371 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07372 fr->callno = new_callno; 07373 } 07374 /* For security, always ack immediately */ 07375 if (delayreject) 07376 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07377 if (check_access(fr->callno, &sin, &ies)) { 07378 /* They're not allowed on */ 07379 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07380 if (authdebug) 07381 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); 07382 break; 07383 } 07384 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07385 const char *context, *exten, *cid_num; 07386 07387 context = ast_strdupa(iaxs[fr->callno]->context); 07388 exten = ast_strdupa(iaxs[fr->callno]->exten); 07389 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07390 07391 /* This might re-enter the IAX code and need the lock */ 07392 ast_mutex_unlock(&iaxsl[fr->callno]); 07393 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07394 ast_mutex_lock(&iaxsl[fr->callno]); 07395 07396 if (!iaxs[fr->callno]) { 07397 ast_mutex_unlock(&iaxsl[fr->callno]); 07398 return 1; 07399 } 07400 } else 07401 exists = 0; 07402 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07403 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07404 memset(&ied0, 0, sizeof(ied0)); 07405 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07406 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07407 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07408 if (!iaxs[fr->callno]) { 07409 ast_mutex_unlock(&iaxsl[fr->callno]); 07410 return 1; 07411 } 07412 if (authdebug) 07413 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); 07414 } else { 07415 /* Select an appropriate format */ 07416 07417 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07418 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07419 using_prefs = "reqonly"; 07420 } else { 07421 using_prefs = "disabled"; 07422 } 07423 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07424 memset(&pref, 0, sizeof(pref)); 07425 strcpy(caller_pref_buf, "disabled"); 07426 strcpy(host_pref_buf, "disabled"); 07427 } else { 07428 using_prefs = "mine"; 07429 /* If the information elements are in here... use them */ 07430 if (ies.codec_prefs) 07431 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07432 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07433 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07434 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07435 pref = iaxs[fr->callno]->rprefs; 07436 using_prefs = "caller"; 07437 } else { 07438 pref = iaxs[fr->callno]->prefs; 07439 } 07440 } else 07441 pref = iaxs[fr->callno]->prefs; 07442 07443 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07444 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07445 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07446 } 07447 if (!format) { 07448 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07449 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07450 if (!format) { 07451 memset(&ied0, 0, sizeof(ied0)); 07452 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07453 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07454 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07455 if (!iaxs[fr->callno]) { 07456 ast_mutex_unlock(&iaxsl[fr->callno]); 07457 return 1; 07458 } 07459 if (authdebug) { 07460 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07461 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); 07462 else 07463 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); 07464 } 07465 } else { 07466 /* Pick one... */ 07467 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07468 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07469 format = 0; 07470 } else { 07471 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07472 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07473 memset(&pref, 0, sizeof(pref)); 07474 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07475 strcpy(caller_pref_buf,"disabled"); 07476 strcpy(host_pref_buf,"disabled"); 07477 } else { 07478 using_prefs = "mine"; 07479 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07480 /* Do the opposite of what we tried above. */ 07481 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07482 pref = iaxs[fr->callno]->prefs; 07483 } else { 07484 pref = iaxs[fr->callno]->rprefs; 07485 using_prefs = "caller"; 07486 } 07487 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07488 07489 } else /* if no codec_prefs IE do it the old way */ 07490 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07491 } 07492 } 07493 07494 if (!format) { 07495 memset(&ied0, 0, sizeof(ied0)); 07496 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07497 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07498 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07499 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07500 if (!iaxs[fr->callno]) { 07501 ast_mutex_unlock(&iaxsl[fr->callno]); 07502 return 1; 07503 } 07504 if (authdebug) 07505 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); 07506 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07507 break; 07508 } 07509 } 07510 } 07511 if (format) { 07512 /* No authentication required, let them in */ 07513 memset(&ied1, 0, sizeof(ied1)); 07514 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07515 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07516 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07517 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07518 if (option_verbose > 2) 07519 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07520 "%srequested format = %s,\n" 07521 "%srequested prefs = %s,\n" 07522 "%sactual format = %s,\n" 07523 "%shost prefs = %s,\n" 07524 "%spriority = %s\n", 07525 ast_inet_ntoa(sin.sin_addr), 07526 VERBOSE_PREFIX_4, 07527 ast_getformatname(iaxs[fr->callno]->peerformat), 07528 VERBOSE_PREFIX_4, 07529 caller_pref_buf, 07530 VERBOSE_PREFIX_4, 07531 ast_getformatname(format), 07532 VERBOSE_PREFIX_4, 07533 host_pref_buf, 07534 VERBOSE_PREFIX_4, 07535 using_prefs); 07536 07537 iaxs[fr->callno]->chosenformat = format; 07538 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07539 } else { 07540 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07541 /* If this is a TBD call, we're ready but now what... */ 07542 if (option_verbose > 2) 07543 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07544 } 07545 } 07546 } 07547 break; 07548 } 07549 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07550 merge_encryption(iaxs[fr->callno],ies.encmethods); 07551 else 07552 iaxs[fr->callno]->encmethods = 0; 07553 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07554 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07555 if (!iaxs[fr->callno]) { 07556 ast_mutex_unlock(&iaxsl[fr->callno]); 07557 return 1; 07558 } 07559 break; 07560 case IAX_COMMAND_DPREQ: 07561 /* Request status in the dialplan */ 07562 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07563 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07564 if (iaxcompat) { 07565 /* Spawn a thread for the lookup */ 07566 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07567 } else { 07568 /* Just look it up */ 07569 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07570 } 07571 } 07572 break; 07573 case IAX_COMMAND_HANGUP: 07574 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07575 if (option_debug) 07576 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07577 /* Set hangup cause according to remote */ 07578 if (ies.causecode && iaxs[fr->callno]->owner) 07579 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07580 /* Send ack immediately, before we destroy */ 07581 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07582 iax2_destroy(fr->callno); 07583 break; 07584 case IAX_COMMAND_REJECT: 07585 /* Set hangup cause according to remote */ 07586 if (ies.causecode && iaxs[fr->callno]->owner) 07587 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07588 07589 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07590 if (iaxs[fr->callno]->owner && authdebug) 07591 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07592 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07593 ies.cause ? ies.cause : "<Unknown>"); 07594 if (option_debug) 07595 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07596 fr->callno); 07597 } 07598 /* Send ack immediately, before we destroy */ 07599 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07600 fr->ts, NULL, 0, fr->iseqno); 07601 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07602 iaxs[fr->callno]->error = EPERM; 07603 iax2_destroy(fr->callno); 07604 break; 07605 case IAX_COMMAND_TRANSFER: 07606 { 07607 struct ast_channel *bridged_chan; 07608 07609 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07610 /* Set BLINDTRANSFER channel variables */ 07611 07612 ast_mutex_unlock(&iaxsl[fr->callno]); 07613 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07614 ast_mutex_lock(&iaxsl[fr->callno]); 07615 if (!iaxs[fr->callno]) { 07616 ast_mutex_unlock(&iaxsl[fr->callno]); 07617 return 1; 07618 } 07619 07620 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07621 if (!strcmp(ies.called_number, ast_parking_ext())) { 07622 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07623 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07624 } else { 07625 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07626 } 07627 } else { 07628 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07629 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07630 ies.called_number, iaxs[fr->callno]->context); 07631 else 07632 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07633 ies.called_number, iaxs[fr->callno]->context); 07634 } 07635 } else 07636 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07637 07638 break; 07639 } 07640 case IAX_COMMAND_ACCEPT: 07641 /* Ignore if call is already up or needs authentication or is a TBD */ 07642 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07643 break; 07644 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07645 /* Send ack immediately, before we destroy */ 07646 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07647 iax2_destroy(fr->callno); 07648 break; 07649 } 07650 if (ies.format) { 07651 iaxs[fr->callno]->peerformat = ies.format; 07652 } else { 07653 if (iaxs[fr->callno]->owner) 07654 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07655 else 07656 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07657 } 07658 if (option_verbose > 2) 07659 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)); 07660 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07661 memset(&ied0, 0, sizeof(ied0)); 07662 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07663 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07664 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07665 if (!iaxs[fr->callno]) { 07666 ast_mutex_unlock(&iaxsl[fr->callno]); 07667 return 1; 07668 } 07669 if (authdebug) 07670 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); 07671 } else { 07672 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07673 if (iaxs[fr->callno]->owner) { 07674 /* Switch us to use a compatible format */ 07675 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07676 if (option_verbose > 2) 07677 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07678 retryowner2: 07679 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07680 ast_mutex_unlock(&iaxsl[fr->callno]); 07681 usleep(1); 07682 ast_mutex_lock(&iaxsl[fr->callno]); 07683 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07684 } 07685 07686 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07687 /* Setup read/write formats properly. */ 07688 if (iaxs[fr->callno]->owner->writeformat) 07689 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07690 if (iaxs[fr->callno]->owner->readformat) 07691 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07692 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07693 } 07694 } 07695 } 07696 if (iaxs[fr->callno]) { 07697 ast_mutex_lock(&dpcache_lock); 07698 dp = iaxs[fr->callno]->dpentries; 07699 while(dp) { 07700 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07701 iax2_dprequest(dp, fr->callno); 07702 } 07703 dp = dp->peer; 07704 } 07705 ast_mutex_unlock(&dpcache_lock); 07706 } 07707 break; 07708 case IAX_COMMAND_POKE: 07709 /* Send back a pong packet with the original timestamp */ 07710 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07711 if (!iaxs[fr->callno]) { 07712 ast_mutex_unlock(&iaxsl[fr->callno]); 07713 return 1; 07714 } 07715 break; 07716 case IAX_COMMAND_PING: 07717 { 07718 struct iax_ie_data pingied; 07719 construct_rr(iaxs[fr->callno], &pingied); 07720 /* Send back a pong packet with the original timestamp */ 07721 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07722 } 07723 break; 07724 case IAX_COMMAND_PONG: 07725 /* Calculate ping time */ 07726 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07727 /* save RR info */ 07728 save_rr(fr, &ies); 07729 07730 if (iaxs[fr->callno]->peerpoke) { 07731 peer = iaxs[fr->callno]->peerpoke; 07732 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07733 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07734 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07735 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07736 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07737 } 07738 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07739 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07740 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07741 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07742 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07743 } 07744 } 07745 peer->lastms = iaxs[fr->callno]->pingtime; 07746 if (peer->smoothing && (peer->lastms > -1)) 07747 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07748 else if (peer->smoothing && peer->lastms < 0) 07749 peer->historicms = (0 + peer->historicms) / 2; 07750 else 07751 peer->historicms = iaxs[fr->callno]->pingtime; 07752 07753 /* Remove scheduled iax2_poke_noanswer */ 07754 if (peer->pokeexpire > -1) { 07755 if (!ast_sched_del(sched, peer->pokeexpire)) { 07756 peer_unref(peer); 07757 peer->pokeexpire = -1; 07758 } 07759 } 07760 /* Schedule the next cycle */ 07761 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07762 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07763 else 07764 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07765 if (peer->pokeexpire == -1) 07766 peer_unref(peer); 07767 /* and finally send the ack */ 07768 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07769 /* And wrap up the qualify call */ 07770 iax2_destroy(fr->callno); 07771 peer->callno = 0; 07772 if (option_debug) 07773 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07774 } 07775 break; 07776 case IAX_COMMAND_LAGRQ: 07777 case IAX_COMMAND_LAGRP: 07778 f.src = "LAGRQ"; 07779 f.mallocd = 0; 07780 f.offset = 0; 07781 f.samples = 0; 07782 iax_frame_wrap(fr, &f); 07783 if(f.subclass == IAX_COMMAND_LAGRQ) { 07784 /* Received a LAGRQ - echo back a LAGRP */ 07785 fr->af.subclass = IAX_COMMAND_LAGRP; 07786 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07787 } else { 07788 /* Received LAGRP in response to our LAGRQ */ 07789 unsigned int ts; 07790 /* This is a reply we've been given, actually measure the difference */ 07791 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07792 iaxs[fr->callno]->lag = ts - fr->ts; 07793 if (option_debug && iaxdebug) 07794 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07795 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07796 } 07797 break; 07798 case IAX_COMMAND_AUTHREQ: 07799 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07800 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>"); 07801 break; 07802 } 07803 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07804 ast_log(LOG_WARNING, 07805 "I don't know how to authenticate %s to %s\n", 07806 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07807 } 07808 if (!iaxs[fr->callno]) { 07809 ast_mutex_unlock(&iaxsl[fr->callno]); 07810 return 1; 07811 } 07812 break; 07813 case IAX_COMMAND_AUTHREP: 07814 /* For security, always ack immediately */ 07815 if (delayreject) 07816 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07817 /* Ignore once we've started */ 07818 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07819 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>"); 07820 break; 07821 } 07822 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07823 if (authdebug) 07824 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); 07825 memset(&ied0, 0, sizeof(ied0)); 07826 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07827 break; 07828 } 07829 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07830 /* This might re-enter the IAX code and need the lock */ 07831 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07832 } else 07833 exists = 0; 07834 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07835 if (authdebug) 07836 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); 07837 memset(&ied0, 0, sizeof(ied0)); 07838 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07839 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07840 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07841 if (!iaxs[fr->callno]) { 07842 ast_mutex_unlock(&iaxsl[fr->callno]); 07843 return 1; 07844 } 07845 } else { 07846 /* Select an appropriate format */ 07847 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07848 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07849 using_prefs = "reqonly"; 07850 } else { 07851 using_prefs = "disabled"; 07852 } 07853 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07854 memset(&pref, 0, sizeof(pref)); 07855 strcpy(caller_pref_buf, "disabled"); 07856 strcpy(host_pref_buf, "disabled"); 07857 } else { 07858 using_prefs = "mine"; 07859 if (ies.codec_prefs) 07860 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07861 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07862 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07863 pref = iaxs[fr->callno]->rprefs; 07864 using_prefs = "caller"; 07865 } else { 07866 pref = iaxs[fr->callno]->prefs; 07867 } 07868 } else /* if no codec_prefs IE do it the old way */ 07869 pref = iaxs[fr->callno]->prefs; 07870 07871 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07872 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07873 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07874 } 07875 if (!format) { 07876 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07877 if (option_debug) 07878 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); 07879 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07880 } 07881 if (!format) { 07882 if (authdebug) { 07883 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07884 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); 07885 else 07886 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); 07887 } 07888 memset(&ied0, 0, sizeof(ied0)); 07889 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07890 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07891 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07892 if (!iaxs[fr->callno]) { 07893 ast_mutex_unlock(&iaxsl[fr->callno]); 07894 return 1; 07895 } 07896 } else { 07897 /* Pick one... */ 07898 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07899 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07900 format = 0; 07901 } else { 07902 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07903 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07904 memset(&pref, 0, sizeof(pref)); 07905 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07906 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07907 strcpy(caller_pref_buf,"disabled"); 07908 strcpy(host_pref_buf,"disabled"); 07909 } else { 07910 using_prefs = "mine"; 07911 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07912 /* Do the opposite of what we tried above. */ 07913 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07914 pref = iaxs[fr->callno]->prefs; 07915 } else { 07916 pref = iaxs[fr->callno]->rprefs; 07917 using_prefs = "caller"; 07918 } 07919 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07920 } else /* if no codec_prefs IE do it the old way */ 07921 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07922 } 07923 } 07924 if (!format) { 07925 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07926 if (authdebug) { 07927 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07928 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); 07929 else 07930 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); 07931 } 07932 memset(&ied0, 0, sizeof(ied0)); 07933 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07934 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07935 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07936 if (!iaxs[fr->callno]) { 07937 ast_mutex_unlock(&iaxsl[fr->callno]); 07938 return 1; 07939 } 07940 } 07941 } 07942 } 07943 if (format) { 07944 /* Authentication received */ 07945 memset(&ied1, 0, sizeof(ied1)); 07946 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07947 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07948 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07949 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07950 if (option_verbose > 2) 07951 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07952 "%srequested format = %s,\n" 07953 "%srequested prefs = %s,\n" 07954 "%sactual format = %s,\n" 07955 "%shost prefs = %s,\n" 07956 "%spriority = %s\n", 07957 ast_inet_ntoa(sin.sin_addr), 07958 VERBOSE_PREFIX_4, 07959 ast_getformatname(iaxs[fr->callno]->peerformat), 07960 VERBOSE_PREFIX_4, 07961 caller_pref_buf, 07962 VERBOSE_PREFIX_4, 07963 ast_getformatname(format), 07964 VERBOSE_PREFIX_4, 07965 host_pref_buf, 07966 VERBOSE_PREFIX_4, 07967 using_prefs); 07968 07969 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07970 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07971 iax2_destroy(fr->callno); 07972 } else { 07973 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07974 /* If this is a TBD call, we're ready but now what... */ 07975 if (option_verbose > 2) 07976 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07977 } 07978 } 07979 } 07980 break; 07981 case IAX_COMMAND_DIAL: 07982 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07983 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07984 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07985 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07986 if (authdebug) 07987 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); 07988 memset(&ied0, 0, sizeof(ied0)); 07989 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07990 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07991 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07992 if (!iaxs[fr->callno]) { 07993 ast_mutex_unlock(&iaxsl[fr->callno]); 07994 return 1; 07995 } 07996 } else { 07997 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07998 if (option_verbose > 2) 07999 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08000 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08001 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08002 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08003 iax2_destroy(fr->callno); 08004 } 08005 } 08006 break; 08007 case IAX_COMMAND_INVAL: 08008 iaxs[fr->callno]->error = ENOTCONN; 08009 if (option_debug) 08010 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08011 iax2_destroy(fr->callno); 08012 if (option_debug) 08013 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08014 break; 08015 case IAX_COMMAND_VNAK: 08016 if (option_debug) 08017 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08018 /* Force retransmission */ 08019 vnak_retransmit(fr->callno, fr->iseqno); 08020 break; 08021 case IAX_COMMAND_REGREQ: 08022 case IAX_COMMAND_REGREL: 08023 /* For security, always ack immediately */ 08024 if (delayreject) 08025 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08026 if (register_verify(fr->callno, &sin, &ies)) { 08027 if (!iaxs[fr->callno]) { 08028 ast_mutex_unlock(&iaxsl[fr->callno]); 08029 return 1; 08030 } 08031 /* Send delayed failure */ 08032 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08033 break; 08034 } 08035 if (!iaxs[fr->callno]) { 08036 ast_mutex_unlock(&iaxsl[fr->callno]); 08037 return 1; 08038 } 08039 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08040 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08041 if (f.subclass == IAX_COMMAND_REGREL) 08042 memset(&sin, 0, sizeof(sin)); 08043 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08044 ast_log(LOG_WARNING, "Registry error\n"); 08045 if (!iaxs[fr->callno]) { 08046 ast_mutex_unlock(&iaxsl[fr->callno]); 08047 return 1; 08048 } 08049 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08050 ast_mutex_unlock(&iaxsl[fr->callno]); 08051 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08052 ast_mutex_lock(&iaxsl[fr->callno]); 08053 if (!iaxs[fr->callno]) { 08054 ast_mutex_unlock(&iaxsl[fr->callno]); 08055 return 1; 08056 } 08057 } 08058 break; 08059 } 08060 registry_authrequest(fr->callno); 08061 if (!iaxs[fr->callno]) { 08062 ast_mutex_unlock(&iaxsl[fr->callno]); 08063 return 1; 08064 } 08065 break; 08066 case IAX_COMMAND_REGACK: 08067 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08068 ast_log(LOG_WARNING, "Registration failure\n"); 08069 /* Send ack immediately, before we destroy */ 08070 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08071 iax2_destroy(fr->callno); 08072 break; 08073 case IAX_COMMAND_REGREJ: 08074 if (iaxs[fr->callno]->reg) { 08075 if (authdebug) { 08076 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)); 08077 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>"); 08078 } 08079 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08080 } 08081 /* Send ack immediately, before we destroy */ 08082 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08083 iax2_destroy(fr->callno); 08084 break; 08085 case IAX_COMMAND_REGAUTH: 08086 /* Authentication request */ 08087 if (registry_rerequest(&ies, fr->callno, &sin)) { 08088 memset(&ied0, 0, sizeof(ied0)); 08089 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08090 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08091 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08092 if (!iaxs[fr->callno]) { 08093 ast_mutex_unlock(&iaxsl[fr->callno]); 08094 return 1; 08095 } 08096 } 08097 break; 08098 case IAX_COMMAND_TXREJ: 08099 iaxs[fr->callno]->transferring = 0; 08100 if (option_verbose > 2) 08101 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08102 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08103 if (iaxs[fr->callno]->bridgecallno) { 08104 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08105 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08106 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08107 } 08108 } 08109 break; 08110 case IAX_COMMAND_TXREADY: 08111 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08112 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08113 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08114 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08115 else 08116 iaxs[fr->callno]->transferring = TRANSFER_READY; 08117 if (option_verbose > 2) 08118 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08119 if (iaxs[fr->callno]->bridgecallno) { 08120 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08121 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08122 /* They're both ready, now release them. */ 08123 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08124 if (option_verbose > 2) 08125 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08126 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08127 08128 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08129 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08130 08131 memset(&ied0, 0, sizeof(ied0)); 08132 memset(&ied1, 0, sizeof(ied1)); 08133 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08134 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08135 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08136 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08137 } else { 08138 if (option_verbose > 2) 08139 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08140 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08141 08142 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08143 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08144 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08145 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08146 08147 /* Stop doing lag & ping requests */ 08148 stop_stuff(fr->callno); 08149 stop_stuff(iaxs[fr->callno]->bridgecallno); 08150 08151 memset(&ied0, 0, sizeof(ied0)); 08152 memset(&ied1, 0, sizeof(ied1)); 08153 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08154 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08155 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08156 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08157 } 08158 08159 } 08160 } 08161 } 08162 break; 08163 case IAX_COMMAND_TXREQ: 08164 try_transfer(iaxs[fr->callno], &ies); 08165 break; 08166 case IAX_COMMAND_TXCNT: 08167 if (iaxs[fr->callno]->transferring) 08168 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08169 break; 08170 case IAX_COMMAND_TXREL: 08171 /* Send ack immediately, rather than waiting until we've changed addresses */ 08172 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08173 complete_transfer(fr->callno, &ies); 08174 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08175 break; 08176 case IAX_COMMAND_TXMEDIA: 08177 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08178 AST_LIST_LOCK(&iaxq.queue); 08179 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08180 /* Cancel any outstanding frames and start anew */ 08181 if ((fr->callno == cur->callno) && (cur->transfer)) { 08182 cur->retries = -1; 08183 } 08184 } 08185 AST_LIST_UNLOCK(&iaxq.queue); 08186 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08187 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08188 } 08189 break; 08190 case IAX_COMMAND_DPREP: 08191 complete_dpreply(iaxs[fr->callno], &ies); 08192 break; 08193 case IAX_COMMAND_UNSUPPORT: 08194 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08195 break; 08196 case IAX_COMMAND_FWDOWNL: 08197 /* Firmware download */ 08198 memset(&ied0, 0, sizeof(ied0)); 08199 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08200 if (res < 0) 08201 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08202 else if (res > 0) 08203 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08204 else 08205 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08206 if (!iaxs[fr->callno]) { 08207 ast_mutex_unlock(&iaxsl[fr->callno]); 08208 return 1; 08209 } 08210 break; 08211 default: 08212 if (option_debug) 08213 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08214 memset(&ied0, 0, sizeof(ied0)); 08215 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08216 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08217 } 08218 /* Don't actually pass these frames along */ 08219 if ((f.subclass != IAX_COMMAND_ACK) && 08220 (f.subclass != IAX_COMMAND_TXCNT) && 08221 (f.subclass != IAX_COMMAND_TXACC) && 08222 (f.subclass != IAX_COMMAND_INVAL) && 08223 (f.subclass != IAX_COMMAND_VNAK)) { 08224 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08225 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08226 } 08227 ast_mutex_unlock(&iaxsl[fr->callno]); 08228 return 1; 08229 } 08230 /* Unless this is an ACK or INVAL frame, ack it */ 08231 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08232 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08233 } else if (minivid) { 08234 f.frametype = AST_FRAME_VIDEO; 08235 if (iaxs[fr->callno]->videoformat > 0) 08236 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08237 else { 08238 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08239 iax2_vnak(fr->callno); 08240 ast_mutex_unlock(&iaxsl[fr->callno]); 08241 return 1; 08242 } 08243 f.datalen = res - sizeof(*vh); 08244 if (f.datalen) 08245 f.data = thread->buf + sizeof(*vh); 08246 else 08247 f.data = NULL; 08248 #ifdef IAXTESTS 08249 if (test_resync) { 08250 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08251 } else 08252 #endif /* IAXTESTS */ 08253 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08254 } else { 08255 /* A mini frame */ 08256 f.frametype = AST_FRAME_VOICE; 08257 if (iaxs[fr->callno]->voiceformat > 0) 08258 f.subclass = iaxs[fr->callno]->voiceformat; 08259 else { 08260 if (option_debug) 08261 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08262 iax2_vnak(fr->callno); 08263 ast_mutex_unlock(&iaxsl[fr->callno]); 08264 return 1; 08265 } 08266 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08267 if (f.datalen < 0) { 08268 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08269 ast_mutex_unlock(&iaxsl[fr->callno]); 08270 return 1; 08271 } 08272 if (f.datalen) 08273 f.data = thread->buf + sizeof(*mh); 08274 else 08275 f.data = NULL; 08276 #ifdef IAXTESTS 08277 if (test_resync) { 08278 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08279 } else 08280 #endif /* IAXTESTS */ 08281 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08282 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08283 } 08284 /* Don't pass any packets until we're started */ 08285 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08286 ast_mutex_unlock(&iaxsl[fr->callno]); 08287 return 1; 08288 } 08289 /* Common things */ 08290 f.src = "IAX2"; 08291 f.mallocd = 0; 08292 f.offset = 0; 08293 f.len = 0; 08294 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08295 f.samples = ast_codec_get_samples(&f); 08296 /* We need to byteswap incoming slinear samples from network byte order */ 08297 if (f.subclass == AST_FORMAT_SLINEAR) 08298 ast_frame_byteswap_be(&f); 08299 } else 08300 f.samples = 0; 08301 iax_frame_wrap(fr, &f); 08302 08303 /* If this is our most recent packet, use it as our basis for timestamping */ 08304 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08305 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08306 fr->outoforder = 0; 08307 } else { 08308 if (option_debug && iaxdebug && iaxs[fr->callno]) 08309 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); 08310 fr->outoforder = -1; 08311 } 08312 duped_fr = iaxfrdup2(fr); 08313 if (duped_fr) { 08314 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08315 } 08316 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08317 iaxs[fr->callno]->last = fr->ts; 08318 #if 1 08319 if (option_debug && iaxdebug) 08320 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08321 #endif 08322 } 08323 08324 /* Always run again */ 08325 ast_mutex_unlock(&iaxsl[fr->callno]); 08326 return 1; 08327 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6729 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06730 { 06731 struct iax2_thread *thread; 06732 socklen_t len; 06733 time_t t; 06734 static time_t last_errtime = 0; 06735 struct ast_iax2_full_hdr *fh; 06736 06737 if (!(thread = find_idle_thread())) { 06738 time(&t); 06739 if (t != last_errtime && option_debug) 06740 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06741 last_errtime = t; 06742 usleep(1); 06743 return 1; 06744 } 06745 06746 len = sizeof(thread->iosin); 06747 thread->iofd = fd; 06748 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06749 thread->buf_size = sizeof(thread->readbuf); 06750 thread->buf = thread->readbuf; 06751 if (thread->buf_len < 0) { 06752 if (errno != ECONNREFUSED && errno != EAGAIN) 06753 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06754 handle_error(); 06755 thread->iostate = IAX_IOSTATE_IDLE; 06756 signal_condition(&thread->lock, &thread->cond); 06757 return 1; 06758 } 06759 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06760 thread->iostate = IAX_IOSTATE_IDLE; 06761 signal_condition(&thread->lock, &thread->cond); 06762 return 1; 06763 } 06764 06765 /* Determine if this frame is a full frame; if so, and any thread is currently 06766 processing a full frame for the same callno from this peer, then drop this 06767 frame (and the peer will retransmit it) */ 06768 fh = (struct ast_iax2_full_hdr *) thread->buf; 06769 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06770 struct iax2_thread *cur = NULL; 06771 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06772 06773 AST_LIST_LOCK(&active_list); 06774 AST_LIST_TRAVERSE(&active_list, cur, list) { 06775 if ((cur->ffinfo.callno == callno) && 06776 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06777 break; 06778 } 06779 if (cur) { 06780 /* we found another thread processing a full frame for this call, 06781 so queue it up for processing later. */ 06782 defer_full_frame(thread, cur); 06783 AST_LIST_UNLOCK(&active_list); 06784 thread->iostate = IAX_IOSTATE_IDLE; 06785 signal_condition(&thread->lock, &thread->cond); 06786 return 1; 06787 } else { 06788 /* this thread is going to process this frame, so mark it */ 06789 thread->ffinfo.callno = callno; 06790 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06791 thread->ffinfo.type = fh->type; 06792 thread->ffinfo.csub = fh->csub; 06793 } 06794 AST_LIST_UNLOCK(&active_list); 06795 } 06796 06797 /* Mark as ready and send on its way */ 06798 thread->iostate = IAX_IOSTATE_READY; 06799 #ifdef DEBUG_SCHED_MULTITHREAD 06800 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06801 #endif 06802 signal_condition(&thread->lock, &thread->cond); 06803 06804 return 1; 06805 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6516 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06517 { 06518 pthread_t newthread; 06519 struct dpreq_data *dpr; 06520 pthread_attr_t attr; 06521 06522 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06523 return; 06524 06525 pthread_attr_init(&attr); 06526 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06527 06528 dpr->callno = callno; 06529 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06530 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06531 if (callerid) 06532 dpr->callerid = ast_strdup(callerid); 06533 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06534 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06535 } 06536 06537 pthread_attr_destroy(&attr); 06538 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8922 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().
08923 { 08924 pthread_attr_t attr; 08925 int threadcount = 0; 08926 int x; 08927 for (x = 0; x < iaxthreadcount; x++) { 08928 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08929 if (thread) { 08930 thread->type = IAX_TYPE_POOL; 08931 thread->threadnum = ++threadcount; 08932 ast_mutex_init(&thread->lock); 08933 ast_cond_init(&thread->cond, NULL); 08934 pthread_attr_init(&attr); 08935 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08936 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08937 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08938 free(thread); 08939 thread = NULL; 08940 } 08941 AST_LIST_LOCK(&idle_list); 08942 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08943 AST_LIST_UNLOCK(&idle_list); 08944 } 08945 } 08946 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08947 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08948 if (option_verbose > 1) 08949 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08950 return 0; 08951 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6198 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06199 { 06200 iax2_destroy_helper(iaxs[callno]); 06201 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6385 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06386 { 06387 char buf[1024]; 06388 int res; 06389 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06390 int processed = 0; 06391 int totalcalls = 0; 06392 #ifdef ZT_TIMERACK 06393 int x = 1; 06394 #endif 06395 struct timeval now; 06396 if (iaxtrunkdebug) 06397 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06398 gettimeofday(&now, NULL); 06399 if (events & AST_IO_PRI) { 06400 #ifdef ZT_TIMERACK 06401 /* Great, this is a timing interface, just call the ioctl */ 06402 if (ioctl(fd, ZT_TIMERACK, &x)) { 06403 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06404 usleep(1); 06405 return -1; 06406 } 06407 #endif 06408 } else { 06409 /* Read and ignore from the pseudo channel for timing */ 06410 res = read(fd, buf, sizeof(buf)); 06411 if (res < 1) { 06412 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06413 return 1; 06414 } 06415 } 06416 /* For each peer that supports trunking... */ 06417 ast_mutex_lock(&tpeerlock); 06418 tpeer = tpeers; 06419 while(tpeer) { 06420 processed++; 06421 res = 0; 06422 ast_mutex_lock(&tpeer->lock); 06423 /* We can drop a single tpeer per pass. That makes all this logic 06424 substantially easier */ 06425 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06426 /* Take it out of the list, but don't free it yet, because it 06427 could be in use */ 06428 if (prev) 06429 prev->next = tpeer->next; 06430 else 06431 tpeers = tpeer->next; 06432 drop = tpeer; 06433 } else { 06434 res = send_trunk(tpeer, &now); 06435 if (iaxtrunkdebug) 06436 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); 06437 } 06438 totalcalls += res; 06439 res = 0; 06440 ast_mutex_unlock(&tpeer->lock); 06441 prev = tpeer; 06442 tpeer = tpeer->next; 06443 } 06444 ast_mutex_unlock(&tpeerlock); 06445 if (drop) { 06446 ast_mutex_lock(&drop->lock); 06447 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06448 because by the time they could get tpeerlock, we've already grabbed it */ 06449 if (option_debug) 06450 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06451 if (drop->trunkdata) { 06452 free(drop->trunkdata); 06453 drop->trunkdata = NULL; 06454 } 06455 ast_mutex_unlock(&drop->lock); 06456 ast_mutex_destroy(&drop->lock); 06457 free(drop); 06458 06459 } 06460 if (iaxtrunkdebug) 06461 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06462 iaxtrunkdebug =0; 06463 return 1; 06464 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1846 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01847 { 01848 int res; 01849 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01850 sizeof(*sin)); 01851 if (res < 0) { 01852 if (option_debug) 01853 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01854 handle_error(); 01855 } else 01856 res = 0; 01857 return res; 01858 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1534 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, len, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01535 { 01536 struct stat stbuf; 01537 struct iax_firmware *cur; 01538 int ifd; 01539 int fd; 01540 int res; 01541 01542 struct ast_iax2_firmware_header *fwh, fwh2; 01543 struct MD5Context md5; 01544 unsigned char sum[16]; 01545 unsigned char buf[1024]; 01546 int len, chunk; 01547 char *s2; 01548 char *last; 01549 s2 = alloca(strlen(s) + 100); 01550 if (!s2) { 01551 ast_log(LOG_WARNING, "Alloca failed!\n"); 01552 return -1; 01553 } 01554 last = strrchr(s, '/'); 01555 if (last) 01556 last++; 01557 else 01558 last = s; 01559 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01560 res = stat(s, &stbuf); 01561 if (res < 0) { 01562 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01563 return -1; 01564 } 01565 /* Make sure it's not a directory */ 01566 if (S_ISDIR(stbuf.st_mode)) 01567 return -1; 01568 ifd = open(s, O_RDONLY); 01569 if (ifd < 0) { 01570 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01571 return -1; 01572 } 01573 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01574 if (fd < 0) { 01575 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01576 close(ifd); 01577 return -1; 01578 } 01579 /* Unlink our newly created file */ 01580 unlink(s2); 01581 01582 /* Now copy the firmware into it */ 01583 len = stbuf.st_size; 01584 while(len) { 01585 chunk = len; 01586 if (chunk > sizeof(buf)) 01587 chunk = sizeof(buf); 01588 res = read(ifd, buf, chunk); 01589 if (res != chunk) { 01590 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01591 close(ifd); 01592 close(fd); 01593 return -1; 01594 } 01595 res = write(fd, buf, chunk); 01596 if (res != chunk) { 01597 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01598 close(ifd); 01599 close(fd); 01600 return -1; 01601 } 01602 len -= chunk; 01603 } 01604 close(ifd); 01605 /* Return to the beginning */ 01606 lseek(fd, 0, SEEK_SET); 01607 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01608 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01609 close(fd); 01610 return -1; 01611 } 01612 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01613 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01614 close(fd); 01615 return -1; 01616 } 01617 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01618 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01619 close(fd); 01620 return -1; 01621 } 01622 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01623 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01624 close(fd); 01625 return -1; 01626 } 01627 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01628 if (fwh == (void *) -1) { 01629 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01630 close(fd); 01631 return -1; 01632 } 01633 MD5Init(&md5); 01634 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01635 MD5Final(sum, &md5); 01636 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01637 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01638 munmap((void*)fwh, stbuf.st_size); 01639 close(fd); 01640 return -1; 01641 } 01642 cur = waresl.wares; 01643 while(cur) { 01644 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01645 /* Found a candidate */ 01646 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01647 /* The version we have on loaded is older, load this one instead */ 01648 break; 01649 /* This version is no newer than what we have. Don't worry about it. 01650 We'll consider it a proper load anyhow though */ 01651 munmap((void*)fwh, stbuf.st_size); 01652 close(fd); 01653 return 0; 01654 } 01655 cur = cur->next; 01656 } 01657 if (!cur) { 01658 /* Allocate a new one and link it */ 01659 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01660 cur->fd = -1; 01661 cur->next = waresl.wares; 01662 waresl.wares = cur; 01663 } 01664 } 01665 if (cur) { 01666 if (cur->fwh) { 01667 munmap((void*)cur->fwh, cur->mmaplen); 01668 } 01669 if (cur->fd > -1) 01670 close(cur->fd); 01671 cur->fwh = fwh; 01672 cur->fd = fd; 01673 cur->mmaplen = stbuf.st_size; 01674 cur->dead = 0; 01675 } 01676 return 0; 01677 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5606 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05607 { 05608 int newcall = 0; 05609 char newip[256]; 05610 struct iax_ie_data ied; 05611 struct sockaddr_in new; 05612 05613 05614 memset(&ied, 0, sizeof(ied)); 05615 if (ies->apparent_addr) 05616 bcopy(ies->apparent_addr, &new, sizeof(new)); 05617 if (ies->callno) 05618 newcall = ies->callno; 05619 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05620 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05621 return -1; 05622 } 05623 pvt->transfercallno = newcall; 05624 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05625 inet_aton(newip, &pvt->transfer.sin_addr); 05626 pvt->transfer.sin_family = AF_INET; 05627 pvt->transferring = TRANSFER_BEGIN; 05628 pvt->transferid = ies->transferid; 05629 if (ies->transferid) 05630 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05631 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05632 return 0; 05633 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1056 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01057 { 01058 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01059 if (csub & IAX_FLAG_SC_LOG) { 01060 /* special case for 'compressed' -1 */ 01061 if (csub == 0xff) 01062 return -1; 01063 else 01064 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01065 } 01066 else 01067 return csub; 01068 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 5872 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
05873 { 05874 if (peer->expire > -1) { 05875 if (!ast_sched_del(sched, peer->expire)) { 05876 peer->expire = -1; 05877 peer_unref(peer); 05878 } 05879 } 05880 05881 if (peer->pokeexpire > -1) { 05882 if (!ast_sched_del(sched, peer->pokeexpire)) { 05883 peer->pokeexpire = -1; 05884 peer_unref(peer); 05885 } 05886 } 05887 05888 ao2_unlink(peers, peer); 05889 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10842 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
10843 { 10844 ast_custom_function_unregister(&iaxpeer_function); 10845 return __unload_module(); 10846 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3355 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03356 { 03357 ast_mutex_unlock(&iaxsl[callno1]); 03358 ast_mutex_unlock(&iaxsl[callno0]); 03359 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2384 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().
02385 { 02386 int x; 02387 02388 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02389 x = fr->ts - iaxs[fr->callno]->last; 02390 if (x < -50000) { 02391 /* Sudden big jump backwards in timestamp: 02392 What likely happened here is that miniframe timestamp has circled but we haven't 02393 gotten the update from the main packet. We'll just pretend that we did, and 02394 update the timestamp appropriately. */ 02395 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02396 if (option_debug && iaxdebug) 02397 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02398 } 02399 if (x > 50000) { 02400 /* Sudden apparent big jump forwards in timestamp: 02401 What's likely happened is this is an old miniframe belonging to the previous 02402 top-16-bit timestamp that has turned up out of order. 02403 Adjust the timestamp appropriately. */ 02404 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02405 if (option_debug && iaxdebug) 02406 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02407 } 02408 } 02409 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2413 of file chan_iax2.c.
References AST_SCHED_DEL, chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
02414 { 02415 int when; 02416 02417 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02418 02419 when = jb_next(pvt->jb) - when; 02420 02421 AST_SCHED_DEL(sched, pvt->jbid); 02422 02423 if(when <= 0) { 02424 /* XXX should really just empty until when > 0.. */ 02425 when = 1; 02426 } 02427 02428 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02429 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1276 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno().
01277 { 01278 int max = 1; 01279 int x; 01280 /* XXX Prolly don't need locks here XXX */ 01281 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01282 if (iaxs[x]) 01283 max = x + 1; 01284 } 01285 maxnontrunkcall = max; 01286 if (option_debug && iaxdebug) 01287 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01288 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1262 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy().
01263 { 01264 int max = TRUNK_CALL_START; 01265 int x; 01266 /* XXX Prolly don't need locks here XXX */ 01267 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01268 if (iaxs[x]) 01269 max = x + 1; 01270 } 01271 maxtrunkcall = max; 01272 if (option_debug && iaxdebug) 01273 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01274 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2021 of file chan_iax2.c.
References ast_iax2_full_hdr::dcallno, f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
02022 { 02023 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02024 struct ast_iax2_full_hdr *fh = f->data; 02025 /* Mark this as a retransmission */ 02026 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02027 /* Update iseqno */ 02028 f->iseqno = iaxs[f->callno]->iseqno; 02029 fh->iseqno = f->iseqno; 02030 return 0; 02031 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5983 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, peer_ref(), peer_unref(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05984 { 05985 /* Called from IAX thread only, with proper iaxsl lock */ 05986 struct iax_ie_data ied; 05987 struct iax2_peer *p; 05988 int msgcount; 05989 char data[80]; 05990 int version; 05991 const char *peer_name; 05992 int res = -1; 05993 05994 memset(&ied, 0, sizeof(ied)); 05995 05996 peer_name = ast_strdupa(iaxs[callno]->peer); 05997 05998 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05999 ast_mutex_unlock(&iaxsl[callno]); 06000 if (!(p = find_peer(peer_name, 1))) { 06001 ast_mutex_lock(&iaxsl[callno]); 06002 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06003 return -1; 06004 } 06005 ast_mutex_lock(&iaxsl[callno]); 06006 if (!iaxs[callno]) 06007 goto return_unref; 06008 06009 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06010 if (sin->sin_addr.s_addr) { 06011 time_t nowtime; 06012 time(&nowtime); 06013 realtime_update_peer(peer_name, sin, nowtime); 06014 } else { 06015 realtime_update_peer(peer_name, sin, 0); 06016 } 06017 } 06018 if (inaddrcmp(&p->addr, sin)) { 06019 if (iax2_regfunk) 06020 iax2_regfunk(p->name, 1); 06021 /* Stash the IP address from which they registered */ 06022 memcpy(&p->addr, sin, sizeof(p->addr)); 06023 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06024 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06025 ast_db_put("IAX/Registry", p->name, data); 06026 if (option_verbose > 2) 06027 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06028 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06029 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06030 register_peer_exten(p, 1); 06031 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06032 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06033 if (option_verbose > 2) 06034 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06035 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06036 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06037 register_peer_exten(p, 0); 06038 ast_db_del("IAX/Registry", p->name); 06039 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06040 } 06041 /* Update the host */ 06042 /* Verify that the host is really there */ 06043 iax2_poke_peer(p, callno); 06044 } 06045 06046 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06047 if (!iaxs[callno]) { 06048 res = 0; 06049 goto return_unref; 06050 } 06051 06052 /* Store socket fd */ 06053 p->sockfd = fd; 06054 /* Setup the expiry */ 06055 if (p->expire > -1) { 06056 if (!ast_sched_del(sched, p->expire)) { 06057 p->expire = -1; 06058 peer_unref(p); 06059 } 06060 } 06061 /* treat an unspecified refresh interval as the minimum */ 06062 if (!refresh) 06063 refresh = min_reg_expire; 06064 if (refresh > max_reg_expire) { 06065 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06066 p->name, max_reg_expire, refresh); 06067 p->expiry = max_reg_expire; 06068 } else if (refresh < min_reg_expire) { 06069 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06070 p->name, min_reg_expire, refresh); 06071 p->expiry = min_reg_expire; 06072 } else { 06073 p->expiry = refresh; 06074 } 06075 if (p->expiry && sin->sin_addr.s_addr) { 06076 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06077 if (p->expire == -1) 06078 peer_unref(p); 06079 } 06080 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06081 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06082 if (sin->sin_addr.s_addr) { 06083 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06084 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06085 if (!ast_strlen_zero(p->mailbox)) { 06086 int new, old; 06087 ast_app_inboxcount(p->mailbox, &new, &old); 06088 if (new > 255) 06089 new = 255; 06090 if (old > 255) 06091 old = 255; 06092 msgcount = (old << 8) | new; 06093 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06094 } 06095 if (ast_test_flag(p, IAX_HASCALLERID)) { 06096 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06097 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06098 } 06099 } 06100 version = iax_check_version(devtype); 06101 if (version) 06102 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06103 06104 res = 0; 06105 06106 return_unref: 06107 peer_unref(p); 06108 06109 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06110 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1103 of file chan_iax2.c.
Referenced by load_module().
01104 { 01105 struct iax2_user *user = obj, *user2 = arg; 01106 01107 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01108 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9562 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09563 { 09564 struct iax2_user *user = obj; 09565 09566 ast_set_flag(user, IAX_DELME); 09567 09568 return 0; 09569 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9326 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().
09327 { 09328 struct iax2_user *user = obj; 09329 09330 ast_free_ha(user->ha); 09331 free_context(user->contexts); 09332 if(user->vars) { 09333 ast_variables_destroy(user->vars); 09334 user->vars = NULL; 09335 } 09336 ast_string_field_free_memory(user); 09337 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1093 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01094 { 01095 const struct iax2_user *user = obj; 01096 01097 return ast_str_hash(user->name); 01098 }
Definition at line 1142 of file chan_iax2.c.
References ao2_ref().
01143 { 01144 ao2_ref(user, +1); 01145 return user; 01146 }
Definition at line 1148 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().
01149 { 01150 ao2_ref(user, -1); 01151 return NULL; 01152 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6299 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, and send_packet().
Referenced by socket_process().
06300 { 06301 struct iax_frame *f; 06302 06303 AST_LIST_LOCK(&iaxq.queue); 06304 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06305 /* Send a copy immediately */ 06306 if ((f->callno == callno) && iaxs[f->callno] && 06307 ((unsigned char ) (f->oseqno - last) < 128) && 06308 (f->retries >= 0)) { 06309 send_packet(f); 06310 } 06311 } 06312 AST_LIST_UNLOCK(&iaxq.queue); 06313 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 220 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), mysql_log(), sip_new(), skinny_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
int amaflags = 0 [static] |
Definition at line 223 of file chan_iax2.c.
Referenced by build_device(), build_gateway(), and pgsql_log().
int authdebug = 1 [static] |
Definition at line 160 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 161 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 10642 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 10647 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 10657 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 10652 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 10637 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 10611 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 10603 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 10595 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 177 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 225 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 278 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 228 of file chan_iax2.c.
Referenced by __expire_registry(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_callno(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 206 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 226 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 179 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 10553 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 849 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 10619 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 454 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 208 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 164 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 166 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 453 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(), __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(), find_callno(), 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[IAX_MAX_CALLS] [static] |
Definition at line 814 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __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(), find_callno(), 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 451 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 210 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 203 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.
struct timeval lastused[IAX_MAX_CALLS] [static] |
Definition at line 815 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 171 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 156 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 158 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 154 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 170 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 221 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 222 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 175 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 230 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 10615 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 10607 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 10599 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 176 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 8576 of file chan_iax2.c.
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 8578 of file chan_iax2.c.
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(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 152 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 141 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10549 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8577 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 148 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 157 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 204 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 233 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 231 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 10541 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 10569 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 10587 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 10573 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 10545 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 10581 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10557 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 10591 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 10537 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 10577 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 10564 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 212 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 173 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 168 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 159 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(), 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().