#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 "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_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_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#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) } |
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 (void *data) |
static void | __auth_reject (void *nothing) |
static void | __auto_congest (void *nothing) |
static void | __auto_hangup (void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (void *data) |
static void | __get_from_jb (void *p) |
static void | __iax2_do_register_s (void *data) |
static void | __iax2_poke_noanswer (void *data) |
static void | __iax2_poke_peer_s (void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static int | __schedule_action (void(*func)(void *data), 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 (void *data) |
static void | __send_ping (void *data) |
static int | __unload_module (void) |
static int | acf_iaxvar_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | acf_iaxvar_write (struct ast_channel *chan, char *cmd, char *varname, const char *value) |
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 (peers, iax2_peer) |
static | AST_LIST_HEAD_STATIC (users, iax2_user) |
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 (void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (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 (struct chan_iax2_pvt *p) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (void *data) |
static int | auto_hangup (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 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 | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | destroy_peer (struct iax2_peer *peer) |
static void | destroy_user (struct iax2_user *user) |
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 (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 lockpeer, 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 (void *p) |
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 (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, int lockpeer) |
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 (void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_s (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_frame (int callno, struct ast_frame *f) |
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_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, int lockpeer, 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_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 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) |
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 (const char *name, 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 (void) |
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 (void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (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_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 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 (const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
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 ast_custom_function | iaxvar_function |
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 int | ping_time = 20 |
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 ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 642 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 638 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 652 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 640 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 644 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 646 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 648 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 650 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 121 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 109 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 127 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 199 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 198 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 124 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 197 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 123 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 440 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 137 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 180 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 188 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 193 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 182 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
Definition at line 674 of file chan_iax2.c.
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 676 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 680 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 112 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 437 of file chan_iax2.c.
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 443 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 441 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MEMORY_SIZE 100 |
Definition at line 126 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 438 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 1108 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 120 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 105 of file chan_iax2.c.
Definition at line 909 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 130 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 446 of file chan_iax2.c.
anonymous enum |
Definition at line 233 of file chan_iax2.c.
00233 { 00234 IAX_STATE_STARTED = (1 << 0), 00235 IAX_STATE_AUTHENTICATED = (1 << 1), 00236 IAX_STATE_TBD = (1 << 2), 00237 IAX_STATE_UNCHANGED = (1 << 3), 00238 } iax2_state;
anonymous enum |
Definition at line 245 of file chan_iax2.c.
00245 { 00246 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00247 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00248 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00249 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00250 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00251 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00252 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00253 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00254 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00255 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00256 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00257 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00258 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00259 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00260 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00261 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00262 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00263 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00264 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00265 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00266 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00267 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00268 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00269 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00270 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00271 } 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 392 of file chan_iax2.c.
00392 { 00393 REG_STATE_UNREGISTERED = 0, 00394 REG_STATE_REGSENT, 00395 REG_STATE_AUTHSENT, 00396 REG_STATE_REGISTERED, 00397 REG_STATE_REJECTED, 00398 REG_STATE_TIMEOUT, 00399 REG_STATE_NOAUTH 00400 };
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 402 of file chan_iax2.c.
00402 { 00403 TRANSFER_NONE = 0, 00404 TRANSFER_BEGIN, 00405 TRANSFER_READY, 00406 TRANSFER_RELEASED, 00407 TRANSFER_PASSTHROUGH, 00408 TRANSFER_MBEGIN, 00409 TRANSFER_MREADY, 00410 TRANSFER_MRELEASED, 00411 TRANSFER_MPASSTHROUGH, 00412 TRANSFER_MEDIA, 00413 TRANSFER_MEDIAPASS 00414 };
static void __attempt_transmit | ( | void * | data | ) | [static] |
Definition at line 1835 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(), ast_sched_add(), attempt_transmit(), chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), 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().
01836 { 01837 /* Attempt to transmit the frame to the remote peer... 01838 Called without iaxsl held. */ 01839 struct iax_frame *f = data; 01840 int freeme=0; 01841 int callno = f->callno; 01842 /* Make sure this call is still active */ 01843 if (callno) 01844 ast_mutex_lock(&iaxsl[callno]); 01845 if (callno && iaxs[callno]) { 01846 if ((f->retries < 0) /* Already ACK'd */ || 01847 (f->retries >= max_retries) /* Too many attempts */) { 01848 /* Record an error if we've transmitted too many times */ 01849 if (f->retries >= max_retries) { 01850 if (f->transfer) { 01851 /* Transfer timeout */ 01852 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 01853 } else if (f->final) { 01854 if (f->final) 01855 iax2_destroy(callno); 01856 } else { 01857 if (iaxs[callno]->owner) 01858 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); 01859 iaxs[callno]->error = ETIMEDOUT; 01860 if (iaxs[callno]->owner) { 01861 struct ast_frame fr = { 0, }; 01862 /* Hangup the fd */ 01863 fr.frametype = AST_FRAME_CONTROL; 01864 fr.subclass = AST_CONTROL_HANGUP; 01865 iax2_queue_frame(callno, &fr); 01866 /* Remember, owner could disappear */ 01867 if (iaxs[callno]->owner) 01868 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01869 } else { 01870 if (iaxs[callno]->reg) { 01871 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 01872 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 01873 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 01874 } 01875 iax2_destroy(callno); 01876 } 01877 } 01878 01879 } 01880 freeme++; 01881 } else { 01882 /* Update it if it needs it */ 01883 update_packet(f); 01884 /* Attempt transmission */ 01885 send_packet(f); 01886 f->retries++; 01887 /* Try again later after 10 times as long */ 01888 f->retrytime *= 10; 01889 if (f->retrytime > MAX_RETRY_TIME) 01890 f->retrytime = MAX_RETRY_TIME; 01891 /* Transfer messages max out at one second */ 01892 if (f->transfer && (f->retrytime > 1000)) 01893 f->retrytime = 1000; 01894 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 01895 } 01896 } else { 01897 /* Make sure it gets freed */ 01898 f->retries = -1; 01899 freeme++; 01900 } 01901 if (callno) 01902 ast_mutex_unlock(&iaxsl[callno]); 01903 /* Do not try again */ 01904 if (freeme) { 01905 /* Don't attempt delivery, just remove it from the queue */ 01906 AST_LIST_LOCK(&iaxq.queue); 01907 AST_LIST_REMOVE(&iaxq.queue, f, list); 01908 iaxq.count--; 01909 AST_LIST_UNLOCK(&iaxq.queue); 01910 f->retrans = -1; 01911 /* Free the IAX frame */ 01912 iax2_frame_free(f); 01913 } 01914 }
static void __auth_reject | ( | void * | nothing | ) | [static] |
Definition at line 5793 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().
05794 { 05795 /* Called from IAX thread only, without iaxs lock */ 05796 int callno = (int)(long)(nothing); 05797 struct iax_ie_data ied; 05798 ast_mutex_lock(&iaxsl[callno]); 05799 if (iaxs[callno]) { 05800 memset(&ied, 0, sizeof(ied)); 05801 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 05802 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 05803 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 05804 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 05805 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 05806 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 05807 } 05808 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 05809 } 05810 ast_mutex_unlock(&iaxsl[callno]); 05811 }
static void __auto_congest | ( | void * | nothing | ) | [static] |
Definition at line 2712 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().
02713 { 02714 int callno = PTR_TO_CALLNO(nothing); 02715 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02716 ast_mutex_lock(&iaxsl[callno]); 02717 if (iaxs[callno]) { 02718 iaxs[callno]->initid = -1; 02719 iax2_queue_frame(callno, &f); 02720 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02721 } 02722 ast_mutex_unlock(&iaxsl[callno]); 02723 }
static void __auto_hangup | ( | void * | nothing | ) | [static] |
Definition at line 5845 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().
05846 { 05847 /* Called from IAX thread only, without iaxs lock */ 05848 int callno = (int)(long)(nothing); 05849 struct iax_ie_data ied; 05850 ast_mutex_lock(&iaxsl[callno]); 05851 if (iaxs[callno]) { 05852 memset(&ied, 0, sizeof(ied)); 05853 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 05854 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 05855 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 05856 } 05857 ast_mutex_unlock(&iaxsl[callno]); 05858 }
static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 1591 of file chan_iax2.c.
References iax_frame::af, ast_test_flag, iax_frame::callno, ast_frame::has_timing_info, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
01592 { 01593 /* Just deliver the packet by using queueing. This is called by 01594 the IAX thread with the iaxsl lock held. */ 01595 struct iax_frame *fr = data; 01596 fr->retrans = -1; 01597 fr->af.has_timing_info = 0; 01598 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01599 iax2_queue_frame(fr->callno, &fr->af); 01600 /* Free our iax frame */ 01601 iax2_frame_free(fr); 01602 /* And don't run again */ 01603 return 0; 01604 }
static void __expire_registry | ( | void * | data | ) | [static] |
Definition at line 5518 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_set_flag, ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), name, prune_peers(), realtime_update_peer(), and register_peer_exten().
Referenced by expire_registry().
05519 { 05520 char *name = data; 05521 struct iax2_peer *p = NULL; 05522 05523 /* Go through and grab this peer... and if it needs to be removed... then do it */ 05524 AST_LIST_LOCK(&peers); 05525 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) { 05526 if (!strcasecmp(p->name, name)) { 05527 p->expire = -1; 05528 break; 05529 } 05530 } 05531 AST_LIST_TRAVERSE_SAFE_END 05532 AST_LIST_UNLOCK(&peers); 05533 05534 /* Peer is already gone for whatever reason */ 05535 if (!p) 05536 return; 05537 05538 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name); 05539 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05540 realtime_update_peer(p->name, &p->addr, 0); 05541 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name); 05542 /* Reset the address */ 05543 memset(&p->addr, 0, sizeof(p->addr)); 05544 /* Reset expiry value */ 05545 p->expiry = min_reg_expire; 05546 if (!ast_test_flag(p, IAX_TEMPONLY)) 05547 ast_db_del("IAX/Registry", p->name); 05548 register_peer_exten(p, 0); 05549 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05550 if (iax2_regfunk) 05551 iax2_regfunk(p->name, 0); 05552 05553 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) { 05554 ast_set_flag(p, IAX_DELME); 05555 prune_peers(); 05556 } 05557 }
static void __get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2232 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().
02233 { 02234 int callno = PTR_TO_CALLNO(p); 02235 struct chan_iax2_pvt *pvt = NULL; 02236 struct iax_frame *fr; 02237 jb_frame frame; 02238 int ret; 02239 long now; 02240 long next; 02241 struct timeval tv; 02242 02243 /* Make sure we have a valid private structure before going on */ 02244 ast_mutex_lock(&iaxsl[callno]); 02245 pvt = iaxs[callno]; 02246 if (!pvt) { 02247 /* No go! */ 02248 ast_mutex_unlock(&iaxsl[callno]); 02249 return; 02250 } 02251 02252 if( pvt->jb == NULL ) { 02253 ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" ); 02254 ast_backtrace(); 02255 return; 02256 } 02257 02258 pvt->jbid = -1; 02259 02260 gettimeofday(&tv,NULL); 02261 /* round up a millisecond since ast_sched_runq does; */ 02262 /* prevents us from spinning while waiting for our now */ 02263 /* to catch up with runq's now */ 02264 tv.tv_usec += 1000; 02265 02266 now = ast_tvdiff_ms(tv, pvt->rxcore); 02267 02268 if(now >= (next = jb_next(pvt->jb))) { 02269 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02270 switch(ret) { 02271 case JB_OK: 02272 fr = frame.data; 02273 __do_deliver(fr); 02274 break; 02275 case JB_INTERP: 02276 { 02277 struct ast_frame af = { 0, }; 02278 02279 /* create an interpolation frame */ 02280 af.frametype = AST_FRAME_VOICE; 02281 af.subclass = pvt->voiceformat; 02282 af.samples = frame.ms * 8; 02283 af.src = "IAX2 JB interpolation"; 02284 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02285 af.offset = AST_FRIENDLY_OFFSET; 02286 02287 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02288 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02289 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 02290 iax2_queue_frame(callno, &af); 02291 } 02292 break; 02293 case JB_DROP: 02294 iax2_frame_free(frame.data); 02295 break; 02296 case JB_NOFRAME: 02297 case JB_EMPTY: 02298 /* do nothing */ 02299 break; 02300 default: 02301 /* shouldn't happen */ 02302 break; 02303 } 02304 } 02305 update_jbsched(pvt); 02306 ast_mutex_unlock(&iaxsl[callno]); 02307 }
static void __iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5235 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05236 { 05237 struct iax2_registry *reg = data; 05238 reg->expire = -1; 05239 iax2_do_register(reg); 05240 }
static void __iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 7961 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
07962 { 07963 struct iax2_peer *peer = data; 07964 if (peer->lastms > -1) { 07965 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07966 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07967 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07968 } 07969 if (peer->callno > 0) { 07970 ast_mutex_lock(&iaxsl[peer->callno]); 07971 iax2_destroy(peer->callno); 07972 ast_mutex_unlock(&iaxsl[peer->callno]); 07973 } 07974 peer->callno = 0; 07975 peer->lastms = -1; 07976 /* Try again quickly */ 07977 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07978 }
static void __iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 5908 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by iax2_poke_peer_s().
05909 { 05910 struct iax2_peer *peer = data; 05911 iax2_poke_peer(peer, 0); 05912 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4060 of file chan_iax2.c.
References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04061 { 04062 regex_t regexbuf; 04063 int havepattern = 0; 04064 int total_peers = 0; 04065 int online_peers = 0; 04066 int offline_peers = 0; 04067 int unmonitored_peers = 0; 04068 04069 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04070 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04071 04072 struct iax2_peer *peer = NULL; 04073 char name[256]; 04074 int registeredonly=0; 04075 char *term = manager ? "\r\n" : "\n"; 04076 04077 switch (argc) { 04078 case 6: 04079 if (!strcasecmp(argv[3], "registered")) 04080 registeredonly = 1; 04081 else 04082 return RESULT_SHOWUSAGE; 04083 if (!strcasecmp(argv[4], "like")) { 04084 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04085 return RESULT_SHOWUSAGE; 04086 havepattern = 1; 04087 } else 04088 return RESULT_SHOWUSAGE; 04089 break; 04090 case 5: 04091 if (!strcasecmp(argv[3], "like")) { 04092 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04093 return RESULT_SHOWUSAGE; 04094 havepattern = 1; 04095 } else 04096 return RESULT_SHOWUSAGE; 04097 break; 04098 case 4: 04099 if (!strcasecmp(argv[3], "registered")) 04100 registeredonly = 1; 04101 else 04102 return RESULT_SHOWUSAGE; 04103 break; 04104 case 3: 04105 break; 04106 default: 04107 return RESULT_SHOWUSAGE; 04108 } 04109 04110 04111 if (s) 04112 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04113 else 04114 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04115 04116 AST_LIST_LOCK(&peers); 04117 AST_LIST_TRAVERSE(&peers, peer, entry) { 04118 char nm[20]; 04119 char status[20]; 04120 char srch[2000]; 04121 int retstatus; 04122 04123 if (registeredonly && !peer->addr.sin_addr.s_addr) 04124 continue; 04125 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04126 continue; 04127 04128 if (!ast_strlen_zero(peer->username)) 04129 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04130 else 04131 ast_copy_string(name, peer->name, sizeof(name)); 04132 04133 retstatus = peer_status(peer, status, sizeof(status)); 04134 if (retstatus > 0) 04135 online_peers++; 04136 else if (!retstatus) 04137 offline_peers++; 04138 else 04139 unmonitored_peers++; 04140 04141 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04142 04143 snprintf(srch, sizeof(srch), FORMAT, name, 04144 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04145 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04146 nm, 04147 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04148 peer->encmethods ? "(E)" : " ", status, term); 04149 04150 if (s) 04151 astman_append(s, FORMAT, name, 04152 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04153 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04154 nm, 04155 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04156 peer->encmethods ? "(E)" : " ", status, term); 04157 else 04158 ast_cli(fd, FORMAT, name, 04159 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04160 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04161 nm, 04162 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04163 peer->encmethods ? "(E)" : " ", status, term); 04164 total_peers++; 04165 } 04166 AST_LIST_UNLOCK(&peers); 04167 04168 if (s) 04169 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04170 else 04171 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04172 04173 if (havepattern) 04174 regfree(®exbuf); 04175 04176 return RESULT_SUCCESS; 04177 #undef FORMAT 04178 #undef FORMAT2 04179 }
static int __schedule_action | ( | void(*)(void *data) | func, | |
void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 884 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), t, and thread.
00885 { 00886 struct iax2_thread *thread = NULL; 00887 static time_t lasterror; 00888 static time_t t; 00889 00890 thread = find_idle_thread(); 00891 00892 if (thread != NULL) { 00893 thread->schedfunc = func; 00894 thread->scheddata = data; 00895 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00896 #ifdef DEBUG_SCHED_MULTITHREAD 00897 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00898 #endif 00899 signal_condition(&thread->lock, &thread->cond); 00900 return 0; 00901 } 00902 time(&t); 00903 if (t != lasterror) 00904 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n"); 00905 lasterror = t; 00906 00907 return -1; 00908 }
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 4559 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04561 { 04562 struct ast_frame f = { 0, }; 04563 04564 f.frametype = type; 04565 f.subclass = command; 04566 f.datalen = datalen; 04567 f.src = __FUNCTION__; 04568 f.data = (void *) data; 04569 04570 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04571 }
static void __send_lagrq | ( | void * | data | ) | [static] |
Definition at line 948 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
00949 { 00950 int callno = (long)data; 00951 /* Ping only if it's real not if it's bridged */ 00952 ast_mutex_lock(&iaxsl[callno]); 00953 if (iaxs[callno] && iaxs[callno]->lagid != -1) { 00954 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 00955 iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 00956 } 00957 ast_mutex_unlock(&iaxsl[callno]); 00958 }
static void __send_ping | ( | void * | data | ) | [static] |
Definition at line 914 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
00915 { 00916 int callno = (long)data; 00917 ast_mutex_lock(&iaxsl[callno]); 00918 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00919 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00920 iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data); 00921 } 00922 ast_mutex_unlock(&iaxsl[callno]); 00923 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10057 of file chan_iax2.c.
References 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, sched, sched_context_destroy(), thread, and waresl.
Referenced by load_module(), and unload_module().
10058 { 10059 struct iax2_thread *thread = NULL; 10060 int x; 10061 10062 /* Make sure threads do not hold shared resources when they are canceled */ 10063 10064 /* Grab the sched lock resource to keep it away from threads about to die */ 10065 /* Cancel the network thread, close the net socket */ 10066 if (netthreadid != AST_PTHREADT_NULL) { 10067 AST_LIST_LOCK(&iaxq.queue); 10068 ast_mutex_lock(&sched_lock); 10069 pthread_cancel(netthreadid); 10070 ast_cond_signal(&sched_cond); 10071 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10072 AST_LIST_UNLOCK(&iaxq.queue); 10073 pthread_join(netthreadid, NULL); 10074 } 10075 if (schedthreadid != AST_PTHREADT_NULL) { 10076 ast_mutex_lock(&sched_lock); 10077 pthread_cancel(schedthreadid); 10078 ast_cond_signal(&sched_cond); 10079 ast_mutex_unlock(&sched_lock); 10080 pthread_join(schedthreadid, NULL); 10081 } 10082 10083 /* Call for all threads to halt */ 10084 AST_LIST_LOCK(&idle_list); 10085 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10086 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10087 pthread_cancel(thread->threadid); 10088 } 10089 AST_LIST_TRAVERSE_SAFE_END 10090 AST_LIST_UNLOCK(&idle_list); 10091 10092 AST_LIST_LOCK(&active_list); 10093 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10094 AST_LIST_REMOVE_CURRENT(&active_list, list); 10095 pthread_cancel(thread->threadid); 10096 } 10097 AST_LIST_TRAVERSE_SAFE_END 10098 AST_LIST_UNLOCK(&active_list); 10099 10100 AST_LIST_LOCK(&dynamic_list); 10101 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10102 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10103 pthread_cancel(thread->threadid); 10104 } 10105 AST_LIST_TRAVERSE_SAFE_END 10106 AST_LIST_UNLOCK(&dynamic_list); 10107 10108 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10109 10110 /* Wait for threads to exit */ 10111 while(0 < iaxactivethreadcount) 10112 usleep(10000); 10113 10114 ast_netsock_release(netsock); 10115 ast_netsock_release(outsock); 10116 for (x=0;x<IAX_MAX_CALLS;x++) 10117 if (iaxs[x]) 10118 iax2_destroy(x); 10119 ast_manager_unregister( "IAXpeers" ); 10120 ast_manager_unregister( "IAXnetstats" ); 10121 ast_unregister_application(papp); 10122 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10123 ast_unregister_switch(&iax2_switch); 10124 ast_channel_unregister(&iax2_tech); 10125 delete_users(); 10126 iax_provision_unload(); 10127 sched_context_destroy(sched); 10128 10129 ast_mutex_destroy(&waresl.lock); 10130 10131 for (x = 0; x < IAX_MAX_CALLS; x++) 10132 ast_mutex_destroy(&iaxsl[x]); 10133 10134 return 0; 10135 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 6290 of file chan_iax2.c.
References pbx_builtin_getvar_helper().
06291 { 06292 const char *value; 06293 char tmp[256]; 06294 snprintf(tmp, sizeof(tmp), "~IAX2~%s", data); 06295 value = pbx_builtin_getvar_helper(chan, tmp); 06296 ast_copy_string(buf, value ? value : "", len); 06297 return 0; 06298 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | varname, | |||
const char * | value | |||
) | [static] |
Definition at line 6300 of file chan_iax2.c.
References pbx_builtin_setvar_helper().
06301 { 06302 char tmp[256]; 06303 /* Inherit forever */ 06304 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname); 06305 pbx_builtin_setvar_helper(chan, tmp, value); 06306 return 0; 06307 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 4604 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04605 { 04606 while(con) { 04607 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04608 return -1; 04609 con = con->next; 04610 } 04611 return 0; 04612 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4387 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().
04388 { 04389 int x; 04390 int numchans = 0; 04391 for (x=0;x<IAX_MAX_CALLS;x++) { 04392 ast_mutex_lock(&iaxsl[x]); 04393 if (iaxs[x]) { 04394 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04395 char *fmt; 04396 jb_info jbinfo; 04397 04398 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04399 jb_getinfo(iaxs[x]->jb, &jbinfo); 04400 localjitter = jbinfo.jitter; 04401 localdelay = jbinfo.current - jbinfo.min; 04402 locallost = jbinfo.frames_lost; 04403 locallosspct = jbinfo.losspct/1000; 04404 localdropped = jbinfo.frames_dropped; 04405 localooo = jbinfo.frames_ooo; 04406 } else { 04407 localjitter = -1; 04408 localdelay = 0; 04409 locallost = -1; 04410 locallosspct = -1; 04411 localdropped = 0; 04412 localooo = -1; 04413 } 04414 if (limit_fmt) 04415 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04416 else 04417 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04418 if (s) 04419 04420 astman_append(s, fmt, 04421 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04422 iaxs[x]->pingtime, 04423 localjitter, 04424 localdelay, 04425 locallost, 04426 locallosspct, 04427 localdropped, 04428 localooo, 04429 iaxs[x]->frames_received/1000, 04430 iaxs[x]->remote_rr.jitter, 04431 iaxs[x]->remote_rr.delay, 04432 iaxs[x]->remote_rr.losscnt, 04433 iaxs[x]->remote_rr.losspct, 04434 iaxs[x]->remote_rr.dropped, 04435 iaxs[x]->remote_rr.ooo, 04436 iaxs[x]->remote_rr.packets/1000); 04437 else 04438 ast_cli(fd, fmt, 04439 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04440 iaxs[x]->pingtime, 04441 localjitter, 04442 localdelay, 04443 locallost, 04444 locallosspct, 04445 localdropped, 04446 localooo, 04447 iaxs[x]->frames_received/1000, 04448 iaxs[x]->remote_rr.jitter, 04449 iaxs[x]->remote_rr.delay, 04450 iaxs[x]->remote_rr.losscnt, 04451 iaxs[x]->remote_rr.losspct, 04452 iaxs[x]->remote_rr.dropped, 04453 iaxs[x]->remote_rr.ooo, 04454 iaxs[x]->remote_rr.packets/1000 04455 ); 04456 numchans++; 04457 } 04458 ast_mutex_unlock(&iaxsl[x]); 04459 } 04460 return numchans; 04461 }
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 3299 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_name, ast_callerid::cid_num, 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().
03300 { 03301 struct ast_channel *tmp; 03302 struct chan_iax2_pvt *i; 03303 struct ast_variable *v = NULL; 03304 03305 if (!(i = iaxs[callno])) { 03306 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03307 return NULL; 03308 } 03309 03310 /* Don't hold call lock */ 03311 ast_mutex_unlock(&iaxsl[callno]); 03312 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); 03313 ast_mutex_lock(&iaxsl[callno]); 03314 if (!tmp) 03315 return NULL; 03316 tmp->tech = &iax2_tech; 03317 /* We can support any format by default, until we get restricted */ 03318 tmp->nativeformats = capability; 03319 tmp->readformat = ast_best_codec(capability); 03320 tmp->writeformat = ast_best_codec(capability); 03321 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03322 03323 /* Don't use ast_set_callerid() here because it will 03324 * generate a NewCallerID event before the NewChannel event */ 03325 tmp->cid.cid_num = ast_strdup(i->cid_num); 03326 tmp->cid.cid_name = ast_strdup(i->cid_name); 03327 if (!ast_strlen_zero(i->ani)) 03328 tmp->cid.cid_ani = ast_strdup(i->ani); 03329 else 03330 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03331 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03332 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03333 tmp->cid.cid_pres = i->calling_pres; 03334 tmp->cid.cid_ton = i->calling_ton; 03335 tmp->cid.cid_tns = i->calling_tns; 03336 if (!ast_strlen_zero(i->language)) 03337 ast_string_field_set(tmp, language, i->language); 03338 if (!ast_strlen_zero(i->accountcode)) 03339 ast_string_field_set(tmp, accountcode, i->accountcode); 03340 if (i->amaflags) 03341 tmp->amaflags = i->amaflags; 03342 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03343 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03344 if (i->adsi) 03345 tmp->adsicpe = i->peeradsicpe; 03346 else 03347 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03348 i->owner = tmp; 03349 i->capability = capability; 03350 if (state != AST_STATE_DOWN) { 03351 if (ast_pbx_start(tmp)) { 03352 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03353 ast_hangup(tmp); 03354 i->owner = NULL; 03355 return NULL; 03356 } 03357 } 03358 03359 for (v = i->vars ; v ; v = v->next) 03360 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03361 03362 ast_module_ref(ast_module_info->self); 03363 03364 return tmp; 03365 }
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 | ( | peers | , | |
iax2_peer | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | users | , | |
iax2_user | ||||
) | [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 | ( | void * | data | ) | [static] |
Definition at line 1916 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
01917 { 01918 #ifdef SCHED_MULTITHREADED 01919 if (schedule_action(__attempt_transmit, data)) 01920 #endif 01921 __attempt_transmit(data); 01922 return 0; 01923 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 5827 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iaxs, iaxsl, and sched.
Referenced by socket_process().
05828 { 05829 /* Schedule sending the authentication failure in one second, to prevent 05830 guessing */ 05831 ast_mutex_lock(&iaxsl[callno]); 05832 if (iaxs[callno]) { 05833 iaxs[callno]->authfail = failcode; 05834 if (delayreject) { 05835 if (iaxs[callno]->authid > -1) 05836 ast_sched_del(sched, iaxs[callno]->authid); 05837 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 05838 } else 05839 auth_reject((void *)(long)callno); 05840 } 05841 ast_mutex_unlock(&iaxsl[callno]); 05842 return 0; 05843 }
static int auth_reject | ( | void * | data | ) | [static] |
Definition at line 5813 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().
05814 { 05815 int callno = (int)(long)(data); 05816 ast_mutex_lock(&iaxsl[callno]); 05817 if (iaxs[callno]) 05818 iaxs[callno]->authid = -1; 05819 ast_mutex_unlock(&iaxsl[callno]); 05820 #ifdef SCHED_MULTITHREADED 05821 if (schedule_action(__auth_reject, data)) 05822 #endif 05823 __auth_reject(data); 05824 return 0; 05825 }
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 5122 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().
05123 { 05124 int res = -1; 05125 int x; 05126 if (!ast_strlen_zero(keyn)) { 05127 if (!(authmethods & IAX_AUTH_RSA)) { 05128 if (ast_strlen_zero(secret)) 05129 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)); 05130 } else if (ast_strlen_zero(challenge)) { 05131 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05132 } else { 05133 char sig[256]; 05134 struct ast_key *key; 05135 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05136 if (!key) { 05137 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05138 } else { 05139 if (ast_sign(key, (char*)challenge, sig)) { 05140 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05141 res = -1; 05142 } else { 05143 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05144 res = 0; 05145 } 05146 } 05147 } 05148 } 05149 /* Fall back */ 05150 if (res && !ast_strlen_zero(secret)) { 05151 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05152 struct MD5Context md5; 05153 unsigned char digest[16]; 05154 char digres[128]; 05155 MD5Init(&md5); 05156 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05157 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05158 MD5Final(digest, &md5); 05159 /* If they support md5, authenticate with it. */ 05160 for (x=0;x<16;x++) 05161 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05162 if (ecx && dcx) 05163 build_enc_keys(digest, ecx, dcx); 05164 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05165 res = 0; 05166 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05167 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05168 res = 0; 05169 } else 05170 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05171 } 05172 return res; 05173 }
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 5175 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, authenticate(), destroy_peer(), IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ies, iax2_peer::mask, merge_encryption(), realtime_peer(), and send_command().
Referenced by socket_process().
05176 { 05177 struct iax2_peer *peer = NULL; 05178 /* Start pessimistic */ 05179 int res = -1; 05180 int authmethods = 0; 05181 struct iax_ie_data ied; 05182 05183 memset(&ied, 0, sizeof(ied)); 05184 05185 if (ies->username) 05186 ast_string_field_set(p, username, ies->username); 05187 if (ies->challenge) 05188 ast_string_field_set(p, challenge, ies->challenge); 05189 if (ies->authmethods) 05190 authmethods = ies->authmethods; 05191 if (authmethods & IAX_AUTH_MD5) 05192 merge_encryption(p, ies->encmethods); 05193 else 05194 p->encmethods = 0; 05195 05196 /* Check for override RSA authentication first */ 05197 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05198 /* Normal password authentication */ 05199 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05200 } else { 05201 AST_LIST_LOCK(&peers); 05202 AST_LIST_TRAVERSE(&peers, peer, entry) { 05203 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05204 /* No peer specified at our end, or this is the peer */ 05205 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05206 /* No username specified in peer rule, or this is the right username */ 05207 && (!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))) 05208 /* No specified host, or this is our host */ 05209 ) { 05210 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05211 if (!res) 05212 break; 05213 } 05214 } 05215 AST_LIST_UNLOCK(&peers); 05216 if (!peer) { 05217 /* We checked our list and didn't find one. It's unlikely, but possible, 05218 that we're trying to authenticate *to* a realtime peer */ 05219 if ((peer = realtime_peer(p->peer, NULL))) { 05220 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05221 if (ast_test_flag(peer, IAX_TEMPONLY)) 05222 destroy_peer(peer); 05223 } 05224 } 05225 } 05226 if (ies->encmethods) 05227 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05228 if (!res) 05229 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05230 return res; 05231 }
static int authenticate_request | ( | struct chan_iax2_pvt * | p | ) | [static] |
Definition at line 4847 of file chan_iax2.c.
References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, iax2_user::maxauthreq, send_command(), and send_command_final().
Referenced by socket_process().
04848 { 04849 struct iax2_user *user = NULL; 04850 struct iax_ie_data ied; 04851 int res = -1, authreq_restrict = 0; 04852 char challenge[10]; 04853 04854 memset(&ied, 0, sizeof(ied)); 04855 04856 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 04857 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04858 AST_LIST_LOCK(&users); 04859 AST_LIST_TRAVERSE(&users, user, entry) { 04860 if (!strcmp(user->name, p->username)) { 04861 if (user->curauthreq == user->maxauthreq) 04862 authreq_restrict = 1; 04863 else 04864 user->curauthreq++; 04865 break; 04866 } 04867 } 04868 AST_LIST_UNLOCK(&users); 04869 } 04870 04871 /* If the AUTHREQ limit test failed, send back an error */ 04872 if (authreq_restrict) { 04873 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 04874 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 04875 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 04876 return 0; 04877 } 04878 04879 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 04880 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 04881 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 04882 ast_string_field_set(p, challenge, challenge); 04883 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 04884 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 04885 } 04886 if (p->encmethods) 04887 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 04888 04889 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 04890 04891 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 04892 04893 if (p->encmethods) 04894 ast_set_flag(p, IAX_ENCRYPTED); 04895 04896 return res; 04897 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4899 of file chan_iax2.c.
References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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(), chan_iax2_pvt::state, and strsep().
Referenced by socket_process().
04900 { 04901 char requeststr[256]; 04902 char md5secret[256] = ""; 04903 char secret[256] = ""; 04904 char rsasecret[256] = ""; 04905 int res = -1; 04906 int x; 04907 struct iax2_user *user = NULL; 04908 04909 AST_LIST_LOCK(&users); 04910 AST_LIST_TRAVERSE(&users, user, entry) { 04911 if (!strcmp(user->name, p->username)) 04912 break; 04913 } 04914 if (user) { 04915 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04916 user->curauthreq--; 04917 ast_clear_flag(p, IAX_MAXAUTHREQ); 04918 } 04919 ast_string_field_set(p, host, user->name); 04920 } 04921 AST_LIST_UNLOCK(&users); 04922 04923 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 04924 return res; 04925 if (ies->password) 04926 ast_copy_string(secret, ies->password, sizeof(secret)); 04927 if (ies->md5_result) 04928 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 04929 if (ies->rsa_result) 04930 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 04931 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 04932 struct ast_key *key; 04933 char *keyn; 04934 char tmpkey[256]; 04935 char *stringp=NULL; 04936 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 04937 stringp=tmpkey; 04938 keyn = strsep(&stringp, ":"); 04939 while(keyn) { 04940 key = ast_key_get(keyn, AST_KEY_PUBLIC); 04941 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 04942 res = 0; 04943 break; 04944 } else if (!key) 04945 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 04946 keyn = strsep(&stringp, ":"); 04947 } 04948 } else if (p->authmethods & IAX_AUTH_MD5) { 04949 struct MD5Context md5; 04950 unsigned char digest[16]; 04951 char *tmppw, *stringp; 04952 04953 tmppw = ast_strdupa(p->secret); 04954 stringp = tmppw; 04955 while((tmppw = strsep(&stringp, ";"))) { 04956 MD5Init(&md5); 04957 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 04958 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04959 MD5Final(digest, &md5); 04960 /* If they support md5, authenticate with it. */ 04961 for (x=0;x<16;x++) 04962 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 04963 if (!strcasecmp(requeststr, md5secret)) { 04964 res = 0; 04965 break; 04966 } 04967 } 04968 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 04969 if (!strcmp(secret, p->secret)) 04970 res = 0; 04971 } 04972 return res; 04973 }
static int auto_congest | ( | void * | data | ) | [static] |
Definition at line 2725 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
02726 { 02727 #ifdef SCHED_MULTITHREADED 02728 if (schedule_action(__auto_congest, data)) 02729 #endif 02730 __auto_congest(data); 02731 return 0; 02732 }
static int auto_hangup | ( | void * | data | ) | [static] |
Definition at line 5860 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().
05861 { 05862 int callno = (int)(long)(data); 05863 ast_mutex_lock(&iaxsl[callno]); 05864 if (iaxs[callno]) { 05865 iaxs[callno]->autoid = -1; 05866 } 05867 ast_mutex_unlock(&iaxsl[callno]); 05868 #ifdef SCHED_MULTITHREADED 05869 if (schedule_action(__auto_hangup, data)) 05870 #endif 05871 __auto_hangup(data); 05872 return 0; 05873 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 8255 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
08256 { 08257 struct iax2_context *con; 08258 08259 if ((con = ast_calloc(1, sizeof(*con)))) 08260 ast_copy_string(con->context, context, sizeof(con->context)); 08261 08262 return con; 08263 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3659 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03660 { 03661 aes_encrypt_key128(digest, ecx); 03662 aes_decrypt_key128(digest, dcx); 03663 }
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 8380 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_free_pools, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), iax2_peer::authmethods, iax2_peer::capability, cid_name, cid_num, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, free, 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, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_set_srcaddr(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, prefs, sched, iax2_peer::smoothing, and ast_variable::value.
08381 { 08382 struct iax2_peer *peer = NULL; 08383 struct ast_ha *oldha = NULL; 08384 int maskfound=0; 08385 int found=0; 08386 int firstpass=1; 08387 08388 AST_LIST_LOCK(&peers); 08389 if (!temponly) { 08390 AST_LIST_TRAVERSE(&peers, peer, entry) { 08391 if (!strcmp(peer->name, name)) { 08392 if (!ast_test_flag(peer, IAX_DELME)) 08393 firstpass = 0; 08394 break; 08395 } 08396 } 08397 } else 08398 peer = NULL; 08399 if (peer) { 08400 found++; 08401 if (firstpass) { 08402 oldha = peer->ha; 08403 peer->ha = NULL; 08404 } 08405 AST_LIST_REMOVE(&peers, peer, entry); 08406 AST_LIST_UNLOCK(&peers); 08407 } else { 08408 AST_LIST_UNLOCK(&peers); 08409 if ((peer = ast_calloc(1, sizeof(*peer)))) { 08410 peer->expire = -1; 08411 peer->pokeexpire = -1; 08412 peer->sockfd = defaultsockfd; 08413 if (ast_string_field_init(peer, 32)) { 08414 free(peer); 08415 peer = NULL; 08416 } 08417 } 08418 } 08419 if (peer) { 08420 if (firstpass) { 08421 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08422 peer->encmethods = iax2_encryption; 08423 peer->adsi = adsi; 08424 ast_string_field_set(peer,secret,""); 08425 if (!found) { 08426 ast_string_field_set(peer, name, name); 08427 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08428 peer->expiry = min_reg_expire; 08429 } 08430 peer->prefs = prefs; 08431 peer->capability = iax2_capability; 08432 peer->smoothing = 0; 08433 peer->pokefreqok = DEFAULT_FREQ_OK; 08434 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08435 ast_string_field_set(peer,context,""); 08436 ast_string_field_set(peer,peercontext,""); 08437 ast_clear_flag(peer, IAX_HASCALLERID); 08438 ast_string_field_set(peer, cid_name, ""); 08439 ast_string_field_set(peer, cid_num, ""); 08440 } 08441 08442 if (!v) { 08443 v = alt; 08444 alt = NULL; 08445 } 08446 while(v) { 08447 if (!strcasecmp(v->name, "secret")) { 08448 ast_string_field_set(peer, secret, v->value); 08449 } else if (!strcasecmp(v->name, "mailbox")) { 08450 ast_string_field_set(peer, mailbox, v->value); 08451 } else if (!strcasecmp(v->name, "mohinterpret")) { 08452 ast_string_field_set(peer, mohinterpret, v->value); 08453 } else if (!strcasecmp(v->name, "mohsuggest")) { 08454 ast_string_field_set(peer, mohsuggest, v->value); 08455 } else if (!strcasecmp(v->name, "dbsecret")) { 08456 ast_string_field_set(peer, dbsecret, v->value); 08457 } else if (!strcasecmp(v->name, "trunk")) { 08458 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08459 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08460 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08461 ast_clear_flag(peer, IAX_TRUNK); 08462 } 08463 } else if (!strcasecmp(v->name, "auth")) { 08464 peer->authmethods = get_auth_methods(v->value); 08465 } else if (!strcasecmp(v->name, "encryption")) { 08466 peer->encmethods = get_encrypt_methods(v->value); 08467 } else if (!strcasecmp(v->name, "notransfer")) { 08468 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 08469 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 08470 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08471 } else if (!strcasecmp(v->name, "transfer")) { 08472 if (!strcasecmp(v->value, "mediaonly")) { 08473 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 08474 } else if (ast_true(v->value)) { 08475 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 08476 } else 08477 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 08478 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08479 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08480 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08481 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08482 } else if (!strcasecmp(v->name, "host")) { 08483 if (!strcasecmp(v->value, "dynamic")) { 08484 /* They'll register with us */ 08485 ast_set_flag(peer, IAX_DYNAMIC); 08486 if (!found) { 08487 /* Initialize stuff iff we're not found, otherwise 08488 we keep going with what we had */ 08489 memset(&peer->addr.sin_addr, 0, 4); 08490 if (peer->addr.sin_port) { 08491 /* If we've already got a port, make it the default rather than absolute */ 08492 peer->defaddr.sin_port = peer->addr.sin_port; 08493 peer->addr.sin_port = 0; 08494 } 08495 } 08496 } else { 08497 /* Non-dynamic. Make sure we become that way if we're not */ 08498 if (peer->expire > -1) 08499 ast_sched_del(sched, peer->expire); 08500 peer->expire = -1; 08501 ast_clear_flag(peer, IAX_DYNAMIC); 08502 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08503 ast_string_field_free_pools(peer); 08504 free(peer); 08505 return NULL; 08506 } 08507 if (!peer->addr.sin_port) 08508 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08509 } 08510 if (!maskfound) 08511 inet_aton("255.255.255.255", &peer->mask); 08512 } else if (!strcasecmp(v->name, "defaultip")) { 08513 if (ast_get_ip(&peer->defaddr, v->value)) { 08514 ast_string_field_free_pools(peer); 08515 free(peer); 08516 return NULL; 08517 } 08518 } else if (!strcasecmp(v->name, "sourceaddress")) { 08519 peer_set_srcaddr(peer, v->value); 08520 } else if (!strcasecmp(v->name, "permit") || 08521 !strcasecmp(v->name, "deny")) { 08522 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08523 } else if (!strcasecmp(v->name, "mask")) { 08524 maskfound++; 08525 inet_aton(v->value, &peer->mask); 08526 } else if (!strcasecmp(v->name, "context")) { 08527 ast_string_field_set(peer, context, v->value); 08528 } else if (!strcasecmp(v->name, "regexten")) { 08529 ast_string_field_set(peer, regexten, v->value); 08530 } else if (!strcasecmp(v->name, "peercontext")) { 08531 ast_string_field_set(peer, peercontext, v->value); 08532 } else if (!strcasecmp(v->name, "port")) { 08533 if (ast_test_flag(peer, IAX_DYNAMIC)) 08534 peer->defaddr.sin_port = htons(atoi(v->value)); 08535 else 08536 peer->addr.sin_port = htons(atoi(v->value)); 08537 } else if (!strcasecmp(v->name, "username")) { 08538 ast_string_field_set(peer, username, v->value); 08539 } else if (!strcasecmp(v->name, "allow")) { 08540 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08541 } else if (!strcasecmp(v->name, "disallow")) { 08542 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08543 } else if (!strcasecmp(v->name, "callerid")) { 08544 if (!ast_strlen_zero(v->value)) { 08545 char name2[80]; 08546 char num2[80]; 08547 ast_callerid_split(v->value, name2, 80, num2, 80); 08548 ast_string_field_set(peer, cid_name, name2); 08549 ast_string_field_set(peer, cid_num, num2); 08550 ast_set_flag(peer, IAX_HASCALLERID); 08551 } else { 08552 ast_clear_flag(peer, IAX_HASCALLERID); 08553 ast_string_field_set(peer, cid_name, ""); 08554 ast_string_field_set(peer, cid_num, ""); 08555 } 08556 } else if (!strcasecmp(v->name, "fullname")) { 08557 if (!ast_strlen_zero(v->value)) { 08558 ast_string_field_set(peer, cid_name, v->value); 08559 ast_set_flag(peer, IAX_HASCALLERID); 08560 } else { 08561 ast_string_field_set(peer, cid_name, ""); 08562 if (ast_strlen_zero(peer->cid_num)) 08563 ast_clear_flag(peer, IAX_HASCALLERID); 08564 } 08565 } else if (!strcasecmp(v->name, "cid_number")) { 08566 if (!ast_strlen_zero(v->value)) { 08567 ast_string_field_set(peer, cid_num, v->value); 08568 ast_set_flag(peer, IAX_HASCALLERID); 08569 } else { 08570 ast_string_field_set(peer, cid_num, ""); 08571 if (ast_strlen_zero(peer->cid_name)) 08572 ast_clear_flag(peer, IAX_HASCALLERID); 08573 } 08574 } else if (!strcasecmp(v->name, "sendani")) { 08575 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08576 } else if (!strcasecmp(v->name, "inkeys")) { 08577 ast_string_field_set(peer, inkeys, v->value); 08578 } else if (!strcasecmp(v->name, "outkey")) { 08579 ast_string_field_set(peer, outkey, v->value); 08580 } else if (!strcasecmp(v->name, "qualify")) { 08581 if (!strcasecmp(v->value, "no")) { 08582 peer->maxms = 0; 08583 } else if (!strcasecmp(v->value, "yes")) { 08584 peer->maxms = DEFAULT_MAXMS; 08585 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08586 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); 08587 peer->maxms = 0; 08588 } 08589 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08590 peer->smoothing = ast_true(v->value); 08591 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08592 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08593 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); 08594 } 08595 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08596 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08597 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); 08598 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08599 } else if (!strcasecmp(v->name, "timezone")) { 08600 ast_string_field_set(peer, zonetag, v->value); 08601 } else if (!strcasecmp(v->name, "adsi")) { 08602 peer->adsi = ast_true(v->value); 08603 }/* else if (strcasecmp(v->name,"type")) */ 08604 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08605 v = v->next; 08606 if (!v) { 08607 v = alt; 08608 alt = NULL; 08609 } 08610 } 08611 if (!peer->authmethods) 08612 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08613 ast_clear_flag(peer, IAX_DELME); 08614 /* Make sure these are IPv4 addresses */ 08615 peer->addr.sin_family = AF_INET; 08616 } 08617 if (oldha) 08618 ast_free_ha(oldha); 08619 return peer; 08620 }
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 8623 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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_pools, 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, iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free, 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, ast_variable::value, and iax2_user::vars.
08624 { 08625 struct iax2_user *user = NULL; 08626 struct iax2_context *con, *conl = NULL; 08627 struct ast_ha *oldha = NULL; 08628 struct iax2_context *oldcon = NULL; 08629 int format; 08630 int firstpass=1; 08631 int oldcurauthreq = 0; 08632 char *varname = NULL, *varval = NULL; 08633 struct ast_variable *tmpvar = NULL; 08634 08635 AST_LIST_LOCK(&users); 08636 if (!temponly) { 08637 AST_LIST_TRAVERSE(&users, user, entry) { 08638 if (!strcmp(user->name, name)) { 08639 if (!ast_test_flag(user, IAX_DELME)) 08640 firstpass = 0; 08641 break; 08642 } 08643 } 08644 } else 08645 user = NULL; 08646 08647 if (user) { 08648 if (firstpass) { 08649 oldcurauthreq = user->curauthreq; 08650 oldha = user->ha; 08651 oldcon = user->contexts; 08652 user->ha = NULL; 08653 user->contexts = NULL; 08654 } 08655 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08656 AST_LIST_REMOVE(&users, user, entry); 08657 AST_LIST_UNLOCK(&users); 08658 } else { 08659 AST_LIST_UNLOCK(&users); 08660 /* This is going to memset'd to 0 in the next block */ 08661 user = ast_calloc(sizeof(*user),1); 08662 } 08663 08664 if (user) { 08665 if (firstpass) { 08666 ast_string_field_free_pools(user); 08667 memset(user, 0, sizeof(struct iax2_user)); 08668 if (ast_string_field_init(user, 32)) { 08669 free(user); 08670 user = NULL; 08671 } 08672 user->maxauthreq = maxauthreq; 08673 user->curauthreq = oldcurauthreq; 08674 user->prefs = prefs; 08675 user->capability = iax2_capability; 08676 user->encmethods = iax2_encryption; 08677 user->adsi = adsi; 08678 ast_string_field_set(user, name, name); 08679 ast_string_field_set(user, language, language); 08680 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08681 ast_clear_flag(user, IAX_HASCALLERID); 08682 ast_string_field_set(user, cid_name, ""); 08683 ast_string_field_set(user, cid_num, ""); 08684 } 08685 if (!v) { 08686 v = alt; 08687 alt = NULL; 08688 } 08689 while(v) { 08690 if (!strcasecmp(v->name, "context")) { 08691 con = build_context(v->value); 08692 if (con) { 08693 if (conl) 08694 conl->next = con; 08695 else 08696 user->contexts = con; 08697 conl = con; 08698 } 08699 } else if (!strcasecmp(v->name, "permit") || 08700 !strcasecmp(v->name, "deny")) { 08701 user->ha = ast_append_ha(v->name, v->value, user->ha); 08702 } else if (!strcasecmp(v->name, "setvar")) { 08703 varname = ast_strdupa(v->value); 08704 if (varname && (varval = strchr(varname,'='))) { 08705 *varval = '\0'; 08706 varval++; 08707 if((tmpvar = ast_variable_new(varname, varval))) { 08708 tmpvar->next = user->vars; 08709 user->vars = tmpvar; 08710 } 08711 } 08712 } else if (!strcasecmp(v->name, "allow")) { 08713 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08714 } else if (!strcasecmp(v->name, "disallow")) { 08715 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08716 } else if (!strcasecmp(v->name, "trunk")) { 08717 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08718 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08719 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08720 ast_clear_flag(user, IAX_TRUNK); 08721 } 08722 } else if (!strcasecmp(v->name, "auth")) { 08723 user->authmethods = get_auth_methods(v->value); 08724 } else if (!strcasecmp(v->name, "encryption")) { 08725 user->encmethods = get_encrypt_methods(v->value); 08726 } else if (!strcasecmp(v->name, "notransfer")) { 08727 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 08728 ast_clear_flag(user, IAX_TRANSFERMEDIA); 08729 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08730 } else if (!strcasecmp(v->name, "transfer")) { 08731 if (!strcasecmp(v->value, "mediaonly")) { 08732 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 08733 } else if (ast_true(v->value)) { 08734 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 08735 } else 08736 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 08737 } else if (!strcasecmp(v->name, "codecpriority")) { 08738 if(!strcasecmp(v->value, "caller")) 08739 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08740 else if(!strcasecmp(v->value, "disabled")) 08741 ast_set_flag(user, IAX_CODEC_NOPREFS); 08742 else if(!strcasecmp(v->value, "reqonly")) { 08743 ast_set_flag(user, IAX_CODEC_NOCAP); 08744 ast_set_flag(user, IAX_CODEC_NOPREFS); 08745 } 08746 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08747 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08748 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08749 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08750 } else if (!strcasecmp(v->name, "dbsecret")) { 08751 ast_string_field_set(user, dbsecret, v->value); 08752 } else if (!strcasecmp(v->name, "secret")) { 08753 if (!ast_strlen_zero(user->secret)) { 08754 char *old = ast_strdupa(user->secret); 08755 08756 ast_string_field_build(user, secret, "%s;%s", old, v->value); 08757 } else 08758 ast_string_field_set(user, secret, v->value); 08759 } else if (!strcasecmp(v->name, "callerid")) { 08760 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 08761 char name2[80]; 08762 char num2[80]; 08763 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 08764 ast_string_field_set(user, cid_name, name2); 08765 ast_string_field_set(user, cid_num, num2); 08766 ast_set_flag(user, IAX_HASCALLERID); 08767 } else { 08768 ast_clear_flag(user, IAX_HASCALLERID); 08769 ast_string_field_set(user, cid_name, ""); 08770 ast_string_field_set(user, cid_num, ""); 08771 } 08772 } else if (!strcasecmp(v->name, "fullname")) { 08773 if (!ast_strlen_zero(v->value)) { 08774 ast_string_field_set(user, cid_name, v->value); 08775 ast_set_flag(user, IAX_HASCALLERID); 08776 } else { 08777 ast_string_field_set(user, cid_name, ""); 08778 if (ast_strlen_zero(user->cid_num)) 08779 ast_clear_flag(user, IAX_HASCALLERID); 08780 } 08781 } else if (!strcasecmp(v->name, "cid_number")) { 08782 if (!ast_strlen_zero(v->value)) { 08783 ast_string_field_set(user, cid_num, v->value); 08784 ast_set_flag(user, IAX_HASCALLERID); 08785 } else { 08786 ast_string_field_set(user, cid_num, ""); 08787 if (ast_strlen_zero(user->cid_name)) 08788 ast_clear_flag(user, IAX_HASCALLERID); 08789 } 08790 } else if (!strcasecmp(v->name, "accountcode")) { 08791 ast_string_field_set(user, accountcode, v->value); 08792 } else if (!strcasecmp(v->name, "mohinterpret")) { 08793 ast_string_field_set(user, mohinterpret, v->value); 08794 } else if (!strcasecmp(v->name, "mohsuggest")) { 08795 ast_string_field_set(user, mohsuggest, v->value); 08796 } else if (!strcasecmp(v->name, "language")) { 08797 ast_string_field_set(user, language, v->value); 08798 } else if (!strcasecmp(v->name, "amaflags")) { 08799 format = ast_cdr_amaflags2int(v->value); 08800 if (format < 0) { 08801 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08802 } else { 08803 user->amaflags = format; 08804 } 08805 } else if (!strcasecmp(v->name, "inkeys")) { 08806 ast_string_field_set(user, inkeys, v->value); 08807 } else if (!strcasecmp(v->name, "maxauthreq")) { 08808 user->maxauthreq = atoi(v->value); 08809 if (user->maxauthreq < 0) 08810 user->maxauthreq = 0; 08811 } else if (!strcasecmp(v->name, "adsi")) { 08812 user->adsi = ast_true(v->value); 08813 }/* else if (strcasecmp(v->name,"type")) */ 08814 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08815 v = v->next; 08816 if (!v) { 08817 v = alt; 08818 alt = NULL; 08819 } 08820 } 08821 if (!user->authmethods) { 08822 if (!ast_strlen_zero(user->secret)) { 08823 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08824 if (!ast_strlen_zero(user->inkeys)) 08825 user->authmethods |= IAX_AUTH_RSA; 08826 } else if (!ast_strlen_zero(user->inkeys)) { 08827 user->authmethods = IAX_AUTH_RSA; 08828 } else { 08829 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08830 } 08831 } 08832 ast_clear_flag(user, IAX_DELME); 08833 } 08834 if (oldha) 08835 ast_free_ha(oldha); 08836 if (oldcon) 08837 free_context(oldcon); 08838 return user; 08839 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 9363 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, 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, parse_dial_string(), and send_command().
Referenced by find_cache().
09364 { 09365 struct sockaddr_in sin; 09366 int x; 09367 int callno; 09368 struct iax_ie_data ied; 09369 struct create_addr_info cai; 09370 struct parsed_dial_string pds; 09371 char *tmpstr; 09372 09373 for (x=0; x<IAX_MAX_CALLS; x++) { 09374 /* Look for an *exact match* call. Once a call is negotiated, it can only 09375 look up entries for a single context */ 09376 if (!ast_mutex_trylock(&iaxsl[x])) { 09377 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 09378 return x; 09379 ast_mutex_unlock(&iaxsl[x]); 09380 } 09381 } 09382 09383 /* No match found, we need to create a new one */ 09384 09385 memset(&cai, 0, sizeof(cai)); 09386 memset(&ied, 0, sizeof(ied)); 09387 memset(&pds, 0, sizeof(pds)); 09388 09389 tmpstr = ast_strdupa(data); 09390 parse_dial_string(tmpstr, &pds); 09391 09392 /* Populate our address from the given */ 09393 if (create_addr(pds.peer, &sin, &cai)) 09394 return -1; 09395 09396 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 09397 pds.peer, pds.username, pds.password, pds.context); 09398 09399 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 09400 if (callno < 1) { 09401 ast_log(LOG_WARNING, "Unable to create call\n"); 09402 return -1; 09403 } 09404 09405 ast_mutex_lock(&iaxsl[callno]); 09406 ast_string_field_set(iaxs[callno], dproot, data); 09407 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 09408 09409 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 09410 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 09411 /* the string format is slightly different from a standard dial string, 09412 because the context appears in the 'exten' position 09413 */ 09414 if (pds.exten) 09415 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 09416 if (pds.username) 09417 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 09418 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 09419 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 09420 /* Keep password handy */ 09421 if (pds.password) 09422 ast_string_field_set(iaxs[callno], secret, pds.password); 09423 if (pds.key) 09424 ast_string_field_set(iaxs[callno], outkey, pds.key); 09425 /* Start the call going */ 09426 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 09427 09428 return callno; 09429 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3529 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03530 { 03531 /* Returns where in "receive time" we are. That is, how many ms 03532 since we received (or would have received) the frame with timestamp 0 */ 03533 int ms; 03534 #ifdef IAXTESTS 03535 int jit; 03536 #endif /* IAXTESTS */ 03537 /* Setup rxcore if necessary */ 03538 if (ast_tvzero(p->rxcore)) { 03539 p->rxcore = ast_tvnow(); 03540 if (option_debug && iaxdebug) 03541 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03542 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03543 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03544 #if 1 03545 if (option_debug && iaxdebug) 03546 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03547 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03548 #endif 03549 } 03550 03551 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03552 #ifdef IAXTESTS 03553 if (test_jit) { 03554 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03555 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03556 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03557 jit = -jit; 03558 ms += jit; 03559 } 03560 } 03561 if (test_late) { 03562 ms += test_late; 03563 test_late = 0; 03564 } 03565 #endif /* IAXTESTS */ 03566 return ms; 03567 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3411 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, 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().
03412 { 03413 int ms; 03414 int voice = 0; 03415 int genuine = 0; 03416 int adjust; 03417 struct timeval *delivery = NULL; 03418 03419 03420 /* What sort of frame do we have?: voice is self-explanatory 03421 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03422 non-genuine frames are CONTROL frames [ringing etc], DTMF 03423 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03424 the others need a timestamp slaved to the voice frames so that they go in sequence 03425 */ 03426 if (f) { 03427 if (f->frametype == AST_FRAME_VOICE) { 03428 voice = 1; 03429 delivery = &f->delivery; 03430 } else if (f->frametype == AST_FRAME_IAX) { 03431 genuine = 1; 03432 } else if (f->frametype == AST_FRAME_CNG) { 03433 p->notsilenttx = 0; 03434 } 03435 } 03436 if (ast_tvzero(p->offset)) { 03437 gettimeofday(&p->offset, NULL); 03438 /* Round to nearest 20ms for nice looking traces */ 03439 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03440 } 03441 /* If the timestamp is specified, just send it as is */ 03442 if (ts) 03443 return ts; 03444 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03445 if (delivery && !ast_tvzero(*delivery)) { 03446 ms = ast_tvdiff_ms(*delivery, p->offset); 03447 if (option_debug > 2 && iaxdebug) 03448 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03449 } else { 03450 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03451 if (ms < 0) 03452 ms = 0; 03453 if (voice) { 03454 /* On a voice frame, use predicted values if appropriate */ 03455 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03456 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03457 /* AN EXPLANATION: 03458 When we send voice, we usually send "calculated" timestamps worked out 03459 on the basis of the number of samples sent. When we send other frames, 03460 we usually send timestamps worked out from the real clock. 03461 The problem is that they can tend to drift out of step because the 03462 source channel's clock and our clock may not be exactly at the same rate. 03463 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03464 for this call. Moving it adjusts timestamps for non-voice frames. 03465 We make the adjustment in the style of a moving average. Each time we 03466 adjust p->offset by 10% of the difference between our clock-derived 03467 timestamp and the predicted timestamp. That's why you see "10000" 03468 below even though IAX2 timestamps are in milliseconds. 03469 The use of a moving average avoids offset moving too radically. 03470 Generally, "adjust" roams back and forth around 0, with offset hardly 03471 changing at all. But if a consistent different starts to develop it 03472 will be eliminated over the course of 10 frames (200-300msecs) 03473 */ 03474 adjust = (ms - p->nextpred); 03475 if (adjust < 0) 03476 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03477 else if (adjust > 0) 03478 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03479 03480 if (!p->nextpred) { 03481 p->nextpred = ms; /*f->samples / 8;*/ 03482 if (p->nextpred <= p->lastsent) 03483 p->nextpred = p->lastsent + 3; 03484 } 03485 ms = p->nextpred; 03486 } else { 03487 /* in this case, just use the actual 03488 * time, since we're either way off 03489 * (shouldn't happen), or we're ending a 03490 * silent period -- and seed the next 03491 * predicted time. Also, round ms to the 03492 * next multiple of frame size (so our 03493 * silent periods are multiples of 03494 * frame size too) */ 03495 03496 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03497 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03498 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03499 03500 if (f->samples >= 8) /* check to make sure we dont core dump */ 03501 { 03502 int diff = ms % (f->samples / 8); 03503 if (diff) 03504 ms += f->samples/8 - diff; 03505 } 03506 03507 p->nextpred = ms; 03508 p->notsilenttx = 1; 03509 } 03510 } else { 03511 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03512 it's a genuine frame */ 03513 if (genuine) { 03514 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03515 if (ms <= p->lastsent) 03516 ms = p->lastsent + 3; 03517 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03518 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03519 ms = p->lastsent + 3; 03520 } 03521 } 03522 } 03523 p->lastsent = ms; 03524 if (voice) 03525 p->nextpred = p->nextpred + f->samples / 8; 03526 return ms; 03527 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3367 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().
03368 { 03369 unsigned long int mssincetx; /* unsigned to handle overflows */ 03370 long int ms, pred; 03371 03372 tpeer->trunkact = *tv; 03373 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03374 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03375 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03376 tpeer->txtrunktime = *tv; 03377 tpeer->lastsent = 999999; 03378 } 03379 /* Update last transmit time now */ 03380 tpeer->lasttxtime = *tv; 03381 03382 /* Calculate ms offset */ 03383 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03384 /* Predict from last value */ 03385 pred = tpeer->lastsent + sampms; 03386 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03387 ms = pred; 03388 03389 /* We never send the same timestamp twice, so fudge a little if we must */ 03390 if (ms == tpeer->lastsent) 03391 ms = tpeer->lastsent + 1; 03392 tpeer->lastsent = ms; 03393 return ms; 03394 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4615 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, destroy_user(), 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_TEMPONLY, 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(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
04616 { 04617 /* Start pessimistic */ 04618 int res = -1; 04619 int version = 2; 04620 struct iax2_user *user = NULL, *best = NULL; 04621 int bestscore = 0; 04622 int gotcapability = 0; 04623 struct ast_variable *v = NULL, *tmpvar = NULL; 04624 04625 if (!iaxs[callno]) 04626 return res; 04627 if (ies->called_number) 04628 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04629 if (ies->calling_number) { 04630 ast_shrink_phone_number(ies->calling_number); 04631 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04632 } 04633 if (ies->calling_name) 04634 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04635 if (ies->calling_ani) 04636 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04637 if (ies->dnid) 04638 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04639 if (ies->rdnis) 04640 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04641 if (ies->called_context) 04642 ast_string_field_set(iaxs[callno], context, ies->called_context); 04643 if (ies->language) 04644 ast_string_field_set(iaxs[callno], language, ies->language); 04645 if (ies->username) 04646 ast_string_field_set(iaxs[callno], username, ies->username); 04647 if (ies->calling_ton > -1) 04648 iaxs[callno]->calling_ton = ies->calling_ton; 04649 if (ies->calling_tns > -1) 04650 iaxs[callno]->calling_tns = ies->calling_tns; 04651 if (ies->calling_pres > -1) 04652 iaxs[callno]->calling_pres = ies->calling_pres; 04653 if (ies->format) 04654 iaxs[callno]->peerformat = ies->format; 04655 if (ies->adsicpe) 04656 iaxs[callno]->peeradsicpe = ies->adsicpe; 04657 if (ies->capability) { 04658 gotcapability = 1; 04659 iaxs[callno]->peercapability = ies->capability; 04660 } 04661 if (ies->version) 04662 version = ies->version; 04663 04664 /* Use provided preferences until told otherwise for actual preferences */ 04665 if(ies->codec_prefs) { 04666 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04667 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04668 } 04669 04670 if (!gotcapability) 04671 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04672 if (version > IAX_PROTO_VERSION) { 04673 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04674 ast_inet_ntoa(sin->sin_addr), version); 04675 return res; 04676 } 04677 /* Search the userlist for a compatible entry, and fill in the rest */ 04678 AST_LIST_LOCK(&users); 04679 AST_LIST_TRAVERSE(&users, user, entry) { 04680 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04681 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04682 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04683 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04684 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04685 if (!ast_strlen_zero(iaxs[callno]->username)) { 04686 /* Exact match, stop right now. */ 04687 best = user; 04688 break; 04689 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04690 /* No required authentication */ 04691 if (user->ha) { 04692 /* There was host authentication and we passed, bonus! */ 04693 if (bestscore < 4) { 04694 bestscore = 4; 04695 best = user; 04696 } 04697 } else { 04698 /* No host access, but no secret, either, not bad */ 04699 if (bestscore < 3) { 04700 bestscore = 3; 04701 best = user; 04702 } 04703 } 04704 } else { 04705 if (user->ha) { 04706 /* Authentication, but host access too, eh, it's something.. */ 04707 if (bestscore < 2) { 04708 bestscore = 2; 04709 best = user; 04710 } 04711 } else { 04712 /* Authentication and no host access... This is our baseline */ 04713 if (bestscore < 1) { 04714 bestscore = 1; 04715 best = user; 04716 } 04717 } 04718 } 04719 } 04720 } 04721 AST_LIST_UNLOCK(&users); 04722 user = best; 04723 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 04724 user = realtime_user(iaxs[callno]->username); 04725 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04726 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04727 destroy_user(user); 04728 user = NULL; 04729 } 04730 } 04731 if (user) { 04732 /* We found our match (use the first) */ 04733 /* copy vars */ 04734 for (v = user->vars ; v ; v = v->next) { 04735 if((tmpvar = ast_variable_new(v->name, v->value))) { 04736 tmpvar->next = iaxs[callno]->vars; 04737 iaxs[callno]->vars = tmpvar; 04738 } 04739 } 04740 /* If a max AUTHREQ restriction is in place, activate it */ 04741 if (user->maxauthreq > 0) 04742 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 04743 iaxs[callno]->prefs = user->prefs; 04744 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04745 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04746 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04747 iaxs[callno]->encmethods = user->encmethods; 04748 /* Store the requested username if not specified */ 04749 if (ast_strlen_zero(iaxs[callno]->username)) 04750 ast_string_field_set(iaxs[callno], username, user->name); 04751 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04752 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04753 iaxs[callno]->capability = user->capability; 04754 /* And use the default context */ 04755 if (ast_strlen_zero(iaxs[callno]->context)) { 04756 if (user->contexts) 04757 ast_string_field_set(iaxs[callno], context, user->contexts->context); 04758 else 04759 ast_string_field_set(iaxs[callno], context, context); 04760 } 04761 /* And any input keys */ 04762 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 04763 /* And the permitted authentication methods */ 04764 iaxs[callno]->authmethods = user->authmethods; 04765 iaxs[callno]->adsi = user->adsi; 04766 /* If they have callerid, override the given caller id. Always store the ANI */ 04767 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 04768 if (ast_test_flag(user, IAX_HASCALLERID)) { 04769 iaxs[callno]->calling_tns = 0; 04770 iaxs[callno]->calling_ton = 0; 04771 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 04772 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 04773 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 04774 } 04775 if (ast_strlen_zero(iaxs[callno]->ani)) 04776 ast_string_field_set(iaxs[callno], ani, user->cid_num); 04777 } else { 04778 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 04779 } 04780 if (!ast_strlen_zero(user->accountcode)) 04781 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 04782 if (!ast_strlen_zero(user->mohinterpret)) 04783 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 04784 if (!ast_strlen_zero(user->mohsuggest)) 04785 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 04786 if (user->amaflags) 04787 iaxs[callno]->amaflags = user->amaflags; 04788 if (!ast_strlen_zero(user->language)) 04789 ast_string_field_set(iaxs[callno], language, user->language); 04790 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04791 /* Keep this check last */ 04792 if (!ast_strlen_zero(user->dbsecret)) { 04793 char *family, *key=NULL; 04794 char buf[80]; 04795 family = ast_strdupa(user->dbsecret); 04796 key = strchr(family, '/'); 04797 if (key) { 04798 *key = '\0'; 04799 key++; 04800 } 04801 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 04802 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 04803 else 04804 ast_string_field_set(iaxs[callno], secret, buf); 04805 } else 04806 ast_string_field_set(iaxs[callno], secret, user->secret); 04807 if (ast_test_flag(user, IAX_TEMPONLY)) 04808 destroy_user(user); 04809 res = 0; 04810 } 04811 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 04812 return res; 04813 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6210 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06211 { 06212 unsigned int ourver; 06213 char rsi[80]; 06214 snprintf(rsi, sizeof(rsi), "si-%s", si); 06215 if (iax_provision_version(&ourver, rsi, 1)) 06216 return 0; 06217 if (option_debug) 06218 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06219 if (ourver != ver) 06220 iax2_provision(sin, sockfd, NULL, rsi, 1); 06221 return 0; 06222 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 8281 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by peer_set_srcaddr().
08282 { 08283 int sd; 08284 int res; 08285 08286 sd = socket(AF_INET, SOCK_DGRAM, 0); 08287 if (sd < 0) { 08288 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08289 return -1; 08290 } 08291 08292 res = bind(sd, sa, salen); 08293 if (res < 0) { 08294 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08295 close(sd); 08296 return 1; 08297 } 08298 08299 close(sd); 08300 return 0; 08301 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5280 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, 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().
05281 { 05282 char exten[256] = ""; 05283 int status = CACHE_FLAG_UNKNOWN; 05284 int expiry = iaxdefaultdpcache; 05285 int x; 05286 int matchmore = 0; 05287 struct iax2_dpcache *dp, *prev; 05288 05289 if (ies->called_number) 05290 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05291 05292 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05293 status = CACHE_FLAG_EXISTS; 05294 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05295 status = CACHE_FLAG_CANEXIST; 05296 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05297 status = CACHE_FLAG_NONEXISTENT; 05298 05299 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05300 /* Don't really do anything with this */ 05301 } 05302 if (ies->refresh) 05303 expiry = ies->refresh; 05304 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05305 matchmore = CACHE_FLAG_MATCHMORE; 05306 ast_mutex_lock(&dpcache_lock); 05307 prev = NULL; 05308 dp = pvt->dpentries; 05309 while(dp) { 05310 if (!strcmp(dp->exten, exten)) { 05311 /* Let them go */ 05312 if (prev) 05313 prev->peer = dp->peer; 05314 else 05315 pvt->dpentries = dp->peer; 05316 dp->peer = NULL; 05317 dp->callno = 0; 05318 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05319 if (dp->flags & CACHE_FLAG_PENDING) { 05320 dp->flags &= ~CACHE_FLAG_PENDING; 05321 dp->flags |= status; 05322 dp->flags |= matchmore; 05323 } 05324 /* Wake up waiters */ 05325 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05326 if (dp->waiters[x] > -1) 05327 write(dp->waiters[x], "asdf", 4); 05328 } 05329 prev = dp; 05330 dp = dp->peer; 05331 } 05332 ast_mutex_unlock(&dpcache_lock); 05333 return 0; 05334 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2078 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
02079 { 02080 int which = 0; 02081 struct iax2_peer *p = NULL; 02082 char *res = NULL; 02083 int wordlen = strlen(word); 02084 02085 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02086 if (pos == 3) { 02087 AST_LIST_LOCK(&peers); 02088 AST_LIST_TRAVERSE(&peers, p, entry) { 02089 if (!strncasecmp(p->name, word, wordlen) && ++which > state) { 02090 res = ast_strdup(p->name); 02091 break; 02092 } 02093 } 02094 AST_LIST_UNLOCK(&peers); 02095 } 02096 02097 return res; 02098 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5336 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().
05337 { 05338 int peercallno = 0; 05339 struct chan_iax2_pvt *pvt = iaxs[callno]; 05340 struct iax_frame *cur; 05341 jb_frame frame; 05342 05343 if (ies->callno) 05344 peercallno = ies->callno; 05345 05346 if (peercallno < 1) { 05347 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05348 return -1; 05349 } 05350 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05351 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05352 /* Reset sequence numbers */ 05353 pvt->oseqno = 0; 05354 pvt->rseqno = 0; 05355 pvt->iseqno = 0; 05356 pvt->aseqno = 0; 05357 pvt->peercallno = peercallno; 05358 pvt->transferring = TRANSFER_NONE; 05359 pvt->svoiceformat = -1; 05360 pvt->voiceformat = 0; 05361 pvt->svideoformat = -1; 05362 pvt->videoformat = 0; 05363 pvt->transfercallno = -1; 05364 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05365 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05366 /* reset jitterbuffer */ 05367 while(jb_getall(pvt->jb,&frame) == JB_OK) 05368 iax2_frame_free(frame.data); 05369 jb_reset(pvt->jb); 05370 pvt->lag = 0; 05371 pvt->last = 0; 05372 pvt->lastsent = 0; 05373 pvt->nextpred = 0; 05374 pvt->pingtime = DEFAULT_RETRY_TIME; 05375 AST_LIST_LOCK(&iaxq.queue); 05376 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05377 /* We must cancel any packets that would have been transmitted 05378 because now we're talking to someone new. It's okay, they 05379 were transmitted to someone that didn't care anyway. */ 05380 if (callno == cur->callno) 05381 cur->retries = -1; 05382 } 05383 AST_LIST_UNLOCK(&iaxq.queue); 05384 return 0; 05385 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 969 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().
00970 { 00971 int x; 00972 int power=-1; 00973 /* If it's 128 or smaller, just return it */ 00974 if (subclass < IAX_FLAG_SC_LOG) 00975 return subclass; 00976 /* Otherwise find its power */ 00977 for (x = 0; x < IAX_MAX_SHIFT; x++) { 00978 if (subclass & (1 << x)) { 00979 if (power > -1) { 00980 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 00981 return 0; 00982 } else 00983 power = x; 00984 } 00985 } 00986 return power | IAX_FLAG_SC_LOG; 00987 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6224 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().
06225 { 06226 jb_info stats; 06227 jb_getinfo(pvt->jb, &stats); 06228 06229 memset(iep, 0, sizeof(*iep)); 06230 06231 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06232 if(stats.frames_in == 0) stats.frames_in = 1; 06233 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06234 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06235 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06236 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06237 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06238 }
static int create_addr | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2623 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_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, destroy_peer(), iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TEMPONLY, 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, create_addr_info::outkey, 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.
02624 { 02625 struct ast_hostent ahp; 02626 struct hostent *hp; 02627 struct iax2_peer *peer; 02628 02629 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02630 cai->sockfd = defaultsockfd; 02631 cai->maxtime = 0; 02632 sin->sin_family = AF_INET; 02633 02634 if (!(peer = find_peer(peername, 1))) { 02635 cai->found = 0; 02636 02637 hp = ast_gethostbyname(peername, &ahp); 02638 if (hp) { 02639 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02640 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02641 /* use global iax prefs for unknown peer/user */ 02642 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02643 return 0; 02644 } else { 02645 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02646 return -1; 02647 } 02648 } 02649 02650 cai->found = 1; 02651 02652 /* if the peer has no address (current or default), return failure */ 02653 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 02654 if (ast_test_flag(peer, IAX_TEMPONLY)) 02655 destroy_peer(peer); 02656 return -1; 02657 } 02658 02659 /* if the peer is being monitored and is currently unreachable, return failure */ 02660 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) { 02661 if (ast_test_flag(peer, IAX_TEMPONLY)) 02662 destroy_peer(peer); 02663 return -1; 02664 } 02665 02666 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02667 cai->maxtime = peer->maxms; 02668 cai->capability = peer->capability; 02669 cai->encmethods = peer->encmethods; 02670 cai->sockfd = peer->sockfd; 02671 cai->adsi = peer->adsi; 02672 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02673 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02674 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02675 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02676 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02677 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02678 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02679 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02680 if (ast_strlen_zero(peer->dbsecret)) { 02681 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02682 } else { 02683 char *family; 02684 char *key = NULL; 02685 02686 family = ast_strdupa(peer->dbsecret); 02687 key = strchr(family, '/'); 02688 if (key) 02689 *key++ = '\0'; 02690 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02691 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02692 if (ast_test_flag(peer, IAX_TEMPONLY)) 02693 destroy_peer(peer); 02694 return -1; 02695 } 02696 } 02697 02698 if (peer->addr.sin_addr.s_addr) { 02699 sin->sin_addr = peer->addr.sin_addr; 02700 sin->sin_port = peer->addr.sin_port; 02701 } else { 02702 sin->sin_addr = peer->defaddr.sin_addr; 02703 sin->sin_port = peer->defaddr.sin_port; 02704 } 02705 02706 if (ast_test_flag(peer, IAX_TEMPONLY)) 02707 destroy_peer(peer); 02708 02709 return 0; 02710 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3713 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().
03714 { 03715 int padding; 03716 unsigned char *workspace; 03717 03718 workspace = alloca(*datalen); 03719 memset(f, 0, sizeof(*f)); 03720 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03721 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03722 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03723 return -1; 03724 /* Decrypt */ 03725 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03726 03727 padding = 16 + (workspace[15] & 0xf); 03728 if (option_debug && iaxdebug) 03729 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03730 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03731 return -1; 03732 03733 *datalen -= padding; 03734 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03735 f->frametype = fh->type; 03736 if (f->frametype == AST_FRAME_VIDEO) { 03737 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03738 } else { 03739 f->subclass = uncompress_subclass(fh->csub); 03740 } 03741 } else { 03742 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03743 if (option_debug && iaxdebug) 03744 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03745 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03746 return -1; 03747 /* Decrypt */ 03748 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03749 padding = 16 + (workspace[15] & 0x0f); 03750 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03751 return -1; 03752 *datalen -= padding; 03753 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03754 } 03755 return 0; 03756 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3799 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(), and strsep().
Referenced by socket_process().
03800 { 03801 int res=-1; 03802 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 03803 /* Search for possible keys, given secrets */ 03804 struct MD5Context md5; 03805 unsigned char digest[16]; 03806 char *tmppw, *stringp; 03807 03808 tmppw = ast_strdupa(iaxs[callno]->secret); 03809 stringp = tmppw; 03810 while ((tmppw = strsep(&stringp, ";"))) { 03811 MD5Init(&md5); 03812 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 03813 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 03814 MD5Final(digest, &md5); 03815 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 03816 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03817 if (!res) { 03818 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 03819 break; 03820 } 03821 } 03822 } else 03823 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03824 return res; 03825 }
static void delete_users | ( | void | ) | [static] |
Definition at line 8841 of file chan_iax2.c.
References ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, free, iax2_destroy(), IAX_DELME, iaxs, iaxsl, chan_iax2_pvt::reg, and sched.
08842 { 08843 struct iax2_user *user; 08844 struct iax2_peer *peer; 08845 struct iax2_registry *reg; 08846 08847 AST_LIST_LOCK(&users); 08848 AST_LIST_TRAVERSE(&users, user, entry) 08849 ast_set_flag(user, IAX_DELME); 08850 AST_LIST_UNLOCK(&users); 08851 08852 AST_LIST_LOCK(®istrations); 08853 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 08854 if (reg->expire > -1) 08855 ast_sched_del(sched, reg->expire); 08856 if (reg->callno) { 08857 ast_mutex_lock(&iaxsl[reg->callno]); 08858 if (iaxs[reg->callno]) { 08859 iaxs[reg->callno]->reg = NULL; 08860 iax2_destroy(reg->callno); 08861 } 08862 ast_mutex_unlock(&iaxsl[reg->callno]); 08863 } 08864 if (reg->dnsmgr) 08865 ast_dnsmgr_release(reg->dnsmgr); 08866 free(reg); 08867 } 08868 AST_LIST_UNLOCK(®istrations); 08869 08870 AST_LIST_LOCK(&peers); 08871 AST_LIST_TRAVERSE(&peers, peer, entry) 08872 ast_set_flag(peer, IAX_DELME); 08873 AST_LIST_UNLOCK(&peers); 08874 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1329 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01330 { 01331 /* Close firmware */ 01332 if (cur->fwh) { 01333 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01334 } 01335 close(cur->fd); 01336 free(cur); 01337 }
static void destroy_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8904 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_string_field_free_pools, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::expire, free, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::pokeexpire, register_peer_exten(), and sched.
Referenced by authenticate_reply(), create_addr(), iax2_devicestate(), iax2_getpeername(), iax2_show_peer(), prune_peers(), realtime_peer(), register_verify(), registry_authrequest(), and update_registry().
08905 { 08906 ast_free_ha(peer->ha); 08907 08908 /* Delete it, it needs to disappear */ 08909 if (peer->expire > -1) 08910 ast_sched_del(sched, peer->expire); 08911 if (peer->pokeexpire > -1) 08912 ast_sched_del(sched, peer->pokeexpire); 08913 if (peer->callno > 0) { 08914 ast_mutex_lock(&iaxsl[peer->callno]); 08915 iax2_destroy(peer->callno); 08916 ast_mutex_unlock(&iaxsl[peer->callno]); 08917 } 08918 08919 register_peer_exten(peer, 0); 08920 08921 if (peer->dnsmgr) 08922 ast_dnsmgr_release(peer->dnsmgr); 08923 08924 ast_string_field_free_pools(peer); 08925 08926 free(peer); 08927 }
static void destroy_user | ( | struct iax2_user * | user | ) | [static] |
Definition at line 8876 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_pools, ast_variables_destroy(), iax2_user::contexts, free, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by check_access(), and prune_users().
08877 { 08878 ast_free_ha(user->ha); 08879 free_context(user->contexts); 08880 if(user->vars) { 08881 ast_variables_destroy(user->vars); 08882 user->vars = NULL; 08883 } 08884 ast_string_field_free_pools(user); 08885 free(user); 08886 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6058 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().
06059 { 06060 unsigned short dpstatus = 0; 06061 struct iax_ie_data ied1; 06062 int mm; 06063 06064 memset(&ied1, 0, sizeof(ied1)); 06065 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06066 /* Must be started */ 06067 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06068 dpstatus = IAX_DPSTATUS_EXISTS; 06069 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06070 dpstatus = IAX_DPSTATUS_CANEXIST; 06071 } else { 06072 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06073 } 06074 if (ast_ignore_pattern(context, callednum)) 06075 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06076 if (mm) 06077 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06078 if (!skiplock) 06079 ast_mutex_lock(&iaxsl[callno]); 06080 if (iaxs[callno]) { 06081 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06082 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06083 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06084 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06085 } 06086 if (!skiplock) 06087 ast_mutex_unlock(&iaxsl[callno]); 06088 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6090 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().
06091 { 06092 /* Look up for dpreq */ 06093 struct dpreq_data *dpr = data; 06094 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06095 if (dpr->callerid) 06096 free(dpr->callerid); 06097 free(dpr); 06098 return NULL; 06099 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 3758 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().
03759 { 03760 int padding; 03761 unsigned char *workspace; 03762 workspace = alloca(*datalen + 32); 03763 if (!workspace) 03764 return -1; 03765 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03766 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03767 if (option_debug && iaxdebug) 03768 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03769 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03770 padding = 16 + (padding & 0xf); 03771 memcpy(workspace, poo, padding); 03772 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03773 workspace[15] &= 0xf0; 03774 workspace[15] |= (padding & 0xf); 03775 if (option_debug && iaxdebug) 03776 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]); 03777 *datalen += padding; 03778 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03779 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03780 memcpy(poo, workspace + *datalen - 32, 32); 03781 } else { 03782 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03783 if (option_debug && iaxdebug) 03784 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03785 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03786 padding = 16 + (padding & 0xf); 03787 memcpy(workspace, poo, padding); 03788 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03789 workspace[15] &= 0xf0; 03790 workspace[15] |= (padding & 0x0f); 03791 *datalen += padding; 03792 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 03793 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 03794 memcpy(poo, workspace + *datalen - 32, 32); 03795 } 03796 return 0; 03797 }
static int expire_registry | ( | void * | data | ) | [static] |
Definition at line 5559 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
05560 { 05561 #ifdef SCHED_MULTITHREADED 05562 if (schedule_action(__expire_registry, data)) 05563 #endif 05564 __expire_registry(data); 05565 return 0; 05566 }
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 9431 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().
09432 { 09433 struct iax2_dpcache *dp, *prev = NULL, *next; 09434 struct timeval tv; 09435 int x; 09436 int com[2]; 09437 int timeout; 09438 int old=0; 09439 int outfd; 09440 int abort; 09441 int callno; 09442 struct ast_channel *c; 09443 struct ast_frame *f; 09444 gettimeofday(&tv, NULL); 09445 dp = dpcache; 09446 while(dp) { 09447 next = dp->next; 09448 /* Expire old caches */ 09449 if (ast_tvcmp(tv, dp->expiry) > 0) { 09450 /* It's expired, let it disappear */ 09451 if (prev) 09452 prev->next = dp->next; 09453 else 09454 dpcache = dp->next; 09455 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 09456 /* Free memory and go again */ 09457 free(dp); 09458 } else { 09459 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); 09460 } 09461 dp = next; 09462 continue; 09463 } 09464 /* We found an entry that matches us! */ 09465 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 09466 break; 09467 prev = dp; 09468 dp = next; 09469 } 09470 if (!dp) { 09471 /* No matching entry. Create a new one. */ 09472 /* First, can we make a callno? */ 09473 callno = cache_get_callno_locked(data); 09474 if (callno < 0) { 09475 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09476 return NULL; 09477 } 09478 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 09479 ast_mutex_unlock(&iaxsl[callno]); 09480 return NULL; 09481 } 09482 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09483 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09484 gettimeofday(&dp->expiry, NULL); 09485 dp->orig = dp->expiry; 09486 /* Expires in 30 mins by default */ 09487 dp->expiry.tv_sec += iaxdefaultdpcache; 09488 dp->next = dpcache; 09489 dp->flags = CACHE_FLAG_PENDING; 09490 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09491 dp->waiters[x] = -1; 09492 dpcache = dp; 09493 dp->peer = iaxs[callno]->dpentries; 09494 iaxs[callno]->dpentries = dp; 09495 /* Send the request if we're already up */ 09496 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 09497 iax2_dprequest(dp, callno); 09498 ast_mutex_unlock(&iaxsl[callno]); 09499 } 09500 /* By here we must have a dp */ 09501 if (dp->flags & CACHE_FLAG_PENDING) { 09502 /* Okay, here it starts to get nasty. We need a pipe now to wait 09503 for a reply to come back so long as it's pending */ 09504 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09505 /* Find an empty slot */ 09506 if (dp->waiters[x] < 0) 09507 break; 09508 } 09509 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09510 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09511 return NULL; 09512 } 09513 if (pipe(com)) { 09514 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09515 return NULL; 09516 } 09517 dp->waiters[x] = com[1]; 09518 /* Okay, now we wait */ 09519 timeout = iaxdefaulttimeout * 1000; 09520 /* Temporarily unlock */ 09521 ast_mutex_unlock(&dpcache_lock); 09522 /* Defer any dtmf */ 09523 if (chan) 09524 old = ast_channel_defer_dtmf(chan); 09525 abort = 0; 09526 while(timeout) { 09527 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09528 if (outfd > -1) { 09529 break; 09530 } 09531 if (c) { 09532 f = ast_read(c); 09533 if (f) 09534 ast_frfree(f); 09535 else { 09536 /* Got hung up on, abort! */ 09537 break; 09538 abort = 1; 09539 } 09540 } 09541 } 09542 if (!timeout) { 09543 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09544 } 09545 ast_mutex_lock(&dpcache_lock); 09546 dp->waiters[x] = -1; 09547 close(com[1]); 09548 close(com[0]); 09549 if (abort) { 09550 /* Don't interpret anything, just abort. Not sure what th epoint 09551 of undeferring dtmf on a hung up channel is but hey whatever */ 09552 if (!old && chan) 09553 ast_channel_undefer_dtmf(chan); 09554 return NULL; 09555 } 09556 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09557 /* Now to do non-independent analysis the results of our wait */ 09558 if (dp->flags & CACHE_FLAG_PENDING) { 09559 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09560 pending. Don't let it take as long to timeout. */ 09561 dp->flags &= ~CACHE_FLAG_PENDING; 09562 dp->flags |= CACHE_FLAG_TIMEOUT; 09563 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09564 systems without leaving it unavailable once the server comes back online */ 09565 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09566 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09567 if (dp->waiters[x] > -1) 09568 write(dp->waiters[x], "asdf", 4); 09569 } 09570 } 09571 /* Our caller will obtain the rest */ 09572 if (!old && chan) 09573 ast_channel_undefer_dtmf(chan); 09574 } 09575 return dp; 09576 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | lockpeer, | |||
int | sockfd | |||
) | [static] |
Definition at line 1219 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_sched_add(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), 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().
01220 { 01221 int res = 0; 01222 int x; 01223 struct timeval now; 01224 char host[80]; 01225 if (new <= NEW_ALLOW) { 01226 /* Look for an existing connection first */ 01227 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01228 ast_mutex_lock(&iaxsl[x]); 01229 if (iaxs[x]) { 01230 /* Look for an exact match */ 01231 if (match(sin, callno, dcallno, iaxs[x])) { 01232 res = x; 01233 } 01234 } 01235 ast_mutex_unlock(&iaxsl[x]); 01236 } 01237 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01238 ast_mutex_lock(&iaxsl[x]); 01239 if (iaxs[x]) { 01240 /* Look for an exact match */ 01241 if (match(sin, callno, dcallno, iaxs[x])) { 01242 res = x; 01243 } 01244 } 01245 ast_mutex_unlock(&iaxsl[x]); 01246 } 01247 } 01248 if ((res < 1) && (new >= NEW_ALLOW)) { 01249 /* It may seem odd that we look through the peer list for a name for 01250 * this *incoming* call. Well, it is weird. However, users don't 01251 * have an IP address/port number that we can match against. So, 01252 * this is just checking for a peer that has that IP/port and 01253 * assuming that we have a user of the same name. This isn't always 01254 * correct, but it will be changed if needed after authentication. */ 01255 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) 01256 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01257 gettimeofday(&now, NULL); 01258 for (x=1;x<TRUNK_CALL_START;x++) { 01259 /* Find first unused call number that hasn't been used in a while */ 01260 ast_mutex_lock(&iaxsl[x]); 01261 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01262 ast_mutex_unlock(&iaxsl[x]); 01263 } 01264 /* We've still got lock held if we found a spot */ 01265 if (x >= TRUNK_CALL_START) { 01266 ast_log(LOG_WARNING, "No more space\n"); 01267 return 0; 01268 } 01269 iaxs[x] = new_iax(sin, lockpeer, host); 01270 update_max_nontrunk(); 01271 if (iaxs[x]) { 01272 if (option_debug && iaxdebug) 01273 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01274 iaxs[x]->sockfd = sockfd; 01275 iaxs[x]->addr.sin_port = sin->sin_port; 01276 iaxs[x]->addr.sin_family = sin->sin_family; 01277 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01278 iaxs[x]->peercallno = callno; 01279 iaxs[x]->callno = x; 01280 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01281 iaxs[x]->expiry = min_reg_expire; 01282 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01283 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01284 iaxs[x]->amaflags = amaflags; 01285 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01286 01287 ast_string_field_set(iaxs[x], accountcode, accountcode); 01288 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01289 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01290 } else { 01291 ast_log(LOG_WARNING, "Out of resources\n"); 01292 ast_mutex_unlock(&iaxsl[x]); 01293 return 0; 01294 } 01295 ast_mutex_unlock(&iaxsl[x]); 01296 res = x; 01297 } 01298 return res; 01299 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 844 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().
00845 { 00846 pthread_attr_t attr; 00847 struct iax2_thread *thread = NULL; 00848 00849 /* Pop the head of the list off */ 00850 AST_LIST_LOCK(&idle_list); 00851 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00852 AST_LIST_UNLOCK(&idle_list); 00853 00854 /* If no idle thread is available from the regular list, try dynamic */ 00855 if (thread == NULL) { 00856 AST_LIST_LOCK(&dynamic_list); 00857 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00858 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00859 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00860 /* We need to MAKE a thread! */ 00861 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00862 thread->threadnum = iaxdynamicthreadcount; 00863 thread->type = IAX_TYPE_DYNAMIC; 00864 ast_mutex_init(&thread->lock); 00865 ast_cond_init(&thread->cond, NULL); 00866 pthread_attr_init(&attr); 00867 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00868 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00869 free(thread); 00870 thread = NULL; 00871 } else { 00872 /* All went well and the thread is up, so increment our count */ 00873 iaxdynamicthreadcount++; 00874 } 00875 } 00876 } 00877 AST_LIST_UNLOCK(&dynamic_list); 00878 } 00879 00880 return thread; 00881 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1003 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and realtime_peer().
01004 { 01005 struct iax2_peer *peer = NULL; 01006 01007 /* Grab peer from linked list */ 01008 AST_LIST_LOCK(&peers); 01009 AST_LIST_TRAVERSE(&peers, peer, entry) { 01010 if (!strcasecmp(peer->name, name)) { 01011 break; 01012 } 01013 } 01014 AST_LIST_UNLOCK(&peers); 01015 01016 /* Now go for realtime if applicable */ 01017 if(!peer && realtime) 01018 peer = realtime_peer(name, NULL); 01019 return peer; 01020 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 3569 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().
03570 { 03571 struct iax2_trunk_peer *tpeer; 03572 03573 /* Finds and locks trunk peer */ 03574 ast_mutex_lock(&tpeerlock); 03575 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03576 /* We don't lock here because tpeer->addr *never* changes */ 03577 if (!inaddrcmp(&tpeer->addr, sin)) { 03578 ast_mutex_lock(&tpeer->lock); 03579 break; 03580 } 03581 } 03582 if (!tpeer) { 03583 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03584 ast_mutex_init(&tpeer->lock); 03585 tpeer->lastsent = 9999; 03586 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03587 tpeer->trunkact = ast_tvnow(); 03588 ast_mutex_lock(&tpeer->lock); 03589 tpeer->next = tpeers; 03590 tpeer->sockfd = fd; 03591 tpeers = tpeer; 03592 #ifdef SO_NO_CHECK 03593 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03594 #endif 03595 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03596 } 03597 } 03598 ast_mutex_unlock(&tpeerlock); 03599 return tpeer; 03600 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3396 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03397 { 03398 long ms; /* NOT unsigned */ 03399 if (ast_tvzero(iaxs[callno]->rxcore)) { 03400 /* Initialize rxcore time if appropriate */ 03401 gettimeofday(&iaxs[callno]->rxcore, NULL); 03402 /* Round to nearest 20ms so traces look pretty */ 03403 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03404 } 03405 /* Calculate difference between trunk and channel */ 03406 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03407 /* Return as the sum of trunk time and the difference between trunk and real time */ 03408 return ms + ts; 03409 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8039 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and destroy_user().
08040 { 08041 struct iax2_context *conl; 08042 while(con) { 08043 conl = con; 08044 con = con->next; 08045 free(conl); 08046 } 08047 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9700 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::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
09701 { 09702 struct iax2_peer *peer; 09703 char *peername, *colname; 09704 09705 peername = ast_strdupa(data); 09706 09707 /* if our channel, return the IP address of the endpoint of current channel */ 09708 if (!strcmp(peername,"CURRENTCHANNEL")) { 09709 unsigned short callno; 09710 if (chan->tech != &iax2_tech) 09711 return -1; 09712 callno = PTR_TO_CALLNO(chan->tech_pvt); 09713 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 09714 return 0; 09715 } 09716 09717 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 09718 *colname++ = '\0'; 09719 else if ((colname = strchr(peername, '|'))) 09720 *colname++ = '\0'; 09721 else 09722 colname = "ip"; 09723 09724 if (!(peer = find_peer(peername, 1))) 09725 return -1; 09726 09727 if (!strcasecmp(colname, "ip")) { 09728 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 09729 } else if (!strcasecmp(colname, "status")) { 09730 peer_status(peer, buf, len); 09731 } else if (!strcasecmp(colname, "mailbox")) { 09732 ast_copy_string(buf, peer->mailbox, len); 09733 } else if (!strcasecmp(colname, "context")) { 09734 ast_copy_string(buf, peer->context, len); 09735 } else if (!strcasecmp(colname, "expire")) { 09736 snprintf(buf, len, "%d", peer->expire); 09737 } else if (!strcasecmp(colname, "dynamic")) { 09738 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09739 } else if (!strcasecmp(colname, "callerid_name")) { 09740 ast_copy_string(buf, peer->cid_name, len); 09741 } else if (!strcasecmp(colname, "callerid_num")) { 09742 ast_copy_string(buf, peer->cid_num, len); 09743 } else if (!strcasecmp(colname, "codecs")) { 09744 ast_getformatname_multiple(buf, len -1, peer->capability); 09745 } else if (!strncasecmp(colname, "codec[", 6)) { 09746 char *codecnum, *ptr; 09747 int index = 0, codec = 0; 09748 09749 codecnum = strchr(colname, '['); 09750 *codecnum = '\0'; 09751 codecnum++; 09752 if ((ptr = strchr(codecnum, ']'))) { 09753 *ptr = '\0'; 09754 } 09755 index = atoi(codecnum); 09756 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09757 ast_copy_string(buf, ast_getformatname(codec), len); 09758 } 09759 } 09760 09761 return 0; 09762 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8265 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08266 { 08267 int methods = 0; 08268 if (strstr(value, "rsa")) 08269 methods |= IAX_AUTH_RSA; 08270 if (strstr(value, "md5")) 08271 methods |= IAX_AUTH_MD5; 08272 if (strstr(value, "plaintext")) 08273 methods |= IAX_AUTH_PLAINTEXT; 08274 return methods; 08275 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 934 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
00935 { 00936 int e; 00937 if (!strcasecmp(s, "aes128")) 00938 e = IAX_ENCRYPT_AES128; 00939 else if (ast_true(s)) 00940 e = IAX_ENCRYPT_AES128; 00941 else 00942 e = 0; 00943 return e; 00944 }
static int get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2309 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02310 { 02311 #ifdef SCHED_MULTITHREADED 02312 if (schedule_action(__get_from_jb, data)) 02313 #endif 02314 __get_from_jb(data); 02315 return 0; 02316 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1606 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
01607 { 01608 /* XXX Ideally we should figure out why an error occured and then abort those 01609 rather than continuing to try. Unfortunately, the published interface does 01610 not seem to work XXX */ 01611 #if 0 01612 struct sockaddr_in *sin; 01613 int res; 01614 struct msghdr m; 01615 struct sock_extended_err e; 01616 m.msg_name = NULL; 01617 m.msg_namelen = 0; 01618 m.msg_iov = NULL; 01619 m.msg_control = &e; 01620 m.msg_controllen = sizeof(e); 01621 m.msg_flags = 0; 01622 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01623 if (res < 0) 01624 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01625 else { 01626 if (m.msg_controllen) { 01627 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01628 if (sin) 01629 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01630 else 01631 ast_log(LOG_WARNING, "No address detected??\n"); 01632 } else { 01633 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01634 } 01635 } 01636 #endif 01637 return 0; 01638 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5388 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), 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().
05389 { 05390 struct iax2_registry *reg; 05391 /* Start pessimistic */ 05392 char peer[256] = ""; 05393 char msgstatus[60]; 05394 int refresh = 60; 05395 char ourip[256] = "<Unspecified>"; 05396 struct sockaddr_in oldus; 05397 struct sockaddr_in us; 05398 int oldmsgs; 05399 05400 memset(&us, 0, sizeof(us)); 05401 if (ies->apparent_addr) 05402 bcopy(ies->apparent_addr, &us, sizeof(us)); 05403 if (ies->username) 05404 ast_copy_string(peer, ies->username, sizeof(peer)); 05405 if (ies->refresh) 05406 refresh = ies->refresh; 05407 if (ies->calling_number) { 05408 /* We don't do anything with it really, but maybe we should */ 05409 } 05410 reg = iaxs[callno]->reg; 05411 if (!reg) { 05412 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05413 return -1; 05414 } 05415 memcpy(&oldus, ®->us, sizeof(oldus)); 05416 oldmsgs = reg->messages; 05417 if (inaddrcmp(®->addr, sin)) { 05418 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05419 return -1; 05420 } 05421 memcpy(®->us, &us, sizeof(reg->us)); 05422 if (ies->msgcount >= 0) 05423 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05424 /* always refresh the registration at the interval requested by the server 05425 we are registering to 05426 */ 05427 reg->refresh = refresh; 05428 if (reg->expire > -1) 05429 ast_sched_del(sched, reg->expire); 05430 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05431 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05432 if (option_verbose > 2) { 05433 if (reg->messages > 255) 05434 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05435 else if (reg->messages > 1) 05436 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05437 else if (reg->messages > 0) 05438 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05439 else 05440 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05441 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05442 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05443 } 05444 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05445 } 05446 reg->regstate = REG_STATE_REGISTERED; 05447 return 0; 05448 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3219 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.
03220 { 03221 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03222 if (option_debug) 03223 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03224 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03225 }
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 3075 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, 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.
03076 { 03077 struct ast_channel *cs[3]; 03078 struct ast_channel *who, *other; 03079 int to = -1; 03080 int res = -1; 03081 int transferstarted=0; 03082 struct ast_frame *f; 03083 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03084 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03085 struct timeval waittimer = {0, 0}, tv; 03086 03087 lock_both(callno0, callno1); 03088 /* Put them in native bridge mode */ 03089 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03090 iaxs[callno0]->bridgecallno = callno1; 03091 iaxs[callno1]->bridgecallno = callno0; 03092 } 03093 unlock_both(callno0, callno1); 03094 03095 /* If not, try to bridge until we can execute a transfer, if we can */ 03096 cs[0] = c0; 03097 cs[1] = c1; 03098 for (/* ever */;;) { 03099 /* Check in case we got masqueraded into */ 03100 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03101 if (option_verbose > 2) 03102 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03103 /* Remove from native mode */ 03104 if (c0->tech == &iax2_tech) { 03105 ast_mutex_lock(&iaxsl[callno0]); 03106 iaxs[callno0]->bridgecallno = 0; 03107 ast_mutex_unlock(&iaxsl[callno0]); 03108 } 03109 if (c1->tech == &iax2_tech) { 03110 ast_mutex_lock(&iaxsl[callno1]); 03111 iaxs[callno1]->bridgecallno = 0; 03112 ast_mutex_unlock(&iaxsl[callno1]); 03113 } 03114 return AST_BRIDGE_FAILED_NOWARN; 03115 } 03116 if (c0->nativeformats != c1->nativeformats) { 03117 if (option_verbose > 2) { 03118 char buf0[255]; 03119 char buf1[255]; 03120 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03121 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03122 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03123 } 03124 /* Remove from native mode */ 03125 lock_both(callno0, callno1); 03126 iaxs[callno0]->bridgecallno = 0; 03127 iaxs[callno1]->bridgecallno = 0; 03128 unlock_both(callno0, callno1); 03129 return AST_BRIDGE_FAILED_NOWARN; 03130 } 03131 /* check if transfered and if we really want native bridging */ 03132 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03133 /* Try the transfer */ 03134 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03135 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03136 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03137 transferstarted = 1; 03138 } 03139 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03140 /* Call has been transferred. We're no longer involved */ 03141 gettimeofday(&tv, NULL); 03142 if (ast_tvzero(waittimer)) { 03143 waittimer = tv; 03144 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03145 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03146 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03147 *fo = NULL; 03148 *rc = c0; 03149 res = AST_BRIDGE_COMPLETE; 03150 break; 03151 } 03152 } 03153 to = 1000; 03154 who = ast_waitfor_n(cs, 2, &to); 03155 if (timeoutms > -1) { 03156 timeoutms -= (1000 - to); 03157 if (timeoutms < 0) 03158 timeoutms = 0; 03159 } 03160 if (!who) { 03161 if (!timeoutms) { 03162 res = AST_BRIDGE_RETRY; 03163 break; 03164 } 03165 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03166 res = AST_BRIDGE_FAILED; 03167 break; 03168 } 03169 continue; 03170 } 03171 f = ast_read(who); 03172 if (!f) { 03173 *fo = NULL; 03174 *rc = who; 03175 res = AST_BRIDGE_COMPLETE; 03176 break; 03177 } 03178 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03179 *fo = f; 03180 *rc = who; 03181 res = AST_BRIDGE_COMPLETE; 03182 break; 03183 } 03184 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03185 if ((f->frametype == AST_FRAME_VOICE) || 03186 (f->frametype == AST_FRAME_TEXT) || 03187 (f->frametype == AST_FRAME_VIDEO) || 03188 (f->frametype == AST_FRAME_IMAGE) || 03189 (f->frametype == AST_FRAME_DTMF)) { 03190 /* monitored dtmf take out of the bridge. 03191 * check if we monitor the specific source. 03192 */ 03193 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03194 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03195 *rc = who; 03196 *fo = f; 03197 res = AST_BRIDGE_COMPLETE; 03198 /* Remove from native mode */ 03199 break; 03200 } 03201 /* everything else goes to the other side */ 03202 ast_write(other, f); 03203 } 03204 ast_frfree(f); 03205 /* Swap who gets priority */ 03206 cs[2] = cs[0]; 03207 cs[0] = cs[1]; 03208 cs[1] = cs[2]; 03209 } 03210 lock_both(callno0, callno1); 03211 if(iaxs[callno0]) 03212 iaxs[callno0]->bridgecallno = 0; 03213 if(iaxs[callno1]) 03214 iaxs[callno1]->bridgecallno = 0; 03215 unlock_both(callno0, callno1); 03216 return res; 03217 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 2821 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_sched_add(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), CALLNO_TO_PTR, 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(), 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_VARIABLE, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, LOG_WARNING, chan_iax2_pvt::maxtime, ast_channel::nativeformats, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, var, and ast_channel::varshead.
02822 { 02823 struct sockaddr_in sin; 02824 char *l=NULL, *n=NULL, *tmpstr; 02825 struct iax_ie_data ied; 02826 char *defaultrdest = "s"; 02827 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02828 struct parsed_dial_string pds; 02829 struct create_addr_info cai; 02830 struct ast_var_t *var; 02831 02832 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 02833 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 02834 return -1; 02835 } 02836 02837 memset(&cai, 0, sizeof(cai)); 02838 cai.encmethods = iax2_encryption; 02839 02840 memset(&pds, 0, sizeof(pds)); 02841 tmpstr = ast_strdupa(dest); 02842 parse_dial_string(tmpstr, &pds); 02843 02844 if (!pds.exten) 02845 pds.exten = defaultrdest; 02846 02847 if (create_addr(pds.peer, &sin, &cai)) { 02848 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 02849 return -1; 02850 } 02851 02852 if (!pds.username && !ast_strlen_zero(cai.username)) 02853 pds.username = cai.username; 02854 if (!pds.password && !ast_strlen_zero(cai.secret)) 02855 pds.password = cai.secret; 02856 if (!pds.key && !ast_strlen_zero(cai.outkey)) 02857 pds.key = cai.outkey; 02858 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 02859 pds.context = cai.peercontext; 02860 02861 /* Keep track of the context for outgoing calls too */ 02862 ast_copy_string(c->context, cai.context, sizeof(c->context)); 02863 02864 if (pds.port) 02865 sin.sin_port = htons(atoi(pds.port)); 02866 02867 l = c->cid.cid_num; 02868 n = c->cid.cid_name; 02869 02870 /* Now build request */ 02871 memset(&ied, 0, sizeof(ied)); 02872 02873 /* On new call, first IE MUST be IAX version of caller */ 02874 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 02875 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 02876 if (pds.options && strchr(pds.options, 'a')) { 02877 /* Request auto answer */ 02878 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 02879 } 02880 02881 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 02882 02883 if (l) { 02884 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 02885 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02886 } else { 02887 if (n) 02888 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02889 else 02890 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 02891 } 02892 02893 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 02894 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 02895 02896 if (n) 02897 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 02898 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 02899 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 02900 02901 if (!ast_strlen_zero(c->language)) 02902 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 02903 if (!ast_strlen_zero(c->cid.cid_dnid)) 02904 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 02905 if (!ast_strlen_zero(c->cid.cid_rdnis)) 02906 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 02907 02908 if (pds.context) 02909 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 02910 02911 if (pds.username) 02912 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 02913 02914 if (cai.encmethods) 02915 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 02916 02917 ast_mutex_lock(&iaxsl[callno]); 02918 02919 if (!ast_strlen_zero(c->context)) 02920 ast_string_field_set(iaxs[callno], context, c->context); 02921 02922 if (pds.username) 02923 ast_string_field_set(iaxs[callno], username, pds.username); 02924 02925 iaxs[callno]->encmethods = cai.encmethods; 02926 02927 iaxs[callno]->adsi = cai.adsi; 02928 02929 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 02930 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 02931 02932 if (pds.key) 02933 ast_string_field_set(iaxs[callno], outkey, pds.key); 02934 if (pds.password) 02935 ast_string_field_set(iaxs[callno], secret, pds.password); 02936 02937 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 02938 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 02939 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 02940 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 02941 02942 if (iaxs[callno]->maxtime) { 02943 /* Initialize pingtime and auto-congest time */ 02944 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 02945 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 02946 } else if (autokill) { 02947 iaxs[callno]->pingtime = autokill / 2; 02948 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 02949 } 02950 02951 /* Add remote vars */ 02952 AST_LIST_TRAVERSE(&c->varshead, var, entries) { 02953 if (!strncmp(ast_var_name(var), "~IAX2~", strlen("~IAX2~"))) { 02954 char tmp[256]; 02955 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var) + strlen("~IAX2~"), ast_var_value(var)); 02956 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 02957 } 02958 } 02959 02960 /* send the command using the appropriate socket for this peer */ 02961 iaxs[callno]->sockfd = cai.sockfd; 02962 02963 /* Transmit the string in a "NEW" request */ 02964 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 02965 02966 ast_mutex_unlock(&iaxsl[callno]); 02967 ast_setstate(c, AST_STATE_RINGING); 02968 02969 return 0; 02970 }
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 9602 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.
09603 { 09604 int res = 0; 09605 struct iax2_dpcache *dp; 09606 #if 0 09607 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09608 #endif 09609 if ((priority != 1) && (priority != 2)) 09610 return 0; 09611 ast_mutex_lock(&dpcache_lock); 09612 dp = find_cache(chan, data, context, exten, priority); 09613 if (dp) { 09614 if (dp->flags & CACHE_FLAG_CANEXIST) 09615 res= 1; 09616 } 09617 ast_mutex_unlock(&dpcache_lock); 09618 if (!dp) { 09619 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09620 } 09621 return res; 09622 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 2734 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
02735 { 02736 time_t t; 02737 struct tm tm; 02738 unsigned int tmp; 02739 time(&t); 02740 localtime_r(&t, &tm); 02741 if (!ast_strlen_zero(tz)) 02742 ast_localtime(&t, &tm, tz); 02743 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02744 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02745 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02746 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02747 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02748 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02749 return tmp; 02750 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1753 of file chan_iax2.c.
References ast_channel::_softhangup, 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_SOFTHANGUP_DEV, ast_string_field_free_pools, 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(), destroy_peer(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), and socket_process().
01754 { 01755 struct chan_iax2_pvt *pvt; 01756 struct iax_frame *cur; 01757 struct ast_channel *owner; 01758 01759 retry: 01760 pvt = iaxs[callno]; 01761 gettimeofday(&lastused[callno], NULL); 01762 01763 owner = pvt ? pvt->owner : NULL; 01764 01765 if (owner) { 01766 if (ast_mutex_trylock(&owner->lock)) { 01767 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01768 ast_mutex_unlock(&iaxsl[callno]); 01769 usleep(1); 01770 ast_mutex_lock(&iaxsl[callno]); 01771 goto retry; 01772 } 01773 } 01774 if (!owner) 01775 iaxs[callno] = NULL; 01776 if (pvt) { 01777 if (!owner) 01778 pvt->owner = NULL; 01779 iax2_destroy_helper(pvt); 01780 01781 /* Already gone */ 01782 ast_set_flag(pvt, IAX_ALREADYGONE); 01783 01784 if (owner) { 01785 /* If there's an owner, prod it to give up */ 01786 owner->_softhangup |= AST_SOFTHANGUP_DEV; 01787 ast_queue_hangup(owner); 01788 } 01789 01790 AST_LIST_LOCK(&iaxq.queue); 01791 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01792 /* Cancel any pending transmissions */ 01793 if (cur->callno == pvt->callno) 01794 cur->retries = -1; 01795 } 01796 AST_LIST_UNLOCK(&iaxq.queue); 01797 01798 if (pvt->reg) 01799 pvt->reg->callno = 0; 01800 if (!owner) { 01801 jb_frame frame; 01802 if (pvt->vars) { 01803 ast_variables_destroy(pvt->vars); 01804 pvt->vars = NULL; 01805 } 01806 01807 while (jb_getall(pvt->jb, &frame) == JB_OK) 01808 iax2_frame_free(frame.data); 01809 jb_destroy(pvt->jb); 01810 /* gotta free up the stringfields */ 01811 ast_string_field_free_pools(pvt); 01812 free(pvt); 01813 } 01814 } 01815 if (owner) { 01816 ast_mutex_unlock(&owner->lock); 01817 } 01818 if (callno & 0x4000) 01819 update_max_trunk(); 01820 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1694 of file chan_iax2.c.
References ast_clear_flag, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, and sched.
Referenced by iax2_destroy(), iax2_predestroy(), and stop_stuff().
01695 { 01696 struct iax2_user *user = NULL; 01697 01698 /* Decrement AUTHREQ count if needed */ 01699 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01700 AST_LIST_LOCK(&users); 01701 AST_LIST_TRAVERSE(&users, user, entry) { 01702 if (!strcmp(user->name, pvt->username)) { 01703 user->curauthreq--; 01704 break; 01705 } 01706 } 01707 AST_LIST_UNLOCK(&users); 01708 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01709 } 01710 /* No more pings or lagrq's */ 01711 if (pvt->pingid > -1) 01712 ast_sched_del(sched, pvt->pingid); 01713 pvt->pingid = -1; 01714 if (pvt->lagid > -1) 01715 ast_sched_del(sched, pvt->lagid); 01716 pvt->lagid = -1; 01717 if (pvt->autoid > -1) 01718 ast_sched_del(sched, pvt->autoid); 01719 pvt->autoid = -1; 01720 if (pvt->authid > -1) 01721 ast_sched_del(sched, pvt->authid); 01722 pvt->authid = -1; 01723 if (pvt->initid > -1) 01724 ast_sched_del(sched, pvt->initid); 01725 pvt->initid = -1; 01726 if (pvt->jbid > -1) 01727 ast_sched_del(sched, pvt->jbid); 01728 pvt->jbid = -1; 01729 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 9787 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(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, iax2_peer::maxms, option_debug, and parse_dial_string().
09788 { 09789 struct parsed_dial_string pds; 09790 char *tmp = ast_strdupa(data); 09791 struct iax2_peer *p; 09792 int res = AST_DEVICE_INVALID; 09793 09794 memset(&pds, 0, sizeof(pds)); 09795 parse_dial_string(tmp, &pds); 09796 if (ast_strlen_zero(pds.peer)) 09797 return res; 09798 09799 if (option_debug > 2) 09800 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 09801 09802 /* SLD: FIXME: second call to find_peer during registration */ 09803 if (!(p = find_peer(pds.peer, 1))) 09804 return res; 09805 09806 res = AST_DEVICE_UNAVAILABLE; 09807 if (option_debug > 2) 09808 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09809 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09810 09811 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09812 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09813 /* Peer is registered, or have default IP address 09814 and a valid registration */ 09815 if (p->historicms == 0 || p->historicms <= p->maxms) 09816 /* let the core figure out whether it is in use or not */ 09817 res = AST_DEVICE_UNKNOWN; 09818 } 09819 09820 if (ast_test_flag(p, IAX_TEMPONLY)) 09821 destroy_peer(p); 09822 09823 return res; 09824 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2418 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02419 { 02420 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02421 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2423 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02424 { 02425 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02426 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4475 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04476 { 04477 if (argc < 2 || argc > 3) 04478 return RESULT_SHOWUSAGE; 04479 iaxdebug = 1; 04480 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04481 return RESULT_SUCCESS; 04482 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4493 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04494 { 04495 if (argc < 3 || argc > 4) 04496 return RESULT_SHOWUSAGE; 04497 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04498 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04499 return RESULT_SUCCESS; 04500 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 7784 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_add(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), 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().
07785 { 07786 struct iax_ie_data ied; 07787 if (option_debug && iaxdebug) 07788 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07789 07790 if (reg->dnsmgr && 07791 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 07792 /* Maybe the IP has changed, force DNS refresh */ 07793 ast_dnsmgr_refresh(reg->dnsmgr); 07794 } 07795 07796 /* 07797 * if IP has Changed, free allocated call to create a new one with new IP 07798 * call has the pointer to IP and must be updated to the new one 07799 */ 07800 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 07801 ast_mutex_lock(&iaxsl[reg->callno]); 07802 iax2_destroy(reg->callno); 07803 ast_mutex_unlock(&iaxsl[reg->callno]); 07804 reg->callno = 0; 07805 } 07806 if (!reg->addr.sin_addr.s_addr) { 07807 if (option_debug && iaxdebug) 07808 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 07809 /* Setup the next registration attempt */ 07810 if (reg->expire > -1) 07811 ast_sched_del(sched, reg->expire); 07812 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07813 return -1; 07814 } 07815 07816 if (!reg->callno) { 07817 if (option_debug) 07818 ast_log(LOG_DEBUG, "Allocate call number\n"); 07819 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07820 if (reg->callno < 1) { 07821 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07822 return -1; 07823 } else if (option_debug) 07824 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07825 iaxs[reg->callno]->reg = reg; 07826 } 07827 /* Schedule the next registration attempt */ 07828 if (reg->expire > -1) 07829 ast_sched_del(sched, reg->expire); 07830 /* Setup the next registration a little early */ 07831 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07832 /* Send the request */ 07833 memset(&ied, 0, sizeof(ied)); 07834 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07835 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07836 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07837 reg->regstate = REG_STATE_REGSENT; 07838 return 0; 07839 }
static int iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5242 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05243 { 05244 #ifdef SCHED_MULTITHREADED 05245 if (schedule_action(__iax2_do_register_s, data)) 05246 #endif 05247 __iax2_do_register_s(data); 05248 return 0; 05249 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4484 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04485 { 04486 if (argc < 3 || argc > 4) 04487 return RESULT_SHOWUSAGE; 04488 iaxtrunkdebug = 1; 04489 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04490 return RESULT_SUCCESS; 04491 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 5875 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
05876 { 05877 struct iax_ie_data ied; 05878 /* Auto-hangup with 30 seconds of inactivity */ 05879 if (iaxs[callno]->autoid > -1) 05880 ast_sched_del(sched, iaxs[callno]->autoid); 05881 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 05882 memset(&ied, 0, sizeof(ied)); 05883 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 05884 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 05885 dp->flags |= CACHE_FLAG_TRANSMITTED; 05886 }
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 9648 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.
09649 { 09650 char odata[256]; 09651 char req[256]; 09652 char *ncontext; 09653 struct iax2_dpcache *dp; 09654 struct ast_app *dial; 09655 #if 0 09656 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); 09657 #endif 09658 if (priority == 2) { 09659 /* Indicate status, can be overridden in dialplan */ 09660 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09661 if (dialstatus) { 09662 dial = pbx_findapp(dialstatus); 09663 if (dial) 09664 pbx_exec(chan, dial, ""); 09665 } 09666 return -1; 09667 } else if (priority != 1) 09668 return -1; 09669 ast_mutex_lock(&dpcache_lock); 09670 dp = find_cache(chan, data, context, exten, priority); 09671 if (dp) { 09672 if (dp->flags & CACHE_FLAG_EXISTS) { 09673 ast_copy_string(odata, data, sizeof(odata)); 09674 ncontext = strchr(odata, '/'); 09675 if (ncontext) { 09676 *ncontext = '\0'; 09677 ncontext++; 09678 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09679 } else { 09680 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09681 } 09682 if (option_verbose > 2) 09683 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09684 } else { 09685 ast_mutex_unlock(&dpcache_lock); 09686 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09687 return -1; 09688 } 09689 } 09690 ast_mutex_unlock(&dpcache_lock); 09691 dial = pbx_findapp("Dial"); 09692 if (dial) { 09693 return pbx_exec(chan, dial, req); 09694 } else { 09695 ast_log(LOG_WARNING, "No dial application registered\n"); 09696 } 09697 return -1; 09698 }
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 9579 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.
09580 { 09581 struct iax2_dpcache *dp; 09582 int res = 0; 09583 #if 0 09584 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09585 #endif 09586 if ((priority != 1) && (priority != 2)) 09587 return 0; 09588 ast_mutex_lock(&dpcache_lock); 09589 dp = find_cache(chan, data, context, exten, priority); 09590 if (dp) { 09591 if (dp->flags & CACHE_FLAG_EXISTS) 09592 res= 1; 09593 } 09594 ast_mutex_unlock(&dpcache_lock); 09595 if (!dp) { 09596 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09597 } 09598 return res; 09599 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2445 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.
02446 { 02447 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02448 ast_mutex_lock(&iaxsl[callno]); 02449 if (iaxs[callno]) 02450 iaxs[callno]->owner = newchan; 02451 else 02452 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02453 ast_mutex_unlock(&iaxsl[callno]); 02454 return 0; 02455 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1301 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().
01302 { 01303 if (fr->retrans > -1) 01304 ast_sched_del(sched, fr->retrans); 01305 iax_frame_free(fr); 01306 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len, | |||
int | lockpeer | |||
) | [static] |
Definition at line 1022 of file chan_iax2.c.
References iax2_peer::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_test_flag, destroy_peer(), IAX_TEMPONLY, and realtime_peer().
Referenced by find_callno().
01023 { 01024 struct iax2_peer *peer = NULL; 01025 int res = 0; 01026 01027 if (lockpeer) 01028 AST_LIST_LOCK(&peers); 01029 AST_LIST_TRAVERSE(&peers, peer, entry) { 01030 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01031 (peer->addr.sin_port == sin.sin_port)) { 01032 ast_copy_string(host, peer->name, len); 01033 res = 1; 01034 break; 01035 } 01036 } 01037 if (lockpeer) 01038 AST_LIST_UNLOCK(&peers); 01039 if (!peer) { 01040 peer = realtime_peer(NULL, &sin); 01041 if (peer) { 01042 ast_copy_string(host, peer->name, len); 01043 if (ast_test_flag(peer, IAX_TEMPONLY)) 01044 destroy_peer(peer); 01045 res = 1; 01046 } 01047 } 01048 01049 return res; 01050 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3280 of file chan_iax2.c.
References iax2_peer::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_test_flag, and IAX_TRUNK.
Referenced by check_access().
03281 { 03282 struct iax2_peer *peer = NULL; 03283 int res = 0; 03284 03285 AST_LIST_LOCK(&peers); 03286 AST_LIST_TRAVERSE(&peers, peer, entry) { 03287 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03288 (peer->addr.sin_port == sin.sin_port)) { 03289 res = ast_test_flag(peer, IAX_TRUNK); 03290 break; 03291 } 03292 } 03293 AST_LIST_UNLOCK(&peers); 03294 03295 return res; 03296 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2972 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_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
02973 { 02974 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02975 int alreadygone; 02976 struct iax_ie_data ied; 02977 memset(&ied, 0, sizeof(ied)); 02978 ast_mutex_lock(&iaxsl[callno]); 02979 if (callno && iaxs[callno]) { 02980 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 02981 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 02982 /* Send the hangup unless we have had a transmission error or are already gone */ 02983 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 02984 if (!iaxs[callno]->error && !alreadygone) 02985 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 02986 /* Explicitly predestroy it */ 02987 iax2_predestroy(callno); 02988 /* If we were already gone to begin with, destroy us now */ 02989 if (alreadygone) { 02990 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 02991 iax2_destroy(callno); 02992 } 02993 } 02994 ast_mutex_unlock(&iaxsl[callno]); 02995 if (option_verbose > 2) 02996 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 02997 return 0; 02998 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3227 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.
03228 { 03229 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03230 struct chan_iax2_pvt *pvt; 03231 int res = 0; 03232 03233 if (option_debug && iaxdebug) 03234 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03235 03236 ast_mutex_lock(&iaxsl[callno]); 03237 pvt = iaxs[callno]; 03238 if (!strcasecmp(pvt->mohinterpret, "passthrough")) { 03239 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03240 ast_mutex_unlock(&iaxsl[callno]); 03241 return res; 03242 } 03243 03244 switch (condition) { 03245 case AST_CONTROL_HOLD: 03246 ast_moh_start(c, data, pvt->mohinterpret); 03247 break; 03248 case AST_CONTROL_UNHOLD: 03249 ast_moh_stop(c); 03250 break; 03251 default: 03252 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03253 } 03254 03255 ast_mutex_unlock(&iaxsl[callno]); 03256 03257 return res; 03258 }
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 9625 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.
09626 { 09627 int res = 0; 09628 struct iax2_dpcache *dp; 09629 #if 0 09630 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09631 #endif 09632 if ((priority != 1) && (priority != 2)) 09633 return 0; 09634 ast_mutex_lock(&dpcache_lock); 09635 dp = find_cache(chan, data, context, exten, priority); 09636 if (dp) { 09637 if (dp->flags & CACHE_FLAG_MATCHMORE) 09638 res= 1; 09639 } 09640 ast_mutex_unlock(&dpcache_lock); 09641 if (!dp) { 09642 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09643 } 09644 return res; 09645 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4502 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04503 { 04504 if (argc < 3 || argc > 4) 04505 return RESULT_SHOWUSAGE; 04506 iaxdebug = 0; 04507 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04508 return RESULT_SUCCESS; 04509 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4520 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04521 { 04522 if (argc < 4 || argc > 5) 04523 return RESULT_SHOWUSAGE; 04524 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04525 jb_debug_output("\n"); 04526 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04527 return RESULT_SUCCESS; 04528 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4511 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04512 { 04513 if (argc < 4 || argc > 5) 04514 return RESULT_SHOWUSAGE; 04515 iaxtrunkdebug = 0; 04516 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04517 return RESULT_SUCCESS; 04518 }
static int iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 7980 of file chan_iax2.c.
References __iax2_poke_noanswer(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
07981 { 07982 struct iax2_peer *peer = data; 07983 peer->pokeexpire = -1; 07984 #ifdef SCHED_MULTITHREADED 07985 if (schedule_action(__iax2_poke_noanswer, data)) 07986 #endif 07987 __iax2_poke_noanswer(data); 07988 return 0; 07989 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 7991 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, 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(), load_module(), reg_source_db(), reload_config(), and update_registry().
07992 { 07993 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07994 /* IF we have no IP, or this isn't to be monitored, return 07995 immediately after clearing things out */ 07996 peer->lastms = 0; 07997 peer->historicms = 0; 07998 peer->pokeexpire = -1; 07999 peer->callno = 0; 08000 return 0; 08001 } 08002 if (peer->callno > 0) { 08003 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08004 ast_mutex_lock(&iaxsl[peer->callno]); 08005 iax2_destroy(peer->callno); 08006 ast_mutex_unlock(&iaxsl[peer->callno]); 08007 } 08008 if (heldcall) 08009 ast_mutex_unlock(&iaxsl[heldcall]); 08010 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 08011 if (heldcall) 08012 ast_mutex_lock(&iaxsl[heldcall]); 08013 if (peer->callno < 1) { 08014 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08015 return -1; 08016 } 08017 08018 /* Speed up retransmission times for this qualify call */ 08019 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08020 iaxs[peer->callno]->peerpoke = peer; 08021 08022 /* Remove any pending pokeexpire task */ 08023 if (peer->pokeexpire > -1) 08024 ast_sched_del(sched, peer->pokeexpire); 08025 08026 /* Queue up a new task to handle no reply */ 08027 /* If the host is already unreachable then use the unreachable interval instead */ 08028 if (peer->lastms < 0) { 08029 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 08030 } else 08031 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 08032 08033 /* And send the poke */ 08034 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08035 08036 return 0; 08037 }
static int iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 5914 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
05915 { 05916 struct iax2_peer *peer = data; 05917 peer->pokeexpire = -1; 05918 #ifdef SCHED_MULTITHREADED 05919 if (schedule_action(__iax2_poke_peer_s, data)) 05920 #endif 05921 __iax2_poke_peer_s(data); 05922 return 0; 05923 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1731 of file chan_iax2.c.
References ast_channel::_softhangup, ast_module_unref(), ast_queue_hangup(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, iax2_destroy_helper(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
01732 { 01733 struct ast_channel *c; 01734 struct chan_iax2_pvt *pvt = iaxs[callno]; 01735 01736 if (!pvt) 01737 return -1; 01738 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01739 iax2_destroy_helper(pvt); 01740 ast_set_flag(pvt, IAX_ALREADYGONE); 01741 } 01742 c = pvt->owner; 01743 if (c) { 01744 c->_softhangup |= AST_SOFTHANGUP_DEV; 01745 c->tech_pvt = NULL; 01746 ast_queue_hangup(c); 01747 pvt->owner = NULL; 01748 ast_module_unref(ast_module_info->self); 01749 } 01750 return 0; 01751 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 7706 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(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
07707 { 07708 struct iax2_thread *thread = data; 07709 struct timeval tv; 07710 struct timespec ts; 07711 int put_into_idle = 0; 07712 07713 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 07714 pthread_cleanup_push(iax2_process_thread_cleanup, data); 07715 for(;;) { 07716 /* Wait for something to signal us to be awake */ 07717 ast_mutex_lock(&thread->lock); 07718 07719 /* Put into idle list if applicable */ 07720 if (put_into_idle) 07721 insert_idle_thread(thread); 07722 07723 if (thread->type == IAX_TYPE_DYNAMIC) { 07724 /* Wait to be signalled or time out */ 07725 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 07726 ts.tv_sec = tv.tv_sec; 07727 ts.tv_nsec = tv.tv_usec * 1000; 07728 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 07729 ast_mutex_unlock(&thread->lock); 07730 AST_LIST_LOCK(&dynamic_list); 07731 AST_LIST_REMOVE(&dynamic_list, thread, list); 07732 iaxdynamicthreadcount--; 07733 AST_LIST_UNLOCK(&dynamic_list); 07734 break; /* exiting the main loop */ 07735 } 07736 } else { 07737 ast_cond_wait(&thread->cond, &thread->lock); 07738 } 07739 ast_mutex_unlock(&thread->lock); 07740 07741 /* Add ourselves to the active list now */ 07742 AST_LIST_LOCK(&active_list); 07743 AST_LIST_INSERT_HEAD(&active_list, thread, list); 07744 AST_LIST_UNLOCK(&active_list); 07745 07746 /* See what we need to do */ 07747 switch(thread->iostate) { 07748 case IAX_IOSTATE_READY: 07749 thread->actions++; 07750 thread->iostate = IAX_IOSTATE_PROCESSING; 07751 socket_process(thread); 07752 break; 07753 case IAX_IOSTATE_SCHEDREADY: 07754 thread->actions++; 07755 thread->iostate = IAX_IOSTATE_PROCESSING; 07756 #ifdef SCHED_MULTITHREADED 07757 thread->schedfunc(thread->scheddata); 07758 #endif 07759 break; 07760 } 07761 time(&thread->checktime); 07762 thread->iostate = IAX_IOSTATE_IDLE; 07763 #ifdef DEBUG_SCHED_MULTITHREAD 07764 thread->curfunc[0]='\0'; 07765 #endif 07766 07767 /* Now... remove ourselves from the active list, and return to the idle list */ 07768 AST_LIST_LOCK(&active_list); 07769 AST_LIST_REMOVE(&active_list, thread, list); 07770 AST_LIST_UNLOCK(&active_list); 07771 07772 /* Go back into our respective list */ 07773 put_into_idle = 1; 07774 } 07775 07776 /* I am exiting here on my own volition, I need to clean up my own data structures 07777 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 07778 */ 07779 pthread_cleanup_pop(1); 07780 07781 return NULL; 07782 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 7697 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
07698 { 07699 struct iax2_thread *thread = data; 07700 ast_mutex_destroy(&thread->lock); 07701 ast_cond_destroy(&thread->cond); 07702 free(thread); 07703 ast_atomic_dec_and_test(&iaxactivethreadcount); 07704 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 7939 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
07940 { 07941 int force = 0; 07942 int res; 07943 if (argc < 4) 07944 return RESULT_SHOWUSAGE; 07945 if ((argc > 4)) { 07946 if (!strcasecmp(argv[4], "forced")) 07947 force = 1; 07948 else 07949 return RESULT_SHOWUSAGE; 07950 } 07951 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07952 if (res < 0) 07953 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07954 else if (res < 1) 07955 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07956 else 07957 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07958 return RESULT_SUCCESS; 07959 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 7841 of file chan_iax2.c.
References iax_prov_complete_template().
07842 { 07843 if (pos != 3) 07844 return NULL; 07845 return iax_prov_complete_template(line, word, pos, state); 07846 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 7848 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), 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().
07849 { 07850 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07851 is found for template */ 07852 struct iax_ie_data provdata; 07853 struct iax_ie_data ied; 07854 unsigned int sig; 07855 struct sockaddr_in sin; 07856 int callno; 07857 struct create_addr_info cai; 07858 07859 memset(&cai, 0, sizeof(cai)); 07860 07861 if (option_debug) 07862 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07863 07864 if (iax_provision_build(&provdata, &sig, template, force)) { 07865 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07866 return 0; 07867 } 07868 07869 if (end) { 07870 memcpy(&sin, end, sizeof(sin)); 07871 cai.sockfd = sockfd; 07872 } else if (create_addr(dest, &sin, &cai)) 07873 return -1; 07874 07875 /* Build the rest of the message */ 07876 memset(&ied, 0, sizeof(ied)); 07877 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07878 07879 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07880 if (!callno) 07881 return -1; 07882 07883 ast_mutex_lock(&iaxsl[callno]); 07884 if (iaxs[callno]) { 07885 /* Schedule autodestruct in case they don't ever give us anything back */ 07886 if (iaxs[callno]->autoid > -1) 07887 ast_sched_del(sched, iaxs[callno]->autoid); 07888 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07889 ast_set_flag(iaxs[callno], IAX_PROVISION); 07890 /* Got a call number now, so go ahead and send the provisioning information */ 07891 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07892 } 07893 ast_mutex_unlock(&iaxsl[callno]); 07894 07895 return 1; 07896 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1925 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01926 { 01927 struct iax2_peer *peer; 01928 01929 if (argc != 4) 01930 return RESULT_SHOWUSAGE; 01931 if (!strcmp(argv[3],"all")) { 01932 reload_config(); 01933 ast_cli(fd, "OK cache is flushed.\n"); 01934 } else if ((peer = find_peer(argv[3], 0))) { 01935 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 01936 ast_set_flag(peer, IAX_RTAUTOCLEAR); 01937 expire_registry((void*)peer->name); 01938 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 01939 } else { 01940 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 01941 } 01942 } else { 01943 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 01944 } 01945 01946 return RESULT_SUCCESS; 01947 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 1308 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().
01309 { 01310 /* Assumes lock for callno is already held... */ 01311 for (;;) { 01312 if (iaxs[callno] && iaxs[callno]->owner) { 01313 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01314 /* Avoid deadlock by pausing and trying again */ 01315 ast_mutex_unlock(&iaxsl[callno]); 01316 usleep(1); 01317 ast_mutex_lock(&iaxsl[callno]); 01318 } else { 01319 ast_queue_frame(iaxs[callno]->owner, f); 01320 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01321 break; 01322 } 01323 } else 01324 break; 01325 } 01326 return 0; 01327 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3026 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
03027 { 03028 ast_log(LOG_NOTICE, "I should never be called!\n"); 03029 return &ast_null_frame; 03030 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5450 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, and strsep().
Referenced by set_config().
05451 { 05452 struct iax2_registry *reg; 05453 char copy[256]; 05454 char *username, *hostname, *secret; 05455 char *porta; 05456 char *stringp=NULL; 05457 05458 if (!value) 05459 return -1; 05460 ast_copy_string(copy, value, sizeof(copy)); 05461 stringp=copy; 05462 username = strsep(&stringp, "@"); 05463 hostname = strsep(&stringp, "@"); 05464 if (!hostname) { 05465 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05466 return -1; 05467 } 05468 stringp=username; 05469 username = strsep(&stringp, ":"); 05470 secret = strsep(&stringp, ":"); 05471 stringp=hostname; 05472 hostname = strsep(&stringp, ":"); 05473 porta = strsep(&stringp, ":"); 05474 05475 if (porta && !atoi(porta)) { 05476 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05477 return -1; 05478 } 05479 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05480 return -1; 05481 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05482 free(reg); 05483 return -1; 05484 } 05485 ast_copy_string(reg->username, username, sizeof(reg->username)); 05486 if (secret) 05487 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05488 reg->expire = -1; 05489 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05490 reg->addr.sin_family = AF_INET; 05491 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05492 AST_LIST_LOCK(®istrations); 05493 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05494 AST_LIST_UNLOCK(®istrations); 05495 05496 return 0; 05497 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9353 of file chan_iax2.c.
References reload_config().
09354 { 09355 return reload_config(); 09356 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8049 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_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.
08050 { 08051 int callno; 08052 int res; 08053 int fmt, native; 08054 struct sockaddr_in sin; 08055 struct ast_channel *c; 08056 struct parsed_dial_string pds; 08057 struct create_addr_info cai; 08058 char *tmpstr; 08059 08060 memset(&pds, 0, sizeof(pds)); 08061 tmpstr = ast_strdupa(data); 08062 parse_dial_string(tmpstr, &pds); 08063 08064 memset(&cai, 0, sizeof(cai)); 08065 cai.capability = iax2_capability; 08066 08067 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08068 08069 if (!pds.peer) { 08070 ast_log(LOG_WARNING, "No peer given\n"); 08071 return NULL; 08072 } 08073 08074 08075 /* Populate our address from the given */ 08076 if (create_addr(pds.peer, &sin, &cai)) { 08077 *cause = AST_CAUSE_UNREGISTERED; 08078 return NULL; 08079 } 08080 08081 if (pds.port) 08082 sin.sin_port = htons(atoi(pds.port)); 08083 08084 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 08085 if (callno < 1) { 08086 ast_log(LOG_WARNING, "Unable to create call\n"); 08087 *cause = AST_CAUSE_CONGESTION; 08088 return NULL; 08089 } 08090 08091 ast_mutex_lock(&iaxsl[callno]); 08092 08093 /* If this is a trunk, update it now */ 08094 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08095 if (ast_test_flag(&cai, IAX_TRUNK)) 08096 callno = make_trunk(callno, 1); 08097 iaxs[callno]->maxtime = cai.maxtime; 08098 if (cai.found) 08099 ast_string_field_set(iaxs[callno], host, pds.peer); 08100 08101 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08102 08103 ast_mutex_unlock(&iaxsl[callno]); 08104 08105 if (c) { 08106 /* Choose a format we can live with */ 08107 if (c->nativeformats & format) 08108 c->nativeformats &= format; 08109 else { 08110 native = c->nativeformats; 08111 fmt = format; 08112 res = ast_translator_best_choice(&fmt, &native); 08113 if (res < 0) { 08114 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08115 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08116 ast_hangup(c); 08117 return NULL; 08118 } 08119 c->nativeformats = native; 08120 } 08121 c->readformat = ast_best_codec(c->nativeformats); 08122 c->writeformat = c->readformat; 08123 } 08124 08125 return c; 08126 }
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 3827 of file chan_iax2.c.
References iax_frame::af, 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, 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().
03828 { 03829 /* Queue a packet for delivery on a given private structure. Use "ts" for 03830 timestamp, or calculate if ts is 0. Send immediately without retransmission 03831 or delayed, with retransmission */ 03832 struct ast_iax2_full_hdr *fh; 03833 struct ast_iax2_mini_hdr *mh; 03834 struct ast_iax2_video_hdr *vh; 03835 struct { 03836 struct iax_frame fr2; 03837 unsigned char buffer[4096]; 03838 } frb; 03839 struct iax_frame *fr; 03840 int res; 03841 int sendmini=0; 03842 unsigned int lastsent; 03843 unsigned int fts; 03844 03845 if (!pvt) { 03846 ast_log(LOG_WARNING, "No private structure for packet?\n"); 03847 return -1; 03848 } 03849 03850 lastsent = pvt->lastsent; 03851 03852 /* Calculate actual timestamp */ 03853 fts = calc_timestamp(pvt, ts, f); 03854 03855 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 03856 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 03857 * increment the "predicted timestamps" for voice, if we're predecting */ 03858 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 03859 return 0; 03860 03861 03862 if ((ast_test_flag(pvt, IAX_TRUNK) || 03863 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 03864 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 03865 /* High two bytes are the same on timestamp, or sending on a trunk */ && 03866 (f->frametype == AST_FRAME_VOICE) 03867 /* is a voice frame */ && 03868 (f->subclass == pvt->svoiceformat) 03869 /* is the same type */ ) { 03870 /* Force immediate rather than delayed transmission */ 03871 now = 1; 03872 /* Mark that mini-style frame is appropriate */ 03873 sendmini = 1; 03874 } 03875 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 03876 (f->frametype == AST_FRAME_VIDEO) && 03877 ((f->subclass & ~0x1) == pvt->svideoformat)) { 03878 now = 1; 03879 sendmini = 1; 03880 } 03881 /* Allocate an iax_frame */ 03882 if (now) { 03883 fr = &frb.fr2; 03884 } else 03885 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)); 03886 if (!fr) { 03887 ast_log(LOG_WARNING, "Out of memory\n"); 03888 return -1; 03889 } 03890 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 03891 iax_frame_wrap(fr, f); 03892 03893 fr->ts = fts; 03894 fr->callno = pvt->callno; 03895 fr->transfer = transfer; 03896 fr->final = final; 03897 if (!sendmini) { 03898 /* We need a full frame */ 03899 if (seqno > -1) 03900 fr->oseqno = seqno; 03901 else 03902 fr->oseqno = pvt->oseqno++; 03903 fr->iseqno = pvt->iseqno; 03904 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 03905 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 03906 fh->ts = htonl(fr->ts); 03907 fh->oseqno = fr->oseqno; 03908 if (transfer) { 03909 fh->iseqno = 0; 03910 } else 03911 fh->iseqno = fr->iseqno; 03912 /* Keep track of the last thing we've acknowledged */ 03913 if (!transfer) 03914 pvt->aseqno = fr->iseqno; 03915 fh->type = fr->af.frametype & 0xFF; 03916 if (fr->af.frametype == AST_FRAME_VIDEO) 03917 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 03918 else 03919 fh->csub = compress_subclass(fr->af.subclass); 03920 if (transfer) { 03921 fr->dcallno = pvt->transfercallno; 03922 } else 03923 fr->dcallno = pvt->peercallno; 03924 fh->dcallno = htons(fr->dcallno); 03925 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 03926 fr->data = fh; 03927 fr->retries = 0; 03928 /* Retry after 2x the ping time has passed */ 03929 fr->retrytime = pvt->pingtime * 2; 03930 if (fr->retrytime < MIN_RETRY_TIME) 03931 fr->retrytime = MIN_RETRY_TIME; 03932 if (fr->retrytime > MAX_RETRY_TIME) 03933 fr->retrytime = MAX_RETRY_TIME; 03934 /* Acks' don't get retried */ 03935 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 03936 fr->retries = -1; 03937 else if (f->frametype == AST_FRAME_VOICE) 03938 pvt->svoiceformat = f->subclass; 03939 else if (f->frametype == AST_FRAME_VIDEO) 03940 pvt->svideoformat = f->subclass & ~0x1; 03941 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 03942 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 03943 if (iaxdebug) { 03944 if (fr->transfer) 03945 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 03946 else 03947 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 03948 } 03949 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 03950 } else 03951 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 03952 } 03953 03954 if (now) { 03955 res = send_packet(fr); 03956 } else 03957 res = iax2_transmit(fr); 03958 } else { 03959 if (ast_test_flag(pvt, IAX_TRUNK)) { 03960 iax2_trunk_queue(pvt, fr); 03961 res = 0; 03962 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 03963 /* Video frame have no sequence number */ 03964 fr->oseqno = -1; 03965 fr->iseqno = -1; 03966 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 03967 vh->zeros = 0; 03968 vh->callno = htons(0x8000 | fr->callno); 03969 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 03970 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 03971 fr->data = vh; 03972 fr->retries = -1; 03973 res = send_packet(fr); 03974 } else { 03975 /* Mini-frames have no sequence number */ 03976 fr->oseqno = -1; 03977 fr->iseqno = -1; 03978 /* Mini frame will do */ 03979 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 03980 mh->callno = htons(fr->callno); 03981 mh->ts = htons(fr->ts & 0xFFFF); 03982 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 03983 fr->data = mh; 03984 fr->retries = -1; 03985 if (pvt->transferring == TRANSFER_MEDIAPASS) 03986 fr->transfer = 1; 03987 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 03988 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 03989 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 03990 } else 03991 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 03992 } 03993 res = send_packet(fr); 03994 } 03995 } 03996 return res; 03997 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2440 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02441 { 02442 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02443 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2435 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.
02436 { 02437 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02438 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2428 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02429 { 02430 02431 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02432 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02433 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3000 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03001 { 03002 struct ast_option_header *h; 03003 int res; 03004 03005 switch (option) { 03006 case AST_OPTION_TXGAIN: 03007 case AST_OPTION_RXGAIN: 03008 /* these two cannot be sent, because they require a result */ 03009 errno = ENOSYS; 03010 return -1; 03011 default: 03012 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03013 return -1; 03014 03015 h->flag = AST_OPTION_FLAG_REQUEST; 03016 h->option = htons(option); 03017 memcpy(h->data, data, datalen); 03018 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03019 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03020 datalen + sizeof(*h), -1); 03021 free(h); 03022 return res; 03023 } 03024 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2126 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.
02127 { 02128 struct iax2_dpcache *dp; 02129 char tmp[1024], *pc; 02130 int s; 02131 int x,y; 02132 struct timeval tv; 02133 gettimeofday(&tv, NULL); 02134 ast_mutex_lock(&dpcache_lock); 02135 dp = dpcache; 02136 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02137 while(dp) { 02138 s = dp->expiry.tv_sec - tv.tv_sec; 02139 tmp[0] = '\0'; 02140 if (dp->flags & CACHE_FLAG_EXISTS) 02141 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02142 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02143 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02144 if (dp->flags & CACHE_FLAG_CANEXIST) 02145 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02146 if (dp->flags & CACHE_FLAG_PENDING) 02147 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02148 if (dp->flags & CACHE_FLAG_TIMEOUT) 02149 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02150 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02151 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02152 if (dp->flags & CACHE_FLAG_MATCHMORE) 02153 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02154 if (dp->flags & CACHE_FLAG_UNKNOWN) 02155 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02156 /* Trim trailing pipe */ 02157 if (!ast_strlen_zero(tmp)) 02158 tmp[strlen(tmp) - 1] = '\0'; 02159 else 02160 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02161 y=0; 02162 pc = strchr(dp->peercontext, '@'); 02163 if (!pc) 02164 pc = dp->peercontext; 02165 else 02166 pc++; 02167 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02168 if (dp->waiters[x] > -1) 02169 y++; 02170 if (s > 0) 02171 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02172 else 02173 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02174 dp = dp->next; 02175 } 02176 ast_mutex_unlock(&dpcache_lock); 02177 return RESULT_SUCCESS; 02178 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4340 of file chan_iax2.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, 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.
04341 { 04342 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04343 #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" 04344 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04345 int x; 04346 int numchans = 0; 04347 04348 if (argc != 3) 04349 return RESULT_SHOWUSAGE; 04350 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04351 for (x=0;x<IAX_MAX_CALLS;x++) { 04352 ast_mutex_lock(&iaxsl[x]); 04353 if (iaxs[x]) { 04354 int lag, jitter, localdelay; 04355 jb_info jbinfo; 04356 04357 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04358 jb_getinfo(iaxs[x]->jb, &jbinfo); 04359 jitter = jbinfo.jitter; 04360 localdelay = jbinfo.current - jbinfo.min; 04361 } else { 04362 jitter = -1; 04363 localdelay = 0; 04364 } 04365 lag = iaxs[x]->remote_rr.delay; 04366 ast_cli(fd, FORMAT, 04367 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04368 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04369 S_OR(iaxs[x]->username, "(None)"), 04370 iaxs[x]->callno, iaxs[x]->peercallno, 04371 iaxs[x]->oseqno, iaxs[x]->iseqno, 04372 lag, 04373 jitter, 04374 localdelay, 04375 ast_getformatname(iaxs[x]->voiceformat) ); 04376 numchans++; 04377 } 04378 ast_mutex_unlock(&iaxsl[x]); 04379 } 04380 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04381 return RESULT_SUCCESS; 04382 #undef FORMAT 04383 #undef FORMAT2 04384 #undef FORMATB 04385 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4251 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.
04252 { 04253 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04254 #if !defined(__FreeBSD__) 04255 #define FORMAT "%-15.15s %-15d %-15d\n" 04256 #else /* __FreeBSD__ */ 04257 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04258 #endif /* __FreeBSD__ */ 04259 struct iax_firmware *cur; 04260 if ((argc != 3) && (argc != 4)) 04261 return RESULT_SHOWUSAGE; 04262 ast_mutex_lock(&waresl.lock); 04263 04264 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04265 for (cur = waresl.wares;cur;cur = cur->next) { 04266 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04267 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04268 (int)ntohl(cur->fwh->datalen)); 04269 } 04270 ast_mutex_unlock(&waresl.lock); 04271 return RESULT_SUCCESS; 04272 #undef FORMAT 04273 #undef FORMAT2 04274 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4463 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04464 { 04465 int numchans = 0; 04466 if (argc != 3) 04467 return RESULT_SHOWUSAGE; 04468 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04469 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04470 numchans = ast_cli_netstats(NULL, fd, 1); 04471 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04472 return RESULT_SUCCESS; 04473 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2018 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, destroy_peer(), iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TEMPONLY, peer_status(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02019 { 02020 char status[30]; 02021 char cbuf[256]; 02022 struct iax2_peer *peer; 02023 char codec_buf[512]; 02024 int x = 0, codec = 0, load_realtime = 0; 02025 02026 if (argc < 4) 02027 return RESULT_SHOWUSAGE; 02028 02029 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02030 02031 peer = find_peer(argv[3], load_realtime); 02032 if (peer) { 02033 ast_cli(fd,"\n\n"); 02034 ast_cli(fd, " * Name : %s\n", peer->name); 02035 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02036 ast_cli(fd, " Context : %s\n", peer->context); 02037 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02038 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02039 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02040 ast_cli(fd, " Expire : %d\n", peer->expire); 02041 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02042 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)); 02043 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02044 ast_cli(fd, " Username : %s\n", peer->username); 02045 ast_cli(fd, " Codecs : "); 02046 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02047 ast_cli(fd, "%s\n", codec_buf); 02048 02049 ast_cli(fd, " Codec Order : ("); 02050 for(x = 0; x < 32 ; x++) { 02051 codec = ast_codec_pref_index(&peer->prefs,x); 02052 if(!codec) 02053 break; 02054 ast_cli(fd, "%s", ast_getformatname(codec)); 02055 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02056 ast_cli(fd, "|"); 02057 } 02058 02059 if (!x) 02060 ast_cli(fd, "none"); 02061 ast_cli(fd, ")\n"); 02062 02063 ast_cli(fd, " Status : "); 02064 peer_status(peer, status, sizeof(status)); 02065 ast_cli(fd, "%s\n",status); 02066 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02067 ast_cli(fd,"\n"); 02068 if (ast_test_flag(peer, IAX_TEMPONLY)) 02069 destroy_peer(peer); 02070 } else { 02071 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02072 ast_cli(fd,"\n"); 02073 } 02074 02075 return RESULT_SUCCESS; 02076 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4240 of file chan_iax2.c.
References __iax2_show_peers().
04241 { 04242 return __iax2_show_peers(0, fd, NULL, argc, argv); 04243 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4312 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.
04313 { 04314 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04315 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04316 struct iax2_registry *reg = NULL; 04317 04318 char host[80]; 04319 char perceived[80]; 04320 if (argc != 3) 04321 return RESULT_SHOWUSAGE; 04322 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04323 AST_LIST_LOCK(®istrations); 04324 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04325 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04326 if (reg->us.sin_addr.s_addr) 04327 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04328 else 04329 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04330 ast_cli(fd, FORMAT, host, 04331 (reg->dnsmgr) ? "Y" : "N", 04332 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04333 } 04334 AST_LIST_UNLOCK(®istrations); 04335 return RESULT_SUCCESS; 04336 #undef FORMAT 04337 #undef FORMAT2 04338 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2100 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.
02101 { 02102 struct iax_frame *cur; 02103 int cnt = 0, dead=0, final=0; 02104 02105 if (argc != 3) 02106 return RESULT_SHOWUSAGE; 02107 02108 AST_LIST_LOCK(&iaxq.queue); 02109 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02110 if (cur->retries < 0) 02111 dead++; 02112 if (cur->final) 02113 final++; 02114 cnt++; 02115 } 02116 AST_LIST_UNLOCK(&iaxq.queue); 02117 02118 ast_cli(fd, " IAX Statistics\n"); 02119 ast_cli(fd, "---------------------\n"); 02120 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02121 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02122 02123 return RESULT_SUCCESS; 02124 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4181 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, thread, and type.
04182 { 04183 struct iax2_thread *thread = NULL; 04184 time_t t; 04185 int threadcount = 0, dynamiccount = 0; 04186 char type; 04187 04188 if (argc != 3) 04189 return RESULT_SHOWUSAGE; 04190 04191 ast_cli(fd, "IAX2 Thread Information\n"); 04192 time(&t); 04193 ast_cli(fd, "Idle Threads:\n"); 04194 AST_LIST_LOCK(&idle_list); 04195 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04196 #ifdef DEBUG_SCHED_MULTITHREAD 04197 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04198 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04199 #else 04200 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04201 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04202 #endif 04203 threadcount++; 04204 } 04205 AST_LIST_UNLOCK(&idle_list); 04206 ast_cli(fd, "Active Threads:\n"); 04207 AST_LIST_LOCK(&active_list); 04208 AST_LIST_TRAVERSE(&active_list, thread, list) { 04209 if (thread->type == IAX_TYPE_DYNAMIC) 04210 type = 'D'; 04211 else 04212 type = 'P'; 04213 #ifdef DEBUG_SCHED_MULTITHREAD 04214 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04215 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04216 #else 04217 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04218 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04219 #endif 04220 threadcount++; 04221 } 04222 AST_LIST_UNLOCK(&active_list); 04223 ast_cli(fd, "Dynamic Threads:\n"); 04224 AST_LIST_LOCK(&dynamic_list); 04225 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04226 #ifdef DEBUG_SCHED_MULTITHREAD 04227 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04228 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04229 #else 04230 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04231 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04232 #endif 04233 dynamiccount++; 04234 } 04235 AST_LIST_UNLOCK(&dynamic_list); 04236 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04237 return RESULT_SUCCESS; 04238 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3999 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, and RESULT_SUCCESS.
04000 { 04001 regex_t regexbuf; 04002 int havepattern = 0; 04003 04004 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04005 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04006 04007 struct iax2_user *user = NULL; 04008 char auth[90]; 04009 char *pstr = ""; 04010 04011 switch (argc) { 04012 case 5: 04013 if (!strcasecmp(argv[3], "like")) { 04014 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04015 return RESULT_SHOWUSAGE; 04016 havepattern = 1; 04017 } else 04018 return RESULT_SHOWUSAGE; 04019 case 3: 04020 break; 04021 default: 04022 return RESULT_SHOWUSAGE; 04023 } 04024 04025 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04026 AST_LIST_LOCK(&users); 04027 AST_LIST_TRAVERSE(&users, user, entry) { 04028 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04029 continue; 04030 04031 if (!ast_strlen_zero(user->secret)) { 04032 ast_copy_string(auth,user->secret,sizeof(auth)); 04033 } else if (!ast_strlen_zero(user->inkeys)) { 04034 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04035 } else 04036 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04037 04038 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04039 pstr = "REQ Only"; 04040 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04041 pstr = "Disabled"; 04042 else 04043 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04044 04045 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04046 user->contexts ? user->contexts->context : context, 04047 user->ha ? "Yes" : "No", pstr); 04048 04049 } 04050 AST_LIST_UNLOCK(&users); 04051 04052 if (havepattern) 04053 regfree(®exbuf); 04054 04055 return RESULT_SUCCESS; 04056 #undef FORMAT 04057 #undef FORMAT2 04058 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3032 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.
03033 { 03034 int res; 03035 struct iax_ie_data ied0; 03036 struct iax_ie_data ied1; 03037 unsigned int transferid = (unsigned int)ast_random(); 03038 memset(&ied0, 0, sizeof(ied0)); 03039 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03040 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03041 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03042 03043 memset(&ied1, 0, sizeof(ied1)); 03044 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03045 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03046 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03047 03048 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03049 if (res) 03050 return -1; 03051 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03052 if (res) 03053 return -1; 03054 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03055 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03056 return 0; 03057 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1949 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01950 { 01951 if (argc != 4) 01952 return RESULT_SHOWUSAGE; 01953 01954 test_losspct = atoi(argv[3]); 01955 01956 return RESULT_SUCCESS; 01957 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3260 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), 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.
03261 { 03262 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03263 struct iax_ie_data ied; 03264 char tmp[256], *context; 03265 ast_copy_string(tmp, dest, sizeof(tmp)); 03266 context = strchr(tmp, '@'); 03267 if (context) { 03268 *context = '\0'; 03269 context++; 03270 } 03271 memset(&ied, 0, sizeof(ied)); 03272 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03273 if (context) 03274 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03275 if (option_debug) 03276 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03277 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03278 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2399 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().
02400 { 02401 /* Lock the queue and place this packet at the end */ 02402 /* By setting this to 0, the network thread will send it for us, and 02403 queue retransmission if necessary */ 02404 fr->sentyet = 0; 02405 AST_LIST_LOCK(&iaxq.queue); 02406 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02407 iaxq.count++; 02408 AST_LIST_UNLOCK(&iaxq.queue); 02409 /* Wake up the network and scheduler thread */ 02410 if (netthreadid != AST_PTHREADT_NULL) 02411 pthread_kill(netthreadid, SIGURG); 02412 signal_condition(&sched_lock, &sched_cond); 02413 return 0; 02414 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 5968 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
05969 { 05970 /* Drop when trunk is about 5 seconds idle */ 05971 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 05972 return 1; 05973 return 0; 05974 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3602 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, 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().
03603 { 03604 struct ast_frame *f; 03605 struct iax2_trunk_peer *tpeer; 03606 void *tmp, *ptr; 03607 struct ast_iax2_meta_trunk_entry *met; 03608 struct ast_iax2_meta_trunk_mini *mtm; 03609 03610 f = &fr->af; 03611 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03612 if (tpeer) { 03613 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03614 /* Need to reallocate space */ 03615 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03616 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03617 ast_mutex_unlock(&tpeer->lock); 03618 return -1; 03619 } 03620 03621 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03622 tpeer->trunkdata = tmp; 03623 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); 03624 } else { 03625 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)); 03626 ast_mutex_unlock(&tpeer->lock); 03627 return -1; 03628 } 03629 } 03630 03631 /* Append to meta frame */ 03632 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03633 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03634 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03635 mtm->len = htons(f->datalen); 03636 mtm->mini.callno = htons(pvt->callno); 03637 mtm->mini.ts = htons(0xffff & fr->ts); 03638 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03639 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03640 } else { 03641 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03642 /* Store call number and length in meta header */ 03643 met->callno = htons(pvt->callno); 03644 met->len = htons(f->datalen); 03645 /* Advance pointers/decrease length past trunk entry header */ 03646 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03647 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03648 } 03649 /* Copy actual trunk data */ 03650 memcpy(ptr, f->data, f->datalen); 03651 tpeer->trunkdatalen += f->datalen; 03652 03653 tpeer->calls++; 03654 ast_mutex_unlock(&tpeer->lock); 03655 } 03656 return 0; 03657 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 5888 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
05889 { 05890 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 05891 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4530 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, error(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04531 { 04532 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04533 int res = -1; 04534 ast_mutex_lock(&iaxsl[callno]); 04535 if (iaxs[callno]) { 04536 /* If there's an outstanding error, return failure now */ 04537 if (!iaxs[callno]->error) { 04538 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04539 res = 0; 04540 /* Don't waste bandwidth sending null frames */ 04541 else if (f->frametype == AST_FRAME_NULL) 04542 res = 0; 04543 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04544 res = 0; 04545 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04546 res = 0; 04547 else 04548 /* Simple, just queue for transmission */ 04549 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04550 } else { 04551 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04552 } 04553 } 04554 /* If it's already gone, just return */ 04555 ast_mutex_unlock(&iaxsl[callno]); 04556 return res; 04557 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1484 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().
01485 { 01486 int res = 0; 01487 struct iax_firmware *cur; 01488 if (!ast_strlen_zero(dev)) { 01489 ast_mutex_lock(&waresl.lock); 01490 cur = waresl.wares; 01491 while(cur) { 01492 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01493 res = ntohs(cur->fwh->version); 01494 break; 01495 } 01496 cur = cur->next; 01497 } 01498 ast_mutex_unlock(&waresl.lock); 01499 } 01500 return res; 01501 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 719 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00720 { 00721 if (iaxdebug) 00722 ast_verbose("%s", data); 00723 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 725 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00726 { 00727 ast_log(LOG_WARNING, "%s", data); 00728 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1503 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().
01504 { 01505 int res = -1; 01506 unsigned int bs = desc & 0xff; 01507 unsigned int start = (desc >> 8) & 0xffffff; 01508 unsigned int bytes; 01509 struct iax_firmware *cur; 01510 if (!ast_strlen_zero((char *)dev) && bs) { 01511 start *= bs; 01512 ast_mutex_lock(&waresl.lock); 01513 cur = waresl.wares; 01514 while(cur) { 01515 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01516 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01517 if (start < ntohl(cur->fwh->datalen)) { 01518 bytes = ntohl(cur->fwh->datalen) - start; 01519 if (bytes > bs) 01520 bytes = bs; 01521 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01522 } else { 01523 bytes = 0; 01524 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01525 } 01526 if (bytes == bs) 01527 res = 0; 01528 else 01529 res = 1; 01530 break; 01531 } 01532 cur = cur->next; 01533 } 01534 ast_mutex_unlock(&waresl.lock); 01535 } 01536 return res; 01537 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6150 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().
06151 { 06152 struct iax_dual *d; 06153 struct ast_channel *chan1m, *chan2m; 06154 pthread_t th; 06155 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06156 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06157 if (chan2m && chan1m) { 06158 /* Make formats okay */ 06159 chan1m->readformat = chan1->readformat; 06160 chan1m->writeformat = chan1->writeformat; 06161 ast_channel_masquerade(chan1m, chan1); 06162 /* Setup the extensions and such */ 06163 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06164 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06165 chan1m->priority = chan1->priority; 06166 06167 /* We make a clone of the peer channel too, so we can play 06168 back the announcement */ 06169 /* Make formats okay */ 06170 chan2m->readformat = chan2->readformat; 06171 chan2m->writeformat = chan2->writeformat; 06172 ast_channel_masquerade(chan2m, chan2); 06173 /* Setup the extensions and such */ 06174 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06175 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06176 chan2m->priority = chan2->priority; 06177 if (ast_do_masquerade(chan2m)) { 06178 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06179 ast_hangup(chan2m); 06180 return -1; 06181 } 06182 } else { 06183 if (chan1m) 06184 ast_hangup(chan1m); 06185 if (chan2m) 06186 ast_hangup(chan2m); 06187 return -1; 06188 } 06189 if ((d = ast_calloc(1, sizeof(*d)))) { 06190 pthread_attr_t attr; 06191 06192 pthread_attr_init(&attr); 06193 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06194 06195 d->chan1 = chan1m; 06196 d->chan2 = chan2m; 06197 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06198 pthread_attr_destroy(&attr); 06199 return 0; 06200 } 06201 pthread_attr_destroy(&attr); 06202 free(d); 06203 } 06204 return -1; 06205 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6130 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().
06131 { 06132 struct ast_channel *chan1, *chan2; 06133 struct iax_dual *d; 06134 struct ast_frame *f; 06135 int ext; 06136 int res; 06137 d = stuff; 06138 chan1 = d->chan1; 06139 chan2 = d->chan2; 06140 free(d); 06141 f = ast_read(chan1); 06142 if (f) 06143 ast_frfree(f); 06144 res = ast_park_call(chan1, chan2, 0, &ext); 06145 ast_hangup(chan2); 06146 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06147 return NULL; 06148 }
Definition at line 1090 of file chan_iax2.c.
References iax_frame::af, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), iax_frame_wrap(), and iax_frame::mallocd_datalen.
Referenced by socket_process().
01091 { 01092 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01093 if (new) { 01094 size_t mallocd_datalen = new->mallocd_datalen; 01095 memcpy(new, fr, sizeof(*new)); 01096 iax_frame_wrap(new, &fr->af); 01097 new->mallocd_datalen = mallocd_datalen; 01098 new->data = NULL; 01099 new->datalen = 0; 01100 new->direction = DIRECTION_INGRESS; 01101 new->retrans = -1; 01102 } 01103 return new; 01104 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 829 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(), and socket_read().
00830 { 00831 if (thread->type == IAX_TYPE_DYNAMIC) { 00832 AST_LIST_LOCK(&dynamic_list); 00833 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00834 AST_LIST_UNLOCK(&dynamic_list); 00835 } else { 00836 AST_LIST_LOCK(&idle_list); 00837 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00838 AST_LIST_UNLOCK(&idle_list); 00839 } 00840 00841 return; 00842 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 754 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00755 { 00756 va_list args; 00757 char buf[1024]; 00758 00759 va_start(args, fmt); 00760 vsnprintf(buf, 1024, fmt, args); 00761 va_end(args); 00762 00763 ast_verbose(buf); 00764 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 730 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00731 { 00732 va_list args; 00733 char buf[1024]; 00734 00735 va_start(args, fmt); 00736 vsnprintf(buf, 1024, fmt, args); 00737 va_end(args); 00738 00739 ast_log(LOG_ERROR, buf); 00740 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 742 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00743 { 00744 va_list args; 00745 char buf[1024]; 00746 00747 va_start(args, fmt); 00748 vsnprintf(buf, 1024, fmt, args); 00749 va_end(args); 00750 00751 ast_log(LOG_WARNING, buf); 00752 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 10146 of file chan_iax2.c.
References __unload_module(), 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_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, iax2_do_register(), iax2_poke_peer(), 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, iaxvar_function, 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(), netsock, option_verbose, outsock, reload_firmware(), sched, sched_context_create(), set_config(), iax2_peer::sockfd, start_network_thread(), VERBOSE_PREFIX_2, and waresl.
10147 { 10148 char *config = "iax.conf"; 10149 int res = 0; 10150 int x; 10151 struct iax2_registry *reg = NULL; 10152 struct iax2_peer *peer = NULL; 10153 10154 ast_custom_function_register(&iaxpeer_function); 10155 ast_custom_function_register(&iaxvar_function); 10156 10157 iax_set_output(iax_debug_output); 10158 iax_set_error(iax_error_output); 10159 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10160 10161 #ifdef HAVE_ZAPTEL 10162 #ifdef ZT_TIMERACK 10163 timingfd = open("/dev/zap/timer", O_RDWR); 10164 if (timingfd < 0) 10165 #endif 10166 timingfd = open("/dev/zap/pseudo", O_RDWR); 10167 if (timingfd < 0) 10168 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10169 #endif 10170 10171 memset(iaxs, 0, sizeof(iaxs)); 10172 10173 for (x=0;x<IAX_MAX_CALLS;x++) 10174 ast_mutex_init(&iaxsl[x]); 10175 10176 ast_cond_init(&sched_cond, NULL); 10177 10178 io = io_context_create(); 10179 sched = sched_context_create(); 10180 10181 if (!io || !sched) { 10182 ast_log(LOG_ERROR, "Out of memory\n"); 10183 return -1; 10184 } 10185 10186 netsock = ast_netsock_list_alloc(); 10187 if (!netsock) { 10188 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10189 return -1; 10190 } 10191 ast_netsock_init(netsock); 10192 10193 outsock = ast_netsock_list_alloc(); 10194 if (!outsock) { 10195 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10196 return -1; 10197 } 10198 ast_netsock_init(outsock); 10199 10200 ast_mutex_init(&waresl.lock); 10201 10202 AST_LIST_HEAD_INIT(&iaxq.queue); 10203 10204 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10205 10206 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10207 10208 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10209 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10210 10211 if(set_config(config, 0) == -1) 10212 return AST_MODULE_LOAD_DECLINE; 10213 10214 if (ast_channel_register(&iax2_tech)) { 10215 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10216 __unload_module(); 10217 return -1; 10218 } 10219 10220 if (ast_register_switch(&iax2_switch)) 10221 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10222 10223 res = start_network_thread(); 10224 if (!res) { 10225 if (option_verbose > 1) 10226 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10227 } else { 10228 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10229 ast_netsock_release(netsock); 10230 ast_netsock_release(outsock); 10231 } 10232 10233 AST_LIST_LOCK(®istrations); 10234 AST_LIST_TRAVERSE(®istrations, reg, entry) 10235 iax2_do_register(reg); 10236 AST_LIST_UNLOCK(®istrations); 10237 10238 AST_LIST_LOCK(&peers); 10239 AST_LIST_TRAVERSE(&peers, peer, entry) { 10240 if (peer->sockfd < 0) 10241 peer->sockfd = defaultsockfd; 10242 iax2_poke_peer(peer, 0); 10243 } 10244 AST_LIST_UNLOCK(&peers); 10245 reload_firmware(); 10246 iax_provision_reload(); 10247 return res; 10248 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3059 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03060 { 03061 ast_mutex_lock(&iaxsl[callno0]); 03062 while (ast_mutex_trylock(&iaxsl[callno1])) { 03063 ast_mutex_unlock(&iaxsl[callno0]); 03064 usleep(10); 03065 ast_mutex_lock(&iaxsl[callno0]); 03066 } 03067 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1158 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, 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().
01159 { 01160 int x; 01161 int res= 0; 01162 struct timeval now; 01163 if (iaxs[callno]->oseqno) { 01164 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01165 return -1; 01166 } 01167 if (callno & TRUNK_CALL_START) { 01168 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01169 return -1; 01170 } 01171 gettimeofday(&now, NULL); 01172 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01173 ast_mutex_lock(&iaxsl[x]); 01174 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01175 iaxs[x] = iaxs[callno]; 01176 iaxs[x]->callno = x; 01177 iaxs[callno] = NULL; 01178 /* Update the two timers that should have been started */ 01179 if (iaxs[x]->pingid > -1) 01180 ast_sched_del(sched, iaxs[x]->pingid); 01181 if (iaxs[x]->lagid > -1) 01182 ast_sched_del(sched, iaxs[x]->lagid); 01183 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01184 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01185 if (locked) 01186 ast_mutex_unlock(&iaxsl[callno]); 01187 res = x; 01188 if (!locked) 01189 ast_mutex_unlock(&iaxsl[x]); 01190 break; 01191 } 01192 ast_mutex_unlock(&iaxsl[x]); 01193 } 01194 if (x >= IAX_MAX_CALLS - 1) { 01195 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01196 return -1; 01197 } 01198 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01199 /* We move this call from a non-trunked to a trunked call */ 01200 update_max_trunk(); 01201 update_max_nontrunk(); 01202 return res; 01203 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4244 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04245 { 04246 ast_cli_netstats(s, -1, 0); 04247 astman_append(s, "\r\n"); 04248 return RESULT_SUCCESS; 04249 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4277 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04278 { 04279 char *a[] = { "iax2", "show", "users" }; 04280 int ret; 04281 const char *id = astman_get_header(m,"ActionID"); 04282 04283 if (!ast_strlen_zero(id)) 04284 astman_append(s, "ActionID: %s\r\n",id); 04285 ret = __iax2_show_peers(1, -1, s, 3, a ); 04286 astman_append(s, "\r\n\r\n" ); 04287 return ret; 04288 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur | |||
) | [static] |
Definition at line 1110 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and chan_iax2_pvt::transferring.
Referenced by ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01111 { 01112 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01113 (cur->addr.sin_port == sin->sin_port)) { 01114 /* This is the main host */ 01115 if ((cur->peercallno == callno) || 01116 ((dcallno == cur->callno) && !cur->peercallno)) { 01117 /* That's us. Be sure we keep track of the peer call number */ 01118 return 1; 01119 } 01120 } 01121 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01122 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01123 /* We're transferring */ 01124 if (dcallno == cur->callno) 01125 return 1; 01126 } 01127 return 0; 01128 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3665 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03666 { 03667 #if 0 03668 /* Debug with "fake encryption" */ 03669 int x; 03670 if (len % 16) 03671 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03672 for (x=0;x<len;x++) 03673 dst[x] = src[x] ^ 0xff; 03674 #else 03675 unsigned char lastblock[16] = { 0 }; 03676 int x; 03677 while(len > 0) { 03678 aes_decrypt(src, dst, dcx); 03679 for (x=0;x<16;x++) 03680 dst[x] ^= lastblock[x]; 03681 memcpy(lastblock, src, sizeof(lastblock)); 03682 dst += 16; 03683 src += 16; 03684 len -= 16; 03685 } 03686 #endif 03687 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3689 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03690 { 03691 #if 0 03692 /* Debug with "fake encryption" */ 03693 int x; 03694 if (len % 16) 03695 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03696 for (x=0;x<len;x++) 03697 dst[x] = src[x] ^ 0xff; 03698 #else 03699 unsigned char curblock[16] = { 0 }; 03700 int x; 03701 while(len > 0) { 03702 for (x=0;x<16;x++) 03703 curblock[x] ^= src[x]; 03704 aes_encrypt(curblock, dst, ecx); 03705 memcpy(curblock, dst, sizeof(curblock)); 03706 dst += 16; 03707 src += 16; 03708 len -= 16; 03709 } 03710 #endif 03711 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 4835 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
04836 { 04837 /* Select exactly one common encryption if there are any */ 04838 p->encmethods &= enc; 04839 if (p->encmethods) { 04840 if (p->encmethods & IAX_ENCRYPT_AES128) 04841 p->encmethods = IAX_ENCRYPT_AES128; 04842 else 04843 p->encmethods = 0; 04844 } 04845 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8156 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_sched_add(), attempt_transmit(), f, iax_frame_free(), iaxq, iaxs, iaxsl, io, sched, send_packet(), signal_condition(), and timing_read().
Referenced by start_network_thread().
08157 { 08158 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08159 from the network, and queue them for delivery to the channels */ 08160 int res, count, wakeup; 08161 struct iax_frame *f; 08162 08163 if (timingfd > -1) 08164 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08165 08166 for(;;) { 08167 pthread_testcancel(); 08168 08169 /* Go through the queue, sending messages which have not yet been 08170 sent, and scheduling retransmissions if appropriate */ 08171 AST_LIST_LOCK(&iaxq.queue); 08172 count = 0; 08173 wakeup = -1; 08174 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08175 if (f->sentyet) 08176 continue; 08177 08178 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08179 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08180 wakeup = 1; 08181 continue; 08182 } 08183 08184 f->sentyet++; 08185 08186 if (iaxs[f->callno]) { 08187 send_packet(f); 08188 count++; 08189 } 08190 08191 ast_mutex_unlock(&iaxsl[f->callno]); 08192 08193 if (f->retries < 0) { 08194 /* This is not supposed to be retransmitted */ 08195 AST_LIST_REMOVE(&iaxq.queue, f, list); 08196 iaxq.count--; 08197 /* Free the iax frame */ 08198 iax_frame_free(f); 08199 } else { 08200 /* We need reliable delivery. Schedule a retransmission */ 08201 f->retries++; 08202 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 08203 signal_condition(&sched_lock, &sched_cond); 08204 } 08205 } 08206 AST_LIST_TRAVERSE_SAFE_END 08207 AST_LIST_UNLOCK(&iaxq.queue); 08208 08209 pthread_testcancel(); 08210 08211 if (count >= 20) 08212 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08213 08214 /* Now do the IO, and run scheduled tasks */ 08215 res = ast_io_wait(io, wakeup); 08216 if (res >= 0) { 08217 if (res >= 20) 08218 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08219 } 08220 } 08221 return NULL; 08222 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
int | lockpeer, | |||
const char * | host | |||
) | [static] |
Definition at line 1052 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, iax2_user::prefs, and jb_conf::resync_threshold.
Referenced by find_callno().
01053 { 01054 struct chan_iax2_pvt *tmp; 01055 jb_conf jbconf; 01056 01057 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01058 return NULL; 01059 01060 if (ast_string_field_init(tmp, 32)) { 01061 free(tmp); 01062 tmp = NULL; 01063 return NULL; 01064 } 01065 01066 tmp->prefs = prefs; 01067 tmp->callno = 0; 01068 tmp->peercallno = 0; 01069 tmp->transfercallno = 0; 01070 tmp->bridgecallno = 0; 01071 tmp->pingid = -1; 01072 tmp->lagid = -1; 01073 tmp->autoid = -1; 01074 tmp->authid = -1; 01075 tmp->initid = -1; 01076 01077 ast_string_field_set(tmp,exten, "s"); 01078 ast_string_field_set(tmp,host, host); 01079 01080 tmp->jb = jb_new(); 01081 tmp->jbid = -1; 01082 jbconf.max_jitterbuf = maxjitterbuffer; 01083 jbconf.resync_threshold = resyncthreshold; 01084 jbconf.max_contig_interp = maxjitterinterps; 01085 jb_setconf(tmp->jb,&jbconf); 01086 01087 return tmp; 01088 }
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 2781 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().
02782 { 02783 if (ast_strlen_zero(data)) 02784 return; 02785 02786 pds->peer = strsep(&data, "/"); 02787 pds->exten = strsep(&data, "/"); 02788 pds->options = data; 02789 02790 if (pds->exten) { 02791 data = pds->exten; 02792 pds->exten = strsep(&data, "@"); 02793 pds->context = data; 02794 } 02795 02796 if (strchr(pds->peer, '@')) { 02797 data = pds->peer; 02798 pds->username = strsep(&data, "@"); 02799 pds->peer = data; 02800 } 02801 02802 if (pds->username) { 02803 data = pds->username; 02804 pds->username = strsep(&data, ":"); 02805 pds->password = data; 02806 } 02807 02808 data = pds->peer; 02809 pds->peer = strsep(&data, ":"); 02810 pds->port = data; 02811 02812 /* check for a key name wrapped in [] in the secret position, if found, 02813 move it to the key field instead 02814 */ 02815 if (pds->password && (pds->password[0] == '[')) { 02816 pds->key = ast_strip_quoted(pds->password, "[", "]"); 02817 pds->password = NULL; 02818 } 02819 }
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 8306 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, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
08307 { 08308 struct sockaddr_in sin; 08309 int nonlocal = 1; 08310 int port = IAX_DEFAULT_PORTNO; 08311 int sockfd = defaultsockfd; 08312 char *tmp; 08313 char *addr; 08314 char *portstr; 08315 08316 if (!(tmp = ast_strdupa(srcaddr))) 08317 return -1; 08318 08319 addr = strsep(&tmp, ":"); 08320 portstr = tmp; 08321 08322 if (portstr) { 08323 port = atoi(portstr); 08324 if (port < 1) 08325 port = IAX_DEFAULT_PORTNO; 08326 } 08327 08328 if (!ast_get_ip(&sin, addr)) { 08329 struct ast_netsock *sock; 08330 int res; 08331 08332 sin.sin_port = 0; 08333 sin.sin_family = AF_INET; 08334 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08335 if (res == 0) { 08336 /* ip address valid. */ 08337 sin.sin_port = htons(port); 08338 if (!(sock = ast_netsock_find(netsock, &sin))) 08339 sock = ast_netsock_find(outsock, &sin); 08340 if (sock) { 08341 sockfd = ast_netsock_sockfd(sock); 08342 nonlocal = 0; 08343 } else { 08344 unsigned int orig_saddr = sin.sin_addr.s_addr; 08345 /* INADDR_ANY matches anyway! */ 08346 sin.sin_addr.s_addr = INADDR_ANY; 08347 if (ast_netsock_find(netsock, &sin)) { 08348 sin.sin_addr.s_addr = orig_saddr; 08349 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 08350 if (sock) { 08351 sockfd = ast_netsock_sockfd(sock); 08352 ast_netsock_unref(sock); 08353 nonlocal = 0; 08354 } else { 08355 nonlocal = 2; 08356 } 08357 } 08358 } 08359 } 08360 } 08361 08362 peer->sockfd = sockfd; 08363 08364 if (nonlocal == 1) { 08365 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08366 srcaddr, peer->name); 08367 return -1; 08368 } else if (nonlocal == 2) { 08369 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 08370 srcaddr, peer->name); 08371 return -1; 08372 } else { 08373 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08374 return 0; 08375 } 08376 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 1995 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().
01996 { 01997 int res = 0; 01998 if (peer->maxms) { 01999 if (peer->lastms < 0) { 02000 ast_copy_string(status, "UNREACHABLE", statuslen); 02001 } else if (peer->lastms > peer->maxms) { 02002 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02003 res = 1; 02004 } else if (peer->lastms) { 02005 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02006 res = 1; 02007 } else { 02008 ast_copy_string(status, "UNKNOWN", statuslen); 02009 } 02010 } else { 02011 ast_copy_string(status, "Unmonitored", statuslen); 02012 res = -1; 02013 } 02014 return res; 02015 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 8929 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_test_flag, destroy_peer(), and IAX_DELME.
08929 { 08930 /* Prune peers who still are supposed to be deleted */ 08931 struct iax2_peer *peer = NULL; 08932 08933 AST_LIST_LOCK(&peers); 08934 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) { 08935 if (ast_test_flag(peer, IAX_DELME)) { 08936 destroy_peer(peer); 08937 AST_LIST_REMOVE_CURRENT(&peers, entry); 08938 } 08939 } 08940 AST_LIST_TRAVERSE_SAFE_END 08941 AST_LIST_UNLOCK(&peers); 08942 }
static void prune_users | ( | void | ) | [static] |
Definition at line 8888 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_test_flag, destroy_user(), and IAX_DELME.
Referenced by reload_config().
08889 { 08890 struct iax2_user *user = NULL; 08891 08892 AST_LIST_LOCK(&users); 08893 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) { 08894 if (ast_test_flag(user, IAX_DELME)) { 08895 destroy_user(user); 08896 AST_LIST_REMOVE_CURRENT(&users, entry); 08897 } 08898 } 08899 AST_LIST_TRAVERSE_SAFE_END 08900 AST_LIST_UNLOCK(&users); 08901 08902 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 4815 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().
04816 { 04817 struct ast_iax2_full_hdr fh; 04818 fh.scallno = htons(src | IAX_FLAG_FULL); 04819 fh.dcallno = htons(dst); 04820 fh.ts = 0; 04821 fh.oseqno = 0; 04822 fh.iseqno = 0; 04823 fh.type = AST_FRAME_IAX; 04824 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 04825 if (iaxdebug) 04826 iax_showframe(NULL, &fh, 0, sin, 0); 04827 #if 0 04828 if (option_debug) 04829 #endif 04830 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 04831 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 04832 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 04833 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2457 of file chan_iax2.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_test_flag, ast_variables_destroy(), build_peer(), destroy_peer(), globalflags, IAX_RTCACHEFRIENDS, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02458 { 02459 struct ast_variable *var; 02460 struct ast_variable *tmp; 02461 struct iax2_peer *peer=NULL; 02462 time_t regseconds = 0, nowtime; 02463 int dynamic=0; 02464 02465 if (peername) 02466 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02467 else { 02468 char porta[25]; 02469 sprintf(porta, "%d", ntohs(sin->sin_port)); 02470 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02471 if (var) { 02472 /* We'll need the peer name in order to build the structure! */ 02473 for (tmp = var; tmp; tmp = tmp->next) { 02474 if (!strcasecmp(tmp->name, "name")) 02475 peername = tmp->value; 02476 } 02477 } 02478 } 02479 if (!var) 02480 return NULL; 02481 02482 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02483 02484 if (!peer) { 02485 ast_variables_destroy(var); 02486 return NULL; 02487 } 02488 02489 for (tmp = var; tmp; tmp = tmp->next) { 02490 /* Make sure it's not a user only... */ 02491 if (!strcasecmp(tmp->name, "type")) { 02492 if (strcasecmp(tmp->value, "friend") && 02493 strcasecmp(tmp->value, "peer")) { 02494 /* Whoops, we weren't supposed to exist! */ 02495 destroy_peer(peer); 02496 peer = NULL; 02497 break; 02498 } 02499 } else if (!strcasecmp(tmp->name, "regseconds")) { 02500 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02501 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02502 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02503 } else if (!strcasecmp(tmp->name, "port")) { 02504 peer->addr.sin_port = htons(atoi(tmp->value)); 02505 } else if (!strcasecmp(tmp->name, "host")) { 02506 if (!strcasecmp(tmp->value, "dynamic")) 02507 dynamic = 1; 02508 } 02509 } 02510 02511 ast_variables_destroy(var); 02512 02513 if (!peer) 02514 return NULL; 02515 02516 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02517 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02518 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02519 if (peer->expire > -1) 02520 ast_sched_del(sched, peer->expire); 02521 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name); 02522 } 02523 AST_LIST_LOCK(&peers); 02524 AST_LIST_INSERT_HEAD(&peers, peer, entry); 02525 AST_LIST_UNLOCK(&peers); 02526 if (ast_test_flag(peer, IAX_DYNAMIC)) 02527 reg_source_db(peer); 02528 } else { 02529 ast_set_flag(peer, IAX_TEMPONLY); 02530 } 02531 02532 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02533 time(&nowtime); 02534 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02535 memset(&peer->addr, 0, sizeof(peer->addr)); 02536 realtime_update_peer(peer->name, &peer->addr, 0); 02537 if (option_debug) 02538 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02539 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02540 } 02541 else { 02542 if (option_debug) 02543 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02544 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02545 } 02546 } 02547 02548 return peer; 02549 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2592 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02593 { 02594 char port[10]; 02595 char regseconds[20]; 02596 02597 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02598 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02599 ast_update_realtime("iaxpeers", "name", peername, 02600 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02601 "regseconds", regseconds, NULL); 02602 }
static struct iax2_user* realtime_user | ( | const char * | username | ) | [static] |
Definition at line 2551 of file chan_iax2.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), globalflags, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02552 { 02553 struct ast_variable *var; 02554 struct ast_variable *tmp; 02555 struct iax2_user *user=NULL; 02556 02557 var = ast_load_realtime("iaxusers", "name", username, NULL); 02558 if (!var) 02559 return NULL; 02560 02561 tmp = var; 02562 while(tmp) { 02563 /* Make sure it's not a peer only... */ 02564 if (!strcasecmp(tmp->name, "type")) { 02565 if (strcasecmp(tmp->value, "friend") && 02566 strcasecmp(tmp->value, "user")) { 02567 return NULL; 02568 } 02569 } 02570 tmp = tmp->next; 02571 } 02572 02573 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02574 02575 ast_variables_destroy(var); 02576 02577 if (!user) 02578 return NULL; 02579 02580 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02581 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02582 AST_LIST_LOCK(&users); 02583 AST_LIST_INSERT_HEAD(&users, user, entry); 02584 AST_LIST_UNLOCK(&users); 02585 } else { 02586 ast_set_flag(user, IAX_TEMPONLY); 02587 } 02588 02589 return user; 02590 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5570 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, IAX_TEMPONLY, option_verbose, register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
05571 { 05572 char data[80]; 05573 struct in_addr in; 05574 char *c, *d; 05575 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05576 c = strchr(data, ':'); 05577 if (c) { 05578 *c = '\0'; 05579 c++; 05580 if (inet_aton(data, &in)) { 05581 d = strchr(c, ':'); 05582 if (d) { 05583 *d = '\0'; 05584 d++; 05585 if (option_verbose > 2) 05586 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05587 ast_inet_ntoa(in), atoi(c), atoi(d)); 05588 iax2_poke_peer(p, 0); 05589 p->expiry = atoi(d); 05590 memset(&p->addr, 0, sizeof(p->addr)); 05591 p->addr.sin_family = AF_INET; 05592 p->addr.sin_addr = in; 05593 p->addr.sin_port = htons(atoi(c)); 05594 if (p->expire > -1) 05595 ast_sched_del(sched, p->expire); 05596 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05597 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05598 if (iax2_regfunk) 05599 iax2_regfunk(p->name, 1); 05600 register_peer_exten(p, 1); 05601 } 05602 05603 } 05604 } 05605 } 05606 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5499 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(), destroy_peer(), expire_register(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry().
05500 { 05501 char multi[256]; 05502 char *stringp, *ext; 05503 if (!ast_strlen_zero(regcontext)) { 05504 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05505 stringp = multi; 05506 while((ext = strsep(&stringp, "&"))) { 05507 if (onoff) { 05508 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05509 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05510 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05511 } else 05512 ast_context_remove_extension(regcontext, ext, 1, NULL); 05513 } 05514 } 05515 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 4976 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_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, IAX_TEMPONLY, iaxs, ies, inaddrcmp(), key(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and strsep().
Referenced by handle_request_register(), and socket_process().
04977 { 04978 char requeststr[256] = ""; 04979 char peer[256] = ""; 04980 char md5secret[256] = ""; 04981 char rsasecret[256] = ""; 04982 char secret[256] = ""; 04983 struct iax2_peer *p; 04984 struct ast_key *key; 04985 char *keyn; 04986 int x; 04987 int expire = 0; 04988 04989 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 04990 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 04991 if (ies->username) 04992 ast_copy_string(peer, ies->username, sizeof(peer)); 04993 if (ies->password) 04994 ast_copy_string(secret, ies->password, sizeof(secret)); 04995 if (ies->md5_result) 04996 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 04997 if (ies->rsa_result) 04998 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 04999 if (ies->refresh) 05000 expire = ies->refresh; 05001 05002 if (ast_strlen_zero(peer)) { 05003 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05004 return -1; 05005 } 05006 05007 /* SLD: first call to lookup peer during registration */ 05008 p = find_peer(peer, 1); 05009 05010 if (!p) { 05011 if (authdebug) 05012 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05013 return -1; 05014 } 05015 05016 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05017 if (authdebug) 05018 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05019 if (ast_test_flag(p, IAX_TEMPONLY)) 05020 destroy_peer(p); 05021 return -1; 05022 } 05023 05024 if (!ast_apply_ha(p->ha, sin)) { 05025 if (authdebug) 05026 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05027 if (ast_test_flag(p, IAX_TEMPONLY)) 05028 destroy_peer(p); 05029 return -1; 05030 } 05031 if (!inaddrcmp(&p->addr, sin)) 05032 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05033 ast_string_field_set(iaxs[callno], secret, p->secret); 05034 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05035 /* Check secret against what we have on file */ 05036 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05037 if (!ast_strlen_zero(p->inkeys)) { 05038 char tmpkeys[256]; 05039 char *stringp=NULL; 05040 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05041 stringp=tmpkeys; 05042 keyn = strsep(&stringp, ":"); 05043 while(keyn) { 05044 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05045 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05046 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05047 break; 05048 } else if (!key) 05049 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05050 keyn = strsep(&stringp, ":"); 05051 } 05052 if (!keyn) { 05053 if (authdebug) 05054 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05055 if (ast_test_flag(p, IAX_TEMPONLY)) 05056 destroy_peer(p); 05057 return -1; 05058 } 05059 } else { 05060 if (authdebug) 05061 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05062 if (ast_test_flag(p, IAX_TEMPONLY)) 05063 destroy_peer(p); 05064 return -1; 05065 } 05066 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05067 struct MD5Context md5; 05068 unsigned char digest[16]; 05069 char *tmppw, *stringp; 05070 05071 tmppw = ast_strdupa(p->secret); 05072 stringp = tmppw; 05073 while((tmppw = strsep(&stringp, ";"))) { 05074 MD5Init(&md5); 05075 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05076 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05077 MD5Final(digest, &md5); 05078 for (x=0;x<16;x++) 05079 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05080 if (!strcasecmp(requeststr, md5secret)) 05081 break; 05082 } 05083 if (tmppw) { 05084 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05085 } else { 05086 if (authdebug) 05087 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05088 if (ast_test_flag(p, IAX_TEMPONLY)) 05089 destroy_peer(p); 05090 return -1; 05091 } 05092 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05093 /* They've provided a plain text password and we support that */ 05094 if (strcmp(secret, p->secret)) { 05095 if (authdebug) 05096 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05097 if (ast_test_flag(p, IAX_TEMPONLY)) 05098 destroy_peer(p); 05099 return -1; 05100 } else 05101 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05102 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05103 if (authdebug) 05104 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05105 if (ast_test_flag(p, IAX_TEMPONLY)) 05106 destroy_peer(p); 05107 return -1; 05108 } 05109 ast_string_field_set(iaxs[callno], peer, peer); 05110 /* Choose lowest expiry number */ 05111 if (expire && (expire < iaxs[callno]->expiry)) 05112 iaxs[callno]->expiry = expire; 05113 05114 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05115 05116 if (ast_test_flag(p, IAX_TEMPONLY)) 05117 destroy_peer(p); 05118 return 0; 05119 05120 }
static int registry_authrequest | ( | const char * | name, | |
int | callno | |||
) | [static] |
Definition at line 5715 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_random(), ast_string_field_set, ast_test_flag, iax2_peer::authmethods, destroy_peer(), 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, IAX_TEMPONLY, iaxs, LOG_WARNING, and send_command().
Referenced by socket_process().
05716 { 05717 struct iax_ie_data ied; 05718 struct iax2_peer *p; 05719 char challenge[10]; 05720 /* SLD: third call to find_peer in registration */ 05721 p = find_peer(name, 1); 05722 if (p) { 05723 memset(&ied, 0, sizeof(ied)); 05724 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05725 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 05726 /* Build the challenge */ 05727 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05728 ast_string_field_set(iaxs[callno], challenge, challenge); 05729 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */ 05730 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 05731 } 05732 iax_ie_append_str(&ied, IAX_IE_USERNAME, name); 05733 if (ast_test_flag(p, IAX_TEMPONLY)) 05734 destroy_peer(p); 05735 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 05736 } 05737 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05738 return 0; 05739 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 5741 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().
05742 { 05743 struct iax2_registry *reg; 05744 /* Start pessimistic */ 05745 struct iax_ie_data ied; 05746 char peer[256] = ""; 05747 char challenge[256] = ""; 05748 int res; 05749 int authmethods = 0; 05750 if (ies->authmethods) 05751 authmethods = ies->authmethods; 05752 if (ies->username) 05753 ast_copy_string(peer, ies->username, sizeof(peer)); 05754 if (ies->challenge) 05755 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 05756 memset(&ied, 0, sizeof(ied)); 05757 reg = iaxs[callno]->reg; 05758 if (reg) { 05759 if (inaddrcmp(®->addr, sin)) { 05760 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05761 return -1; 05762 } 05763 if (ast_strlen_zero(reg->secret)) { 05764 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 05765 reg->regstate = REG_STATE_NOAUTH; 05766 return -1; 05767 } 05768 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 05769 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 05770 if (reg->secret[0] == '[') { 05771 char tmpkey[256]; 05772 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 05773 tmpkey[strlen(tmpkey) - 1] = '\0'; 05774 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 05775 } else 05776 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 05777 if (!res) { 05778 reg->regstate = REG_STATE_AUTHSENT; 05779 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 05780 } else 05781 return -1; 05782 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 05783 } else 05784 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 05785 return -1; 05786 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4290 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().
04291 { 04292 switch(regstate) { 04293 case REG_STATE_UNREGISTERED: 04294 return "Unregistered"; 04295 case REG_STATE_REGSENT: 04296 return "Request Sent"; 04297 case REG_STATE_AUTHSENT: 04298 return "Auth. Sent"; 04299 case REG_STATE_REGISTERED: 04300 return "Registered"; 04301 case REG_STATE_REJECTED: 04302 return "Rejected"; 04303 case REG_STATE_TIMEOUT: 04304 return "Timeout"; 04305 case REG_STATE_NOAUTH: 04306 return "No Authentication"; 04307 default: 04308 return "Unknown"; 04309 } 04310 }
static int reload | ( | void | ) | [static] |
Definition at line 9358 of file chan_iax2.c.
References reload_config().
09359 { 09360 return reload_config(); 09361 }
static int reload_config | ( | void | ) | [static] |
Definition at line 9318 of file chan_iax2.c.
References ast_clear_flag, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, delete_users(), globalflags, iax2_do_register(), iax2_poke_peer(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_provision_reload(), IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, prune_peers(), prune_users(), reload_firmware(), and set_config().
09319 { 09320 char *config = "iax.conf"; 09321 struct iax2_registry *reg; 09322 struct iax2_peer *peer; 09323 09324 strcpy(accountcode, ""); 09325 strcpy(language, ""); 09326 strcpy(mohinterpret, "default"); 09327 strcpy(mohsuggest, ""); 09328 amaflags = 0; 09329 delayreject = 0; 09330 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09331 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09332 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09333 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09334 delete_users(); 09335 set_config(config, 1); 09336 prune_peers(); 09337 prune_users(); 09338 AST_LIST_LOCK(®istrations); 09339 AST_LIST_TRAVERSE(®istrations, reg, entry) 09340 iax2_do_register(reg); 09341 AST_LIST_UNLOCK(®istrations); 09342 /* Qualify hosts, too */ 09343 AST_LIST_LOCK(&peers); 09344 AST_LIST_TRAVERSE(&peers, peer, entry) 09345 iax2_poke_peer(peer, 0); 09346 AST_LIST_UNLOCK(&peers); 09347 reload_firmware(); 09348 iax_provision_reload(); 09349 09350 return 0; 09351 }
static void reload_firmware | ( | void | ) | [static] |
Definition at line 1540 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(), ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by load_module(), and reload_config().
01541 { 01542 struct iax_firmware *cur, *curl, *curp; 01543 DIR *fwd; 01544 struct dirent *de; 01545 char dir[256]; 01546 char fn[256]; 01547 /* Mark all as dead */ 01548 ast_mutex_lock(&waresl.lock); 01549 cur = waresl.wares; 01550 while(cur) { 01551 cur->dead = 1; 01552 cur = cur->next; 01553 } 01554 /* Now that we've freed them, load the new ones */ 01555 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01556 fwd = opendir(dir); 01557 if (fwd) { 01558 while((de = readdir(fwd))) { 01559 if (de->d_name[0] != '.') { 01560 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01561 if (!try_firmware(fn)) { 01562 if (option_verbose > 1) 01563 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01564 } 01565 } 01566 } 01567 closedir(fwd); 01568 } else 01569 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01570 01571 /* Clean up leftovers */ 01572 cur = waresl.wares; 01573 curp = NULL; 01574 while(cur) { 01575 curl = cur; 01576 cur = cur->next; 01577 if (curl->dead) { 01578 if (curp) { 01579 curp->next = cur; 01580 } else { 01581 waresl.wares = cur; 01582 } 01583 destroy_firmware(curl); 01584 } else { 01585 curp = cur; 01586 } 01587 } 01588 ast_mutex_unlock(&waresl.lock); 01589 }
Definition at line 6240 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().
06241 { 06242 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06243 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06244 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06245 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06246 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06247 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06248 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06249 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8128 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(), and sched.
Referenced by start_network_thread().
08129 { 08130 int count; 08131 int res; 08132 struct timeval tv; 08133 struct timespec ts; 08134 08135 for (;;) { 08136 res = ast_sched_wait(sched); 08137 if ((res > 1000) || (res < 0)) 08138 res = 1000; 08139 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08140 ts.tv_sec = tv.tv_sec; 08141 ts.tv_nsec = tv.tv_usec * 1000; 08142 08143 pthread_testcancel(); 08144 ast_mutex_lock(&sched_lock); 08145 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08146 ast_mutex_unlock(&sched_lock); 08147 pthread_testcancel(); 08148 08149 count = ast_sched_runq(sched); 08150 if (count >= 20) 08151 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08152 } 08153 return NULL; 08154 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
Definition at line 2318 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, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02319 { 02320 int type, len; 02321 int ret; 02322 int needfree = 0; 02323 02324 /* Attempt to recover wrapped timestamps */ 02325 unwrap_timestamp(fr); 02326 02327 02328 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02329 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02330 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02331 else { 02332 #if 0 02333 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02334 #endif 02335 fr->af.delivery = ast_tv(0,0); 02336 } 02337 02338 type = JB_TYPE_CONTROL; 02339 len = 0; 02340 02341 if(fr->af.frametype == AST_FRAME_VOICE) { 02342 type = JB_TYPE_VOICE; 02343 len = ast_codec_get_samples(&fr->af) / 8; 02344 } else if(fr->af.frametype == AST_FRAME_CNG) { 02345 type = JB_TYPE_SILENCE; 02346 } 02347 02348 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02349 if (tsout) 02350 *tsout = fr->ts; 02351 __do_deliver(fr); 02352 return -1; 02353 } 02354 02355 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02356 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02357 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02358 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02359 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02360 jb_frame frame; 02361 02362 /* deliver any frames in the jb */ 02363 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK) 02364 __do_deliver(frame.data); 02365 02366 jb_reset(iaxs[fr->callno]->jb); 02367 02368 if (iaxs[fr->callno]->jbid > -1) 02369 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02370 02371 iaxs[fr->callno]->jbid = -1; 02372 02373 /* deliver this frame now */ 02374 if (tsout) 02375 *tsout = fr->ts; 02376 __do_deliver(fr); 02377 return -1; 02378 } 02379 02380 /* insert into jitterbuffer */ 02381 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02382 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02383 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02384 if (ret == JB_DROP) { 02385 needfree++; 02386 } else if (ret == JB_SCHED) { 02387 update_jbsched(iaxs[fr->callno]); 02388 } 02389 if (tsout) 02390 *tsout = fr->ts; 02391 if (needfree) { 02392 /* Free our iax frame */ 02393 iax2_frame_free(fr); 02394 return -1; 02395 } 02396 return 0; 02397 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4573 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().
04574 { 04575 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04576 }
static int send_command_final | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4587 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy().
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
04588 { 04589 /* It is assumed that the callno has already been locked */ 04590 iax2_predestroy(i->callno); 04591 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04592 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4594 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04595 { 04596 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04597 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4578 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().
04579 { 04580 int res; 04581 ast_mutex_lock(&iaxsl[callno]); 04582 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04583 ast_mutex_unlock(&iaxsl[callno]); 04584 return res; 04585 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 4599 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04600 { 04601 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04602 }
static int send_lagrq | ( | void * | data | ) | [static] |
Definition at line 960 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
00961 { 00962 #ifdef SCHED_MULTITHREADED 00963 if (schedule_action(__send_lagrq, data)) 00964 #endif 00965 __send_lagrq(data); 00966 return 0; 00967 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1654 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_backtrace(), ast_inet_ntoa(), ast_log(), 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().
01655 { 01656 int res; 01657 int callno; 01658 01659 if( f == NULL ) { 01660 ast_log(LOG_ERROR, "send_packet( NULL )\n"); 01661 ast_backtrace(); 01662 return -1; 01663 } 01664 01665 callno = f->callno; 01666 01667 /* Don't send if there was an error, but return error instead */ 01668 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01669 return -1; 01670 01671 /* Called with iaxsl held */ 01672 if (option_debug > 2 && iaxdebug) 01673 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)); 01674 if (f->transfer) { 01675 if (iaxdebug) 01676 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01677 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01678 sizeof(iaxs[callno]->transfer)); 01679 } else { 01680 if (iaxdebug) 01681 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01682 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01683 sizeof(iaxs[callno]->addr)); 01684 } 01685 if (res < 0) { 01686 if (option_debug && iaxdebug) 01687 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01688 handle_error(); 01689 } else 01690 res = 0; 01691 return res; 01692 }
static int send_ping | ( | void * | data | ) | [static] |
Definition at line 925 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00926 { 00927 #ifdef SCHED_MULTITHREADED 00928 if (schedule_action(__send_ping, data)) 00929 #endif 00930 __send_ping(data); 00931 return 0; 00932 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 5925 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, 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().
05926 { 05927 int res = 0; 05928 struct iax_frame *fr; 05929 struct ast_iax2_meta_hdr *meta; 05930 struct ast_iax2_meta_trunk_hdr *mth; 05931 int calls = 0; 05932 05933 /* Point to frame */ 05934 fr = (struct iax_frame *)tpeer->trunkdata; 05935 /* Point to meta data */ 05936 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 05937 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 05938 if (tpeer->trunkdatalen) { 05939 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 05940 meta->zeros = 0; 05941 meta->metacmd = IAX_META_TRUNK; 05942 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 05943 meta->cmddata = IAX_META_TRUNK_MINI; 05944 else 05945 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 05946 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 05947 /* And the rest of the ast_iax2 header */ 05948 fr->direction = DIRECTION_OUTGRESS; 05949 fr->retrans = -1; 05950 fr->transfer = 0; 05951 /* Any appropriate call will do */ 05952 fr->data = fr->afdata; 05953 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 05954 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 05955 calls = tpeer->calls; 05956 #if 0 05957 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)); 05958 #endif 05959 /* Reset transmit trunk side data */ 05960 tpeer->trunkdatalen = 0; 05961 tpeer->calls = 0; 05962 } 05963 if (res < 0) 05964 return res; 05965 return calls; 05966 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 8961 of file chan_iax2.c.
References ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), AST_LIST_INSERT_HEAD, 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(), DEFAULT_MAXMS, 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, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, portno, prefs, reg_source_db(), set_timing(), socket_read(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
08962 { 08963 struct ast_config *cfg, *ucfg; 08964 int capability=iax2_capability; 08965 struct ast_variable *v; 08966 char *cat; 08967 const char *utype; 08968 const char *tosval; 08969 int format; 08970 int portno = IAX_DEFAULT_PORTNO; 08971 int x; 08972 struct iax2_user *user; 08973 struct iax2_peer *peer; 08974 struct ast_netsock *ns; 08975 #if 0 08976 static unsigned short int last_port=0; 08977 #endif 08978 08979 cfg = ast_config_load(config_file); 08980 08981 if (!cfg) { 08982 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08983 return -1; 08984 } 08985 08986 /* Reset global codec prefs */ 08987 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08988 08989 /* Reset Global Flags */ 08990 memset(&globalflags, 0, sizeof(globalflags)); 08991 ast_set_flag(&globalflags, IAX_RTUPDATE); 08992 08993 #ifdef SO_NO_CHECK 08994 nochecksums = 0; 08995 #endif 08996 08997 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08998 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08999 09000 maxauthreq = 3; 09001 09002 v = ast_variable_browse(cfg, "general"); 09003 09004 /* Seed initial tos value */ 09005 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09006 if (tosval) { 09007 if (ast_str2tos(tosval, &tos)) 09008 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09009 } 09010 while(v) { 09011 if (!strcasecmp(v->name, "bindport")){ 09012 if (reload) 09013 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09014 else 09015 portno = atoi(v->value); 09016 } else if (!strcasecmp(v->name, "pingtime")) 09017 ping_time = atoi(v->value); 09018 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09019 if (reload) { 09020 if (atoi(v->value) != iaxthreadcount) 09021 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09022 } else { 09023 iaxthreadcount = atoi(v->value); 09024 if (iaxthreadcount < 1) { 09025 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09026 iaxthreadcount = 1; 09027 } else if (iaxthreadcount > 256) { 09028 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09029 iaxthreadcount = 256; 09030 } 09031 } 09032 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09033 if (reload) { 09034 AST_LIST_LOCK(&dynamic_list); 09035 iaxmaxthreadcount = atoi(v->value); 09036 AST_LIST_UNLOCK(&dynamic_list); 09037 } else { 09038 iaxmaxthreadcount = atoi(v->value); 09039 if (iaxmaxthreadcount < 0) { 09040 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09041 iaxmaxthreadcount = 0; 09042 } else if (iaxmaxthreadcount > 256) { 09043 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09044 iaxmaxthreadcount = 256; 09045 } 09046 } 09047 } else if (!strcasecmp(v->name, "nochecksums")) { 09048 #ifdef SO_NO_CHECK 09049 if (ast_true(v->value)) 09050 nochecksums = 1; 09051 else 09052 nochecksums = 0; 09053 #else 09054 if (ast_true(v->value)) 09055 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09056 #endif 09057 } 09058 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09059 maxjitterbuffer = atoi(v->value); 09060 else if (!strcasecmp(v->name, "resyncthreshold")) 09061 resyncthreshold = atoi(v->value); 09062 else if (!strcasecmp(v->name, "maxjitterinterps")) 09063 maxjitterinterps = atoi(v->value); 09064 else if (!strcasecmp(v->name, "lagrqtime")) 09065 lagrq_time = atoi(v->value); 09066 else if (!strcasecmp(v->name, "maxregexpire")) 09067 max_reg_expire = atoi(v->value); 09068 else if (!strcasecmp(v->name, "minregexpire")) 09069 min_reg_expire = atoi(v->value); 09070 else if (!strcasecmp(v->name, "bindaddr")) { 09071 if (reload) { 09072 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09073 } else { 09074 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09075 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09076 } else { 09077 if (option_verbose > 1) { 09078 if (strchr(v->value, ':')) 09079 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09080 else 09081 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09082 } 09083 if (defaultsockfd < 0) 09084 defaultsockfd = ast_netsock_sockfd(ns); 09085 ast_netsock_unref(ns); 09086 } 09087 } 09088 } else if (!strcasecmp(v->name, "authdebug")) 09089 authdebug = ast_true(v->value); 09090 else if (!strcasecmp(v->name, "encryption")) 09091 iax2_encryption = get_encrypt_methods(v->value); 09092 else if (!strcasecmp(v->name, "notransfer")) { 09093 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09094 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09095 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09096 } else if (!strcasecmp(v->name, "transfer")) { 09097 if (!strcasecmp(v->value, "mediaonly")) { 09098 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09099 } else if (ast_true(v->value)) { 09100 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09101 } else 09102 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09103 } else if (!strcasecmp(v->name, "codecpriority")) { 09104 if(!strcasecmp(v->value, "caller")) 09105 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09106 else if(!strcasecmp(v->value, "disabled")) 09107 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09108 else if(!strcasecmp(v->value, "reqonly")) { 09109 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09110 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09111 } 09112 } else if (!strcasecmp(v->name, "jitterbuffer")) 09113 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09114 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09115 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09116 else if (!strcasecmp(v->name, "delayreject")) 09117 delayreject = ast_true(v->value); 09118 else if (!strcasecmp(v->name, "rtcachefriends")) 09119 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09120 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09121 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09122 else if (!strcasecmp(v->name, "rtupdate")) 09123 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09124 else if (!strcasecmp(v->name, "trunktimestamps")) 09125 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09126 else if (!strcasecmp(v->name, "rtautoclear")) { 09127 int i = atoi(v->value); 09128 if(i > 0) 09129 global_rtautoclear = i; 09130 else 09131 i = 0; 09132 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09133 } else if (!strcasecmp(v->name, "trunkfreq")) { 09134 trunkfreq = atoi(v->value); 09135 if (trunkfreq < 10) 09136 trunkfreq = 10; 09137 } else if (!strcasecmp(v->name, "autokill")) { 09138 if (sscanf(v->value, "%d", &x) == 1) { 09139 if (x >= 0) 09140 autokill = x; 09141 else 09142 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09143 } else if (ast_true(v->value)) { 09144 autokill = DEFAULT_MAXMS; 09145 } else { 09146 autokill = 0; 09147 } 09148 } else if (!strcasecmp(v->name, "bandwidth")) { 09149 if (!strcasecmp(v->value, "low")) { 09150 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09151 } else if (!strcasecmp(v->value, "medium")) { 09152 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09153 } else if (!strcasecmp(v->value, "high")) { 09154 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09155 } else 09156 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09157 } else if (!strcasecmp(v->name, "allow")) { 09158 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09159 } else if (!strcasecmp(v->name, "disallow")) { 09160 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09161 } else if (!strcasecmp(v->name, "register")) { 09162 iax2_register(v->value, v->lineno); 09163 } else if (!strcasecmp(v->name, "iaxcompat")) { 09164 iaxcompat = ast_true(v->value); 09165 } else if (!strcasecmp(v->name, "regcontext")) { 09166 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09167 /* Create context if it doesn't exist already */ 09168 if (!ast_context_find(regcontext)) 09169 ast_context_create(NULL, regcontext, "IAX2"); 09170 } else if (!strcasecmp(v->name, "tos")) { 09171 if (ast_str2tos(v->value, &tos)) 09172 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09173 } else if (!strcasecmp(v->name, "accountcode")) { 09174 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09175 } else if (!strcasecmp(v->name, "mohinterpret")) { 09176 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09177 } else if (!strcasecmp(v->name, "mohsuggest")) { 09178 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09179 } else if (!strcasecmp(v->name, "amaflags")) { 09180 format = ast_cdr_amaflags2int(v->value); 09181 if (format < 0) { 09182 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09183 } else { 09184 amaflags = format; 09185 } 09186 } else if (!strcasecmp(v->name, "language")) { 09187 ast_copy_string(language, v->value, sizeof(language)); 09188 } else if (!strcasecmp(v->name, "maxauthreq")) { 09189 maxauthreq = atoi(v->value); 09190 if (maxauthreq < 0) 09191 maxauthreq = 0; 09192 } else if (!strcasecmp(v->name, "adsi")) { 09193 adsi = ast_true(v->value); 09194 } /*else if (strcasecmp(v->name,"type")) */ 09195 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09196 v = v->next; 09197 } 09198 09199 if (defaultsockfd < 0) { 09200 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09201 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09202 } else { 09203 if (option_verbose > 1) 09204 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09205 defaultsockfd = ast_netsock_sockfd(ns); 09206 ast_netsock_unref(ns); 09207 } 09208 } 09209 if (reload) { 09210 ast_netsock_release(outsock); 09211 outsock = ast_netsock_list_alloc(); 09212 if (!outsock) { 09213 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09214 return -1; 09215 } 09216 ast_netsock_init(outsock); 09217 } 09218 09219 if (min_reg_expire > max_reg_expire) { 09220 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09221 min_reg_expire, max_reg_expire, max_reg_expire); 09222 min_reg_expire = max_reg_expire; 09223 } 09224 iax2_capability = capability; 09225 09226 ucfg = ast_config_load("users.conf"); 09227 if (ucfg) { 09228 struct ast_variable *gen; 09229 int genhasiax; 09230 int genregisteriax; 09231 const char *hasiax, *registeriax; 09232 09233 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09234 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09235 gen = ast_variable_browse(ucfg, "general"); 09236 cat = ast_category_browse(ucfg, NULL); 09237 while (cat) { 09238 if (strcasecmp(cat, "general")) { 09239 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09240 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09241 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09242 /* Start with general parameters, then specific parameters, user and peer */ 09243 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09244 if (user) { 09245 AST_LIST_LOCK(&users); 09246 AST_LIST_INSERT_HEAD(&users, user, entry); 09247 AST_LIST_UNLOCK(&users); 09248 } 09249 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09250 if (peer) { 09251 AST_LIST_LOCK(&peers); 09252 AST_LIST_INSERT_HEAD(&peers, peer, entry); 09253 AST_LIST_UNLOCK(&peers); 09254 if (ast_test_flag(peer, IAX_DYNAMIC)) 09255 reg_source_db(peer); 09256 } 09257 } 09258 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09259 char tmp[256]; 09260 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09261 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09262 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09263 if (!host) 09264 host = ast_variable_retrieve(ucfg, "general", "host"); 09265 if (!username) 09266 username = ast_variable_retrieve(ucfg, "general", "username"); 09267 if (!secret) 09268 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09269 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09270 if (!ast_strlen_zero(secret)) 09271 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09272 else 09273 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09274 iax2_register(tmp, 0); 09275 } 09276 } 09277 } 09278 cat = ast_category_browse(ucfg, cat); 09279 } 09280 ast_config_destroy(ucfg); 09281 } 09282 09283 cat = ast_category_browse(cfg, NULL); 09284 while(cat) { 09285 if (strcasecmp(cat, "general")) { 09286 utype = ast_variable_retrieve(cfg, cat, "type"); 09287 if (utype) { 09288 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 09289 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 09290 if (user) { 09291 AST_LIST_LOCK(&users); 09292 AST_LIST_INSERT_HEAD(&users, user, entry); 09293 AST_LIST_UNLOCK(&users); 09294 } 09295 } 09296 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 09297 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 09298 if (peer) { 09299 AST_LIST_LOCK(&peers); 09300 AST_LIST_INSERT_HEAD(&peers, peer, entry); 09301 AST_LIST_UNLOCK(&peers); 09302 if (ast_test_flag(peer, IAX_DYNAMIC)) 09303 reg_source_db(peer); 09304 } 09305 } else if (strcasecmp(utype, "user")) { 09306 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 09307 } 09308 } else 09309 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 09310 } 09311 cat = ast_category_browse(cfg, cat); 09312 } 09313 ast_config_destroy(cfg); 09314 set_timing(); 09315 return capability; 09316 }
static void set_timing | ( | void | ) | [static] |
Definition at line 8944 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
08945 { 08946 #ifdef HAVE_ZAPTEL 08947 int bs = trunkfreq * 8; 08948 if (timingfd > -1) { 08949 if ( 08950 #ifdef ZT_TIMERACK 08951 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08952 #endif 08953 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08954 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08955 } 08956 #endif 08957 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 712 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_transmit(), network_thread(), socket_read(), and update_jbsched().
00713 { 00714 ast_mutex_lock(lock); 00715 ast_cond_signal(cond); 00716 ast_mutex_unlock(lock); 00717 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6317 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_queue_control(), ast_queue_control_data(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), 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(), 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, free, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), 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_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, 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(), var, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
06318 { 06319 struct sockaddr_in sin; 06320 int res; 06321 int updatehistory=1; 06322 int new = NEW_PREVENT; 06323 void *ptr; 06324 int dcallno = 0; 06325 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06326 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06327 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06328 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06329 struct ast_iax2_meta_trunk_hdr *mth; 06330 struct ast_iax2_meta_trunk_entry *mte; 06331 struct ast_iax2_meta_trunk_mini *mtm; 06332 struct iax_frame *fr; 06333 struct iax_frame *cur; 06334 struct ast_frame f = { 0, }; 06335 struct ast_channel *c; 06336 struct iax2_dpcache *dp; 06337 struct iax2_peer *peer; 06338 struct iax2_trunk_peer *tpeer; 06339 struct timeval rxtrunktime; 06340 struct iax_ies ies; 06341 struct iax_ie_data ied0, ied1; 06342 int format; 06343 int fd; 06344 int exists; 06345 int minivid = 0; 06346 unsigned int ts; 06347 char empty[32]=""; /* Safety measure */ 06348 struct iax_frame *duped_fr; 06349 char host_pref_buf[128]; 06350 char caller_pref_buf[128]; 06351 struct ast_codec_pref pref; 06352 char *using_prefs = "mine"; 06353 06354 /* allocate an iax_frame with 4096 bytes of data buffer */ 06355 fr = alloca(sizeof(*fr) + 4096); 06356 fr->callno = 0; 06357 06358 /* Copy frequently used parameters to the stack */ 06359 res = thread->iores; 06360 fd = thread->iofd; 06361 memcpy(&sin, &thread->iosin, sizeof(sin)); 06362 06363 if (res < sizeof(*mh)) { 06364 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06365 return 1; 06366 } 06367 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06368 if (res < sizeof(*vh)) { 06369 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)); 06370 return 1; 06371 } 06372 06373 /* This is a video frame, get call number */ 06374 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06375 minivid = 1; 06376 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06377 unsigned char metatype; 06378 06379 if (res < sizeof(*meta)) { 06380 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)); 06381 return 1; 06382 } 06383 06384 /* This is a meta header */ 06385 switch(meta->metacmd) { 06386 case IAX_META_TRUNK: 06387 if (res < (sizeof(*meta) + sizeof(*mth))) { 06388 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06389 sizeof(*meta) + sizeof(*mth)); 06390 return 1; 06391 } 06392 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06393 ts = ntohl(mth->ts); 06394 metatype = meta->cmddata; 06395 res -= (sizeof(*meta) + sizeof(*mth)); 06396 ptr = mth->data; 06397 tpeer = find_tpeer(&sin, fd); 06398 if (!tpeer) { 06399 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)); 06400 return 1; 06401 } 06402 tpeer->trunkact = ast_tvnow(); 06403 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06404 tpeer->rxtrunktime = tpeer->trunkact; 06405 rxtrunktime = tpeer->rxtrunktime; 06406 ast_mutex_unlock(&tpeer->lock); 06407 while(res >= sizeof(*mte)) { 06408 /* Process channels */ 06409 unsigned short callno, trunked_ts, len; 06410 06411 if (metatype == IAX_META_TRUNK_MINI) { 06412 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06413 ptr += sizeof(*mtm); 06414 res -= sizeof(*mtm); 06415 len = ntohs(mtm->len); 06416 callno = ntohs(mtm->mini.callno); 06417 trunked_ts = ntohs(mtm->mini.ts); 06418 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06419 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06420 ptr += sizeof(*mte); 06421 res -= sizeof(*mte); 06422 len = ntohs(mte->len); 06423 callno = ntohs(mte->callno); 06424 trunked_ts = 0; 06425 } else { 06426 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06427 break; 06428 } 06429 /* Stop if we don't have enough data */ 06430 if (len > res) 06431 break; 06432 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06433 if (fr->callno) { 06434 ast_mutex_lock(&iaxsl[fr->callno]); 06435 /* If it's a valid call, deliver the contents. If not, we 06436 drop it, since we don't have a scallno to use for an INVAL */ 06437 /* Process as a mini frame */ 06438 memset(&f, 0, sizeof(f)); 06439 f.frametype = AST_FRAME_VOICE; 06440 if (iaxs[fr->callno]) { 06441 if (iaxs[fr->callno]->voiceformat > 0) { 06442 f.subclass = iaxs[fr->callno]->voiceformat; 06443 f.datalen = len; 06444 if (f.datalen >= 0) { 06445 if (f.datalen) 06446 f.data = ptr; 06447 if(trunked_ts) { 06448 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06449 } else 06450 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06451 /* Don't pass any packets until we're started */ 06452 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06453 /* Common things */ 06454 f.src = "IAX2"; 06455 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06456 f.samples = ast_codec_get_samples(&f); 06457 iax_frame_wrap(fr, &f); 06458 duped_fr = iaxfrdup2(fr); 06459 if (duped_fr) { 06460 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06461 } 06462 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06463 if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06464 iaxs[fr->callno]->last = fr->ts; 06465 #if 1 06466 if (option_debug && iaxdebug) 06467 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06468 #endif 06469 } 06470 } 06471 } else { 06472 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06473 } 06474 } else { 06475 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06476 iax2_vnak(fr->callno); 06477 } 06478 } 06479 ast_mutex_unlock(&iaxsl[fr->callno]); 06480 } 06481 ptr += len; 06482 res -= len; 06483 } 06484 06485 } 06486 return 1; 06487 } 06488 06489 #ifdef DEBUG_SUPPORT 06490 if (iaxdebug && (res >= sizeof(*fh))) 06491 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06492 #endif 06493 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06494 if (res < sizeof(*fh)) { 06495 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)); 06496 return 1; 06497 } 06498 06499 /* Get the destination call number */ 06500 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06501 /* Retrieve the type and subclass */ 06502 f.frametype = fh->type; 06503 if (f.frametype == AST_FRAME_VIDEO) { 06504 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06505 } else { 06506 f.subclass = uncompress_subclass(fh->csub); 06507 } 06508 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06509 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06510 (f.subclass == IAX_COMMAND_REGREL))) 06511 new = NEW_ALLOW; 06512 } else { 06513 /* Don't know anything about it yet */ 06514 f.frametype = AST_FRAME_NULL; 06515 f.subclass = 0; 06516 } 06517 06518 if (!fr->callno) 06519 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06520 06521 if (fr->callno > 0) 06522 ast_mutex_lock(&iaxsl[fr->callno]); 06523 06524 if (!fr->callno || !iaxs[fr->callno]) { 06525 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06526 frame, reply with an inval */ 06527 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06528 /* We can only raw hangup control frames */ 06529 if (((f.subclass != IAX_COMMAND_INVAL) && 06530 (f.subclass != IAX_COMMAND_TXCNT) && 06531 (f.subclass != IAX_COMMAND_TXACC) && 06532 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06533 (f.frametype != AST_FRAME_IAX)) 06534 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06535 fd); 06536 } 06537 if (fr->callno > 0) 06538 ast_mutex_unlock(&iaxsl[fr->callno]); 06539 return 1; 06540 } 06541 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06542 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06543 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06544 ast_mutex_unlock(&iaxsl[fr->callno]); 06545 return 1; 06546 } 06547 #ifdef DEBUG_SUPPORT 06548 else if (iaxdebug) 06549 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 06550 #endif 06551 } 06552 06553 /* count this frame */ 06554 iaxs[fr->callno]->frames_received++; 06555 06556 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 06557 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06558 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06559 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06560 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06561 if (option_debug && iaxdebug) 06562 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06563 /* Check if it's out of order (and not an ACK or INVAL) */ 06564 fr->oseqno = fh->oseqno; 06565 fr->iseqno = fh->iseqno; 06566 fr->ts = ntohl(fh->ts); 06567 #ifdef IAXTESTS 06568 if (test_resync) { 06569 if (option_debug) 06570 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 06571 fr->ts += test_resync; 06572 } 06573 #endif /* IAXTESTS */ 06574 #if 0 06575 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06576 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06577 (f.subclass == IAX_COMMAND_NEW || 06578 f.subclass == IAX_COMMAND_AUTHREQ || 06579 f.subclass == IAX_COMMAND_ACCEPT || 06580 f.subclass == IAX_COMMAND_REJECT)) ) ) 06581 #endif 06582 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06583 updatehistory = 0; 06584 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 06585 (iaxs[fr->callno]->iseqno || 06586 ((f.subclass != IAX_COMMAND_TXCNT) && 06587 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06588 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06589 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06590 (f.subclass != IAX_COMMAND_TXACC)) || 06591 (f.frametype != AST_FRAME_IAX))) { 06592 if ( 06593 ((f.subclass != IAX_COMMAND_ACK) && 06594 (f.subclass != IAX_COMMAND_INVAL) && 06595 (f.subclass != IAX_COMMAND_TXCNT) && 06596 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06597 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06598 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06599 (f.subclass != IAX_COMMAND_TXACC) && 06600 (f.subclass != IAX_COMMAND_VNAK)) || 06601 (f.frametype != AST_FRAME_IAX)) { 06602 /* If it's not an ACK packet, it's out of order. */ 06603 if (option_debug) 06604 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06605 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 06606 if (iaxs[fr->callno]->iseqno > fr->oseqno) { 06607 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06608 if ((f.frametype != AST_FRAME_IAX) || 06609 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06610 if (option_debug) 06611 ast_log(LOG_DEBUG, "Acking anyway\n"); 06612 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06613 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06614 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06615 } 06616 } else { 06617 /* Send a VNAK requesting retransmission */ 06618 iax2_vnak(fr->callno); 06619 } 06620 ast_mutex_unlock(&iaxsl[fr->callno]); 06621 return 1; 06622 } 06623 } else { 06624 /* Increment unless it's an ACK or VNAK */ 06625 if (((f.subclass != IAX_COMMAND_ACK) && 06626 (f.subclass != IAX_COMMAND_INVAL) && 06627 (f.subclass != IAX_COMMAND_TXCNT) && 06628 (f.subclass != IAX_COMMAND_TXACC) && 06629 (f.subclass != IAX_COMMAND_VNAK)) || 06630 (f.frametype != AST_FRAME_IAX)) 06631 iaxs[fr->callno]->iseqno++; 06632 } 06633 /* A full frame */ 06634 if (res < sizeof(*fh)) { 06635 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 06636 ast_mutex_unlock(&iaxsl[fr->callno]); 06637 return 1; 06638 } 06639 /* Ensure text frames are NULL-terminated */ 06640 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 06641 if (res < sizeof(thread->buf)) 06642 thread->buf[res++] = '\0'; 06643 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 06644 thread->buf[res - 1] = '\0'; 06645 } 06646 f.datalen = res - sizeof(*fh); 06647 06648 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06649 from the real peer, not the transfer peer */ 06650 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06651 ((f.subclass != IAX_COMMAND_INVAL) || 06652 (f.frametype != AST_FRAME_IAX))) { 06653 unsigned char x; 06654 /* XXX This code is not very efficient. Surely there is a better way which still 06655 properly handles boundary conditions? XXX */ 06656 /* First we have to qualify that the ACKed value is within our window */ 06657 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 06658 if (fr->iseqno == x) 06659 break; 06660 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 06661 /* The acknowledgement is within our window. Time to acknowledge everything 06662 that it says to */ 06663 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 06664 /* Ack the packet with the given timestamp */ 06665 if (option_debug && iaxdebug) 06666 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06667 AST_LIST_LOCK(&iaxq.queue); 06668 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06669 /* If it's our call, and our timestamp, mark -1 retries */ 06670 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 06671 cur->retries = -1; 06672 /* Destroy call if this is the end */ 06673 if (cur->final) { 06674 if (iaxdebug && option_debug) 06675 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno); 06676 iax2_destroy(fr->callno); 06677 } 06678 } 06679 } 06680 AST_LIST_UNLOCK(&iaxq.queue); 06681 } 06682 /* Note how much we've received acknowledgement for */ 06683 if (iaxs[fr->callno]) 06684 iaxs[fr->callno]->rseqno = fr->iseqno; 06685 else { 06686 /* Stop processing now */ 06687 ast_mutex_unlock(&iaxsl[fr->callno]); 06688 return 1; 06689 } 06690 } else 06691 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 06692 } 06693 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06694 ((f.frametype != AST_FRAME_IAX) || 06695 ((f.subclass != IAX_COMMAND_TXACC) && 06696 (f.subclass != IAX_COMMAND_TXCNT)))) { 06697 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06698 ast_mutex_unlock(&iaxsl[fr->callno]); 06699 return 1; 06700 } 06701 06702 if (f.datalen) { 06703 if (f.frametype == AST_FRAME_IAX) { 06704 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 06705 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 06706 ast_mutex_unlock(&iaxsl[fr->callno]); 06707 return 1; 06708 } 06709 f.data = NULL; 06710 } else 06711 f.data = thread->buf + sizeof(*fh); 06712 } else { 06713 if (f.frametype == AST_FRAME_IAX) 06714 f.data = NULL; 06715 else 06716 f.data = empty; 06717 memset(&ies, 0, sizeof(ies)); 06718 } 06719 if (f.frametype == AST_FRAME_VOICE) { 06720 if (f.subclass != iaxs[fr->callno]->voiceformat) { 06721 iaxs[fr->callno]->voiceformat = f.subclass; 06722 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06723 if (iaxs[fr->callno]->owner) { 06724 int orignative; 06725 retryowner: 06726 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 06727 ast_mutex_unlock(&iaxsl[fr->callno]); 06728 usleep(1); 06729 ast_mutex_lock(&iaxsl[fr->callno]); 06730 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 06731 } 06732 if (iaxs[fr->callno]) { 06733 if (iaxs[fr->callno]->owner) { 06734 orignative = iaxs[fr->callno]->owner->nativeformats; 06735 iaxs[fr->callno]->owner->nativeformats = f.subclass; 06736 if (iaxs[fr->callno]->owner->readformat) 06737 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 06738 iaxs[fr->callno]->owner->nativeformats = orignative; 06739 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 06740 } 06741 } else { 06742 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06743 /* Free remote variables (if any) */ 06744 if (ies.vars) 06745 ast_variables_destroy(ies.vars); 06746 ast_mutex_unlock(&iaxsl[fr->callno]); 06747 return 1; 06748 } 06749 } 06750 } 06751 } 06752 if (f.frametype == AST_FRAME_VIDEO) { 06753 if (f.subclass != iaxs[fr->callno]->videoformat) { 06754 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06755 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 06756 } 06757 } 06758 if (f.frametype == AST_FRAME_IAX) { 06759 if (iaxs[fr->callno]->initid > -1) { 06760 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06761 ast_sched_del(sched, iaxs[fr->callno]->initid); 06762 iaxs[fr->callno]->initid = -1; 06763 } 06764 /* Handle the IAX pseudo frame itself */ 06765 if (option_debug && iaxdebug) 06766 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06767 06768 /* Update last ts unless the frame's timestamp originated with us. */ 06769 if (iaxs[fr->callno]->last < fr->ts && 06770 f.subclass != IAX_COMMAND_ACK && 06771 f.subclass != IAX_COMMAND_PONG && 06772 f.subclass != IAX_COMMAND_LAGRP) { 06773 iaxs[fr->callno]->last = fr->ts; 06774 if (option_debug && iaxdebug) 06775 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06776 } 06777 06778 switch(f.subclass) { 06779 case IAX_COMMAND_ACK: 06780 /* Do nothing */ 06781 break; 06782 case IAX_COMMAND_QUELCH: 06783 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06784 /* Generate Manager Hold event, if necessary*/ 06785 if (iaxs[fr->callno]->owner) { 06786 manager_event(EVENT_FLAG_CALL, "Hold", 06787 "Channel: %s\r\n" 06788 "Uniqueid: %s\r\n", 06789 iaxs[fr->callno]->owner->name, 06790 iaxs[fr->callno]->owner->uniqueid); 06791 } 06792 06793 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 06794 if (ies.musiconhold) { 06795 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 06796 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 06797 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD, 06798 S_OR(mohsuggest, NULL), 06799 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 06800 } 06801 } 06802 } 06803 break; 06804 case IAX_COMMAND_UNQUELCH: 06805 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06806 /* Generate Manager Unhold event, if necessary*/ 06807 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 06808 manager_event(EVENT_FLAG_CALL, "Unhold", 06809 "Channel: %s\r\n" 06810 "Uniqueid: %s\r\n", 06811 iaxs[fr->callno]->owner->name, 06812 iaxs[fr->callno]->owner->uniqueid); 06813 } 06814 06815 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 06816 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) 06817 ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD); 06818 } 06819 break; 06820 case IAX_COMMAND_TXACC: 06821 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 06822 /* Ack the packet with the given timestamp */ 06823 AST_LIST_LOCK(&iaxq.queue); 06824 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06825 /* Cancel any outstanding txcnt's */ 06826 if ((fr->callno == cur->callno) && (cur->transfer)) 06827 cur->retries = -1; 06828 } 06829 AST_LIST_UNLOCK(&iaxq.queue); 06830 memset(&ied1, 0, sizeof(ied1)); 06831 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 06832 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06833 iaxs[fr->callno]->transferring = TRANSFER_READY; 06834 } 06835 break; 06836 case IAX_COMMAND_NEW: 06837 /* Ignore if it's already up */ 06838 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06839 break; 06840 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06841 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06842 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06843 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 06844 fr->callno = make_trunk(fr->callno, 1); 06845 } 06846 /* For security, always ack immediately */ 06847 if (delayreject) 06848 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06849 if (check_access(fr->callno, &sin, &ies)) { 06850 /* They're not allowed on */ 06851 auth_fail(fr->callno, IAX_COMMAND_REJECT); 06852 if (authdebug) 06853 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); 06854 break; 06855 } 06856 /* This might re-enter the IAX code and need the lock */ 06857 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 06858 ast_mutex_unlock(&iaxsl[fr->callno]); 06859 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 06860 ast_mutex_lock(&iaxsl[fr->callno]); 06861 } else 06862 exists = 0; 06863 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 06864 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 06865 memset(&ied0, 0, sizeof(ied0)); 06866 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06867 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06868 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06869 if (authdebug) 06870 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); 06871 } else { 06872 /* Select an appropriate format */ 06873 06874 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06875 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06876 using_prefs = "reqonly"; 06877 } else { 06878 using_prefs = "disabled"; 06879 } 06880 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 06881 memset(&pref, 0, sizeof(pref)); 06882 strcpy(caller_pref_buf, "disabled"); 06883 strcpy(host_pref_buf, "disabled"); 06884 } else { 06885 using_prefs = "mine"; 06886 /* If the information elements are in here... use them */ 06887 if (ies.codec_prefs) 06888 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 06889 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06890 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06891 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06892 pref = iaxs[fr->callno]->rprefs; 06893 using_prefs = "caller"; 06894 } else { 06895 pref = iaxs[fr->callno]->prefs; 06896 } 06897 } else 06898 pref = iaxs[fr->callno]->prefs; 06899 06900 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 06901 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06902 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06903 } 06904 if (!format) { 06905 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06906 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 06907 if (!format) { 06908 memset(&ied0, 0, sizeof(ied0)); 06909 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06910 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06911 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06912 if (authdebug) { 06913 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06914 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); 06915 else 06916 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); 06917 } 06918 } else { 06919 /* Pick one... */ 06920 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06921 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 06922 format = 0; 06923 } else { 06924 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06925 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06926 memset(&pref, 0, sizeof(pref)); 06927 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06928 strcpy(caller_pref_buf,"disabled"); 06929 strcpy(host_pref_buf,"disabled"); 06930 } else { 06931 using_prefs = "mine"; 06932 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06933 /* Do the opposite of what we tried above. */ 06934 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06935 pref = iaxs[fr->callno]->prefs; 06936 } else { 06937 pref = iaxs[fr->callno]->rprefs; 06938 using_prefs = "caller"; 06939 } 06940 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 06941 06942 } else /* if no codec_prefs IE do it the old way */ 06943 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06944 } 06945 } 06946 06947 if (!format) { 06948 memset(&ied0, 0, sizeof(ied0)); 06949 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06950 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06951 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06952 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06953 if (authdebug) 06954 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); 06955 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 06956 break; 06957 } 06958 } 06959 } 06960 if (format) { 06961 /* No authentication required, let them in */ 06962 memset(&ied1, 0, sizeof(ied1)); 06963 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 06964 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 06965 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 06966 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 06967 if (option_verbose > 2) 06968 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 06969 "%srequested format = %s,\n" 06970 "%srequested prefs = %s,\n" 06971 "%sactual format = %s,\n" 06972 "%shost prefs = %s,\n" 06973 "%spriority = %s\n", 06974 ast_inet_ntoa(sin.sin_addr), 06975 VERBOSE_PREFIX_4, 06976 ast_getformatname(iaxs[fr->callno]->peerformat), 06977 VERBOSE_PREFIX_4, 06978 caller_pref_buf, 06979 VERBOSE_PREFIX_4, 06980 ast_getformatname(format), 06981 VERBOSE_PREFIX_4, 06982 host_pref_buf, 06983 VERBOSE_PREFIX_4, 06984 using_prefs); 06985 06986 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 06987 iax2_destroy(fr->callno); 06988 else if (ies.vars) { 06989 struct ast_variable *var, *prev = NULL; 06990 char tmp[256]; 06991 for (var = ies.vars; var; var = var->next) { 06992 if (prev) 06993 free(prev); 06994 prev = var; 06995 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", var->name); 06996 pbx_builtin_setvar_helper(c, tmp, var->value); 06997 } 06998 ies.vars = NULL; 06999 } 07000 } else { 07001 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07002 /* If this is a TBD call, we're ready but now what... */ 07003 if (option_verbose > 2) 07004 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07005 } 07006 } 07007 } 07008 break; 07009 } 07010 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07011 merge_encryption(iaxs[fr->callno],ies.encmethods); 07012 else 07013 iaxs[fr->callno]->encmethods = 0; 07014 if (!authenticate_request(iaxs[fr->callno])) 07015 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07016 break; 07017 case IAX_COMMAND_DPREQ: 07018 /* Request status in the dialplan */ 07019 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07020 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07021 if (iaxcompat) { 07022 /* Spawn a thread for the lookup */ 07023 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07024 } else { 07025 /* Just look it up */ 07026 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07027 } 07028 } 07029 break; 07030 case IAX_COMMAND_HANGUP: 07031 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07032 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07033 /* Set hangup cause according to remote */ 07034 if (ies.causecode && iaxs[fr->callno]->owner) 07035 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07036 /* Send ack immediately, before we destroy */ 07037 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07038 iax2_destroy(fr->callno); 07039 break; 07040 case IAX_COMMAND_REJECT: 07041 /* Set hangup cause according to remote */ 07042 if (ies.causecode && iaxs[fr->callno]->owner) 07043 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07044 07045 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07046 if (iaxs[fr->callno]->owner && authdebug) 07047 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07048 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07049 ies.cause ? ies.cause : "<Unknown>"); 07050 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07051 fr->callno); 07052 } 07053 /* Send ack immediately, before we destroy */ 07054 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07055 fr->ts, NULL, 0, fr->iseqno); 07056 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07057 iaxs[fr->callno]->error = EPERM; 07058 iax2_destroy(fr->callno); 07059 break; 07060 case IAX_COMMAND_TRANSFER: 07061 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07062 /* Set BLINDTRANSFER channel variables */ 07063 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07064 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07065 if (!strcmp(ies.called_number, ast_parking_ext())) { 07066 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07067 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07068 } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) 07069 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07070 } else { 07071 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07072 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07073 ies.called_number, iaxs[fr->callno]->context); 07074 else 07075 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07076 ies.called_number, iaxs[fr->callno]->context); 07077 } 07078 } else 07079 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07080 break; 07081 case IAX_COMMAND_ACCEPT: 07082 /* Ignore if call is already up or needs authentication or is a TBD */ 07083 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07084 break; 07085 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07086 /* Send ack immediately, before we destroy */ 07087 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07088 iax2_destroy(fr->callno); 07089 break; 07090 } 07091 if (ies.format) { 07092 iaxs[fr->callno]->peerformat = ies.format; 07093 } else { 07094 if (iaxs[fr->callno]->owner) 07095 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07096 else 07097 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07098 } 07099 if (option_verbose > 2) 07100 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)); 07101 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07102 memset(&ied0, 0, sizeof(ied0)); 07103 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07104 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07105 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07106 if (authdebug) 07107 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); 07108 } else { 07109 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07110 if (iaxs[fr->callno]->owner) { 07111 /* Switch us to use a compatible format */ 07112 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07113 if (option_verbose > 2) 07114 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07115 retryowner2: 07116 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07117 ast_mutex_unlock(&iaxsl[fr->callno]); 07118 usleep(1); 07119 ast_mutex_lock(&iaxsl[fr->callno]); 07120 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07121 } 07122 07123 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07124 /* Setup read/write formats properly. */ 07125 if (iaxs[fr->callno]->owner->writeformat) 07126 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07127 if (iaxs[fr->callno]->owner->readformat) 07128 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07129 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07130 } 07131 } 07132 } 07133 if (iaxs[fr->callno]) { 07134 ast_mutex_lock(&dpcache_lock); 07135 dp = iaxs[fr->callno]->dpentries; 07136 while(dp) { 07137 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07138 iax2_dprequest(dp, fr->callno); 07139 } 07140 dp = dp->peer; 07141 } 07142 ast_mutex_unlock(&dpcache_lock); 07143 } 07144 break; 07145 case IAX_COMMAND_POKE: 07146 /* Send back a pong packet with the original timestamp */ 07147 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07148 break; 07149 case IAX_COMMAND_PING: 07150 { 07151 struct iax_ie_data pingied; 07152 construct_rr(iaxs[fr->callno], &pingied); 07153 /* Send back a pong packet with the original timestamp */ 07154 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07155 } 07156 break; 07157 case IAX_COMMAND_PONG: 07158 /* Calculate ping time */ 07159 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07160 /* save RR info */ 07161 save_rr(fr, &ies); 07162 07163 if (iaxs[fr->callno]->peerpoke) { 07164 peer = iaxs[fr->callno]->peerpoke; 07165 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07166 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07167 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07168 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07169 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07170 } 07171 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07172 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07173 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07174 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07175 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07176 } 07177 } 07178 peer->lastms = iaxs[fr->callno]->pingtime; 07179 if (peer->smoothing && (peer->lastms > -1)) 07180 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07181 else if (peer->smoothing && peer->lastms < 0) 07182 peer->historicms = (0 + peer->historicms) / 2; 07183 else 07184 peer->historicms = iaxs[fr->callno]->pingtime; 07185 07186 /* Remove scheduled iax2_poke_noanswer */ 07187 if (peer->pokeexpire > -1) 07188 ast_sched_del(sched, peer->pokeexpire); 07189 /* Schedule the next cycle */ 07190 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07191 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07192 else 07193 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07194 /* and finally send the ack */ 07195 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07196 /* And wrap up the qualify call */ 07197 iax2_destroy(fr->callno); 07198 peer->callno = 0; 07199 if (option_debug) 07200 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07201 } 07202 break; 07203 case IAX_COMMAND_LAGRQ: 07204 case IAX_COMMAND_LAGRP: 07205 f.src = "LAGRQ"; 07206 f.mallocd = 0; 07207 f.offset = 0; 07208 f.samples = 0; 07209 iax_frame_wrap(fr, &f); 07210 if(f.subclass == IAX_COMMAND_LAGRQ) { 07211 /* Received a LAGRQ - echo back a LAGRP */ 07212 fr->af.subclass = IAX_COMMAND_LAGRP; 07213 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07214 } else { 07215 /* Received LAGRP in response to our LAGRQ */ 07216 unsigned int ts; 07217 /* This is a reply we've been given, actually measure the difference */ 07218 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07219 iaxs[fr->callno]->lag = ts - fr->ts; 07220 if (option_debug && iaxdebug) 07221 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07222 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07223 } 07224 break; 07225 case IAX_COMMAND_AUTHREQ: 07226 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07227 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>"); 07228 break; 07229 } 07230 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07231 ast_log(LOG_WARNING, 07232 "I don't know how to authenticate %s to %s\n", 07233 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07234 } 07235 break; 07236 case IAX_COMMAND_AUTHREP: 07237 /* For security, always ack immediately */ 07238 if (delayreject) 07239 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07240 /* Ignore once we've started */ 07241 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07242 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>"); 07243 break; 07244 } 07245 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07246 if (authdebug) 07247 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); 07248 memset(&ied0, 0, sizeof(ied0)); 07249 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07250 break; 07251 } 07252 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07253 /* This might re-enter the IAX code and need the lock */ 07254 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07255 } else 07256 exists = 0; 07257 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07258 if (authdebug) 07259 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); 07260 memset(&ied0, 0, sizeof(ied0)); 07261 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07262 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07263 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07264 } else { 07265 /* Select an appropriate format */ 07266 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07267 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07268 using_prefs = "reqonly"; 07269 } else { 07270 using_prefs = "disabled"; 07271 } 07272 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07273 memset(&pref, 0, sizeof(pref)); 07274 strcpy(caller_pref_buf, "disabled"); 07275 strcpy(host_pref_buf, "disabled"); 07276 } else { 07277 using_prefs = "mine"; 07278 if (ies.codec_prefs) 07279 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07280 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07281 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07282 pref = iaxs[fr->callno]->rprefs; 07283 using_prefs = "caller"; 07284 } else { 07285 pref = iaxs[fr->callno]->prefs; 07286 } 07287 } else /* if no codec_prefs IE do it the old way */ 07288 pref = iaxs[fr->callno]->prefs; 07289 07290 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07291 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07292 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07293 } 07294 if (!format) { 07295 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07296 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); 07297 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07298 } 07299 if (!format) { 07300 if (authdebug) { 07301 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07302 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); 07303 else 07304 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); 07305 } 07306 memset(&ied0, 0, sizeof(ied0)); 07307 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07308 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07309 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07310 } else { 07311 /* Pick one... */ 07312 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07313 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07314 format = 0; 07315 } else { 07316 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07317 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07318 memset(&pref, 0, sizeof(pref)); 07319 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07320 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07321 strcpy(caller_pref_buf,"disabled"); 07322 strcpy(host_pref_buf,"disabled"); 07323 } else { 07324 using_prefs = "mine"; 07325 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07326 /* Do the opposite of what we tried above. */ 07327 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07328 pref = iaxs[fr->callno]->prefs; 07329 } else { 07330 pref = iaxs[fr->callno]->rprefs; 07331 using_prefs = "caller"; 07332 } 07333 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07334 } else /* if no codec_prefs IE do it the old way */ 07335 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07336 } 07337 } 07338 if (!format) { 07339 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07340 if (authdebug) { 07341 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07342 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); 07343 else 07344 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); 07345 } 07346 memset(&ied0, 0, sizeof(ied0)); 07347 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07348 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07349 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07350 } 07351 } 07352 } 07353 if (format) { 07354 /* Authentication received */ 07355 memset(&ied1, 0, sizeof(ied1)); 07356 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07357 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07358 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07359 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07360 if (option_verbose > 2) 07361 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07362 "%srequested format = %s,\n" 07363 "%srequested prefs = %s,\n" 07364 "%sactual format = %s,\n" 07365 "%shost prefs = %s,\n" 07366 "%spriority = %s\n", 07367 ast_inet_ntoa(sin.sin_addr), 07368 VERBOSE_PREFIX_4, 07369 ast_getformatname(iaxs[fr->callno]->peerformat), 07370 VERBOSE_PREFIX_4, 07371 caller_pref_buf, 07372 VERBOSE_PREFIX_4, 07373 ast_getformatname(format), 07374 VERBOSE_PREFIX_4, 07375 host_pref_buf, 07376 VERBOSE_PREFIX_4, 07377 using_prefs); 07378 07379 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07380 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07381 iax2_destroy(fr->callno); 07382 } else { 07383 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07384 /* If this is a TBD call, we're ready but now what... */ 07385 if (option_verbose > 2) 07386 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07387 } 07388 } 07389 } 07390 break; 07391 case IAX_COMMAND_DIAL: 07392 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07393 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07394 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07395 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07396 if (authdebug) 07397 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); 07398 memset(&ied0, 0, sizeof(ied0)); 07399 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07400 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07401 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07402 } else { 07403 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07404 if (option_verbose > 2) 07405 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 07406 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07407 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07408 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07409 iax2_destroy(fr->callno); 07410 } 07411 } 07412 break; 07413 case IAX_COMMAND_INVAL: 07414 iaxs[fr->callno]->error = ENOTCONN; 07415 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07416 iax2_destroy(fr->callno); 07417 if (option_debug) 07418 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07419 break; 07420 case IAX_COMMAND_VNAK: 07421 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07422 /* Force retransmission */ 07423 vnak_retransmit(fr->callno, fr->iseqno); 07424 break; 07425 case IAX_COMMAND_REGREQ: 07426 case IAX_COMMAND_REGREL: 07427 /* For security, always ack immediately */ 07428 if (delayreject) 07429 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07430 if (register_verify(fr->callno, &sin, &ies)) { 07431 /* Send delayed failure */ 07432 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07433 break; 07434 } 07435 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 07436 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 07437 if (f.subclass == IAX_COMMAND_REGREL) 07438 memset(&sin, 0, sizeof(sin)); 07439 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07440 ast_log(LOG_WARNING, "Registry error\n"); 07441 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07442 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07443 break; 07444 } 07445 registry_authrequest(iaxs[fr->callno]->peer, fr->callno); 07446 break; 07447 case IAX_COMMAND_REGACK: 07448 if (iax2_ack_registry(&ies, &sin, fr->callno)) 07449 ast_log(LOG_WARNING, "Registration failure\n"); 07450 /* Send ack immediately, before we destroy */ 07451 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07452 iax2_destroy(fr->callno); 07453 break; 07454 case IAX_COMMAND_REGREJ: 07455 if (iaxs[fr->callno]->reg) { 07456 if (authdebug) { 07457 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)); 07458 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>"); 07459 } 07460 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 07461 } 07462 /* Send ack immediately, before we destroy */ 07463 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07464 iax2_destroy(fr->callno); 07465 break; 07466 case IAX_COMMAND_REGAUTH: 07467 /* Authentication request */ 07468 if (registry_rerequest(&ies, fr->callno, &sin)) { 07469 memset(&ied0, 0, sizeof(ied0)); 07470 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07471 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07472 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07473 } 07474 break; 07475 case IAX_COMMAND_TXREJ: 07476 iaxs[fr->callno]->transferring = 0; 07477 if (option_verbose > 2) 07478 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07479 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 07480 if (iaxs[fr->callno]->bridgecallno) { 07481 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 07482 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 07483 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07484 } 07485 } 07486 break; 07487 case IAX_COMMAND_TXREADY: 07488 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 07489 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 07490 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 07491 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 07492 else 07493 iaxs[fr->callno]->transferring = TRANSFER_READY; 07494 if (option_verbose > 2) 07495 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07496 if (iaxs[fr->callno]->bridgecallno) { 07497 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 07498 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 07499 /* They're both ready, now release them. */ 07500 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 07501 if (option_verbose > 2) 07502 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07503 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07504 07505 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 07506 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 07507 07508 memset(&ied0, 0, sizeof(ied0)); 07509 memset(&ied1, 0, sizeof(ied1)); 07510 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07511 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07512 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 07513 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 07514 } else { 07515 if (option_verbose > 2) 07516 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07517 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07518 07519 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07520 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 07521 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 07522 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07523 07524 /* Stop doing lag & ping requests */ 07525 stop_stuff(fr->callno); 07526 stop_stuff(iaxs[fr->callno]->bridgecallno); 07527 07528 memset(&ied0, 0, sizeof(ied0)); 07529 memset(&ied1, 0, sizeof(ied1)); 07530 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07531 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07532 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07533 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07534 } 07535 07536 } 07537 } 07538 } 07539 break; 07540 case IAX_COMMAND_TXREQ: 07541 try_transfer(iaxs[fr->callno], &ies); 07542 break; 07543 case IAX_COMMAND_TXCNT: 07544 if (iaxs[fr->callno]->transferring) 07545 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07546 break; 07547 case IAX_COMMAND_TXREL: 07548 /* Send ack immediately, rather than waiting until we've changed addresses */ 07549 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07550 complete_transfer(fr->callno, &ies); 07551 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 07552 break; 07553 case IAX_COMMAND_TXMEDIA: 07554 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 07555 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 07556 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 07557 } 07558 break; 07559 case IAX_COMMAND_DPREP: 07560 complete_dpreply(iaxs[fr->callno], &ies); 07561 break; 07562 case IAX_COMMAND_UNSUPPORT: 07563 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07564 break; 07565 case IAX_COMMAND_FWDOWNL: 07566 /* Firmware download */ 07567 memset(&ied0, 0, sizeof(ied0)); 07568 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07569 if (res < 0) 07570 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07571 else if (res > 0) 07572 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07573 else 07574 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07575 break; 07576 default: 07577 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 07578 memset(&ied0, 0, sizeof(ied0)); 07579 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07580 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07581 } 07582 /* Free remote variables (if any) */ 07583 if (ies.vars) 07584 ast_variables_destroy(ies.vars); 07585 07586 /* Don't actually pass these frames along */ 07587 if ((f.subclass != IAX_COMMAND_ACK) && 07588 (f.subclass != IAX_COMMAND_TXCNT) && 07589 (f.subclass != IAX_COMMAND_TXACC) && 07590 (f.subclass != IAX_COMMAND_INVAL) && 07591 (f.subclass != IAX_COMMAND_VNAK)) { 07592 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07593 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07594 } 07595 ast_mutex_unlock(&iaxsl[fr->callno]); 07596 return 1; 07597 } 07598 /* Unless this is an ACK or INVAL frame, ack it */ 07599 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07600 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07601 } else if (minivid) { 07602 f.frametype = AST_FRAME_VIDEO; 07603 if (iaxs[fr->callno]->videoformat > 0) 07604 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07605 else { 07606 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07607 iax2_vnak(fr->callno); 07608 ast_mutex_unlock(&iaxsl[fr->callno]); 07609 return 1; 07610 } 07611 f.datalen = res - sizeof(*vh); 07612 if (f.datalen) 07613 f.data = thread->buf + sizeof(*vh); 07614 else 07615 f.data = NULL; 07616 #ifdef IAXTESTS 07617 if (test_resync) { 07618 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 07619 } else 07620 #endif /* IAXTESTS */ 07621 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 07622 } else { 07623 /* A mini frame */ 07624 f.frametype = AST_FRAME_VOICE; 07625 if (iaxs[fr->callno]->voiceformat > 0) 07626 f.subclass = iaxs[fr->callno]->voiceformat; 07627 else { 07628 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07629 iax2_vnak(fr->callno); 07630 ast_mutex_unlock(&iaxsl[fr->callno]); 07631 return 1; 07632 } 07633 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07634 if (f.datalen < 0) { 07635 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07636 ast_mutex_unlock(&iaxsl[fr->callno]); 07637 return 1; 07638 } 07639 if (f.datalen) 07640 f.data = thread->buf + sizeof(*mh); 07641 else 07642 f.data = NULL; 07643 #ifdef IAXTESTS 07644 if (test_resync) { 07645 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07646 } else 07647 #endif /* IAXTESTS */ 07648 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07649 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07650 } 07651 /* Don't pass any packets until we're started */ 07652 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07653 ast_mutex_unlock(&iaxsl[fr->callno]); 07654 return 1; 07655 } 07656 /* Common things */ 07657 f.src = "IAX2"; 07658 f.mallocd = 0; 07659 f.offset = 0; 07660 f.len = 0; 07661 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07662 f.samples = ast_codec_get_samples(&f); 07663 /* We need to byteswap incoming slinear samples from network byte order */ 07664 if (f.subclass == AST_FORMAT_SLINEAR) 07665 ast_frame_byteswap_be(&f); 07666 } else 07667 f.samples = 0; 07668 iax_frame_wrap(fr, &f); 07669 07670 /* If this is our most recent packet, use it as our basis for timestamping */ 07671 if (iaxs[fr->callno]->last < fr->ts) { 07672 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07673 fr->outoforder = 0; 07674 } else { 07675 if (option_debug && iaxdebug) 07676 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); 07677 fr->outoforder = -1; 07678 } 07679 duped_fr = iaxfrdup2(fr); 07680 if (duped_fr) { 07681 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07682 } 07683 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07684 iaxs[fr->callno]->last = fr->ts; 07685 #if 1 07686 if (option_debug && iaxdebug) 07687 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07688 #endif 07689 } 07690 07691 /* Always run again */ 07692 ast_mutex_unlock(&iaxsl[fr->callno]); 07693 return 1; 07694 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6251 of file chan_iax2.c.
References ast_log(), ast_random(), find_idle_thread(), handle_error(), IAX_IOSTATE_READY, insert_idle_thread(), len, LOG_NOTICE, LOG_WARNING, signal_condition(), t, and thread.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06252 { 06253 struct iax2_thread *thread; 06254 socklen_t len; 06255 time_t t; 06256 static time_t last_errtime=0; 06257 06258 thread = find_idle_thread(); 06259 if (thread) { 06260 len = sizeof(thread->iosin); 06261 thread->iofd = fd; 06262 thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len); 06263 if (thread->iores < 0) { 06264 if (errno != ECONNREFUSED && errno != EAGAIN) 06265 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06266 handle_error(); 06267 insert_idle_thread(thread); 06268 return 1; 06269 } 06270 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06271 insert_idle_thread(thread); 06272 return 1; 06273 } 06274 /* Mark as ready and send on its way */ 06275 thread->iostate = IAX_IOSTATE_READY; 06276 #ifdef DEBUG_SCHED_MULTITHREAD 06277 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06278 #endif 06279 signal_condition(&thread->lock, &thread->cond); 06280 } else { 06281 time(&t); 06282 if (t != last_errtime) 06283 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n"); 06284 last_errtime = t; 06285 usleep(1); 06286 } 06287 return 1; 06288 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6101 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().
06102 { 06103 pthread_t newthread; 06104 struct dpreq_data *dpr; 06105 pthread_attr_t attr; 06106 06107 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06108 return; 06109 06110 pthread_attr_init(&attr); 06111 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06112 06113 dpr->callno = callno; 06114 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06115 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06116 if (callerid) 06117 dpr->callerid = ast_strdup(callerid); 06118 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06119 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06120 } 06121 06122 pthread_attr_destroy(&attr); 06123 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8224 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().
08225 { 08226 pthread_attr_t attr; 08227 int threadcount = 0; 08228 int x; 08229 for (x = 0; x < iaxthreadcount; x++) { 08230 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08231 if (thread) { 08232 thread->type = IAX_TYPE_POOL; 08233 thread->threadnum = ++threadcount; 08234 ast_mutex_init(&thread->lock); 08235 ast_cond_init(&thread->cond, NULL); 08236 pthread_attr_init(&attr); 08237 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08238 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08239 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08240 free(thread); 08241 thread = NULL; 08242 } 08243 AST_LIST_LOCK(&idle_list); 08244 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08245 AST_LIST_UNLOCK(&idle_list); 08246 } 08247 } 08248 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08249 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08250 if (option_verbose > 1) 08251 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08252 return 0; 08253 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 5788 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
05789 { 05790 iax2_destroy_helper(iaxs[callno]); 05791 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 5976 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, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
05977 { 05978 char buf[1024]; 05979 int res; 05980 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 05981 int processed = 0; 05982 int totalcalls = 0; 05983 #ifdef ZT_TIMERACK 05984 int x = 1; 05985 #endif 05986 struct timeval now; 05987 if (iaxtrunkdebug) 05988 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 05989 gettimeofday(&now, NULL); 05990 if (events & AST_IO_PRI) { 05991 #ifdef ZT_TIMERACK 05992 /* Great, this is a timing interface, just call the ioctl */ 05993 if (ioctl(fd, ZT_TIMERACK, &x)) 05994 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 05995 res = 0; 05996 #endif 05997 } else { 05998 /* Read and ignore from the pseudo channel for timing */ 05999 res = read(fd, buf, sizeof(buf)); 06000 if (res < 1) { 06001 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06002 return 1; 06003 } 06004 } 06005 /* For each peer that supports trunking... */ 06006 ast_mutex_lock(&tpeerlock); 06007 tpeer = tpeers; 06008 while(tpeer) { 06009 processed++; 06010 res = 0; 06011 ast_mutex_lock(&tpeer->lock); 06012 /* We can drop a single tpeer per pass. That makes all this logic 06013 substantially easier */ 06014 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06015 /* Take it out of the list, but don't free it yet, because it 06016 could be in use */ 06017 if (prev) 06018 prev->next = tpeer->next; 06019 else 06020 tpeers = tpeer->next; 06021 drop = tpeer; 06022 } else { 06023 res = send_trunk(tpeer, &now); 06024 if (iaxtrunkdebug) 06025 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); 06026 } 06027 totalcalls += res; 06028 res = 0; 06029 ast_mutex_unlock(&tpeer->lock); 06030 prev = tpeer; 06031 tpeer = tpeer->next; 06032 } 06033 ast_mutex_unlock(&tpeerlock); 06034 if (drop) { 06035 ast_mutex_lock(&drop->lock); 06036 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06037 because by the time they could get tpeerlock, we've already grabbed it */ 06038 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06039 free(drop->trunkdata); 06040 ast_mutex_unlock(&drop->lock); 06041 ast_mutex_destroy(&drop->lock); 06042 free(drop); 06043 06044 } 06045 if (iaxtrunkdebug) 06046 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06047 iaxtrunkdebug =0; 06048 return 1; 06049 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1640 of file chan_iax2.c.
References ast_log(), f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01641 { 01642 int res; 01643 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01644 sizeof(*sin)); 01645 if (res < 0) { 01646 if (option_debug) 01647 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01648 handle_error(); 01649 } else 01650 res = 0; 01651 return res; 01652 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1339 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, 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().
01340 { 01341 struct stat stbuf; 01342 struct iax_firmware *cur; 01343 int ifd; 01344 int fd; 01345 int res; 01346 01347 struct ast_iax2_firmware_header *fwh, fwh2; 01348 struct MD5Context md5; 01349 unsigned char sum[16]; 01350 unsigned char buf[1024]; 01351 int len, chunk; 01352 char *s2; 01353 char *last; 01354 s2 = alloca(strlen(s) + 100); 01355 if (!s2) { 01356 ast_log(LOG_WARNING, "Alloca failed!\n"); 01357 return -1; 01358 } 01359 last = strrchr(s, '/'); 01360 if (last) 01361 last++; 01362 else 01363 last = s; 01364 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01365 res = stat(s, &stbuf); 01366 if (res < 0) { 01367 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01368 return -1; 01369 } 01370 /* Make sure it's not a directory */ 01371 if (S_ISDIR(stbuf.st_mode)) 01372 return -1; 01373 ifd = open(s, O_RDONLY); 01374 if (ifd < 0) { 01375 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01376 return -1; 01377 } 01378 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01379 if (fd < 0) { 01380 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01381 close(ifd); 01382 return -1; 01383 } 01384 /* Unlink our newly created file */ 01385 unlink(s2); 01386 01387 /* Now copy the firmware into it */ 01388 len = stbuf.st_size; 01389 while(len) { 01390 chunk = len; 01391 if (chunk > sizeof(buf)) 01392 chunk = sizeof(buf); 01393 res = read(ifd, buf, chunk); 01394 if (res != chunk) { 01395 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01396 close(ifd); 01397 close(fd); 01398 return -1; 01399 } 01400 res = write(fd, buf, chunk); 01401 if (res != chunk) { 01402 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01403 close(ifd); 01404 close(fd); 01405 return -1; 01406 } 01407 len -= chunk; 01408 } 01409 close(ifd); 01410 /* Return to the beginning */ 01411 lseek(fd, 0, SEEK_SET); 01412 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01413 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01414 close(fd); 01415 return -1; 01416 } 01417 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01418 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01419 close(fd); 01420 return -1; 01421 } 01422 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01423 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01424 close(fd); 01425 return -1; 01426 } 01427 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01428 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01429 close(fd); 01430 return -1; 01431 } 01432 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01433 if (fwh == (void *) -1) { 01434 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01435 close(fd); 01436 return -1; 01437 } 01438 MD5Init(&md5); 01439 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01440 MD5Final(sum, &md5); 01441 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01442 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01443 munmap(fwh, stbuf.st_size); 01444 close(fd); 01445 return -1; 01446 } 01447 cur = waresl.wares; 01448 while(cur) { 01449 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01450 /* Found a candidate */ 01451 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01452 /* The version we have on loaded is older, load this one instead */ 01453 break; 01454 /* This version is no newer than what we have. Don't worry about it. 01455 We'll consider it a proper load anyhow though */ 01456 munmap(fwh, stbuf.st_size); 01457 close(fd); 01458 return 0; 01459 } 01460 cur = cur->next; 01461 } 01462 if (!cur) { 01463 /* Allocate a new one and link it */ 01464 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01465 cur->fd = -1; 01466 cur->next = waresl.wares; 01467 waresl.wares = cur; 01468 } 01469 } 01470 if (cur) { 01471 if (cur->fwh) { 01472 munmap(cur->fwh, cur->mmaplen); 01473 } 01474 if (cur->fd > -1) 01475 close(cur->fd); 01476 cur->fwh = fwh; 01477 cur->fd = fd; 01478 cur->mmaplen = stbuf.st_size; 01479 cur->dead = 0; 01480 } 01481 return 0; 01482 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5251 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().
05252 { 05253 int newcall = 0; 05254 char newip[256]; 05255 struct iax_ie_data ied; 05256 struct sockaddr_in new; 05257 05258 05259 memset(&ied, 0, sizeof(ied)); 05260 if (ies->apparent_addr) 05261 bcopy(ies->apparent_addr, &new, sizeof(new)); 05262 if (ies->callno) 05263 newcall = ies->callno; 05264 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05265 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05266 return -1; 05267 } 05268 pvt->transfercallno = newcall; 05269 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05270 inet_aton(newip, &pvt->transfer.sin_addr); 05271 pvt->transfer.sin_family = AF_INET; 05272 pvt->transferring = TRANSFER_BEGIN; 05273 pvt->transferid = ies->transferid; 05274 if (ies->transferid) 05275 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05276 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05277 return 0; 05278 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 989 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
00990 { 00991 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 00992 if (csub & IAX_FLAG_SC_LOG) { 00993 /* special case for 'compressed' -1 */ 00994 if (csub == 0xff) 00995 return -1; 00996 else 00997 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 00998 } 00999 else 01000 return csub; 01001 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10137 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
10138 { 10139 ast_custom_function_unregister(&iaxpeer_function); 10140 ast_custom_function_unregister(&iaxvar_function); 10141 return __unload_module(); 10142 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3069 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03070 { 03071 ast_mutex_unlock(&iaxsl[callno1]); 03072 ast_mutex_unlock(&iaxsl[callno0]); 03073 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2182 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().
02183 { 02184 int x; 02185 02186 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02187 x = fr->ts - iaxs[fr->callno]->last; 02188 if (x < -50000) { 02189 /* Sudden big jump backwards in timestamp: 02190 What likely happened here is that miniframe timestamp has circled but we haven't 02191 gotten the update from the main packet. We'll just pretend that we did, and 02192 update the timestamp appropriately. */ 02193 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02194 if (option_debug && iaxdebug) 02195 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02196 } 02197 if (x > 50000) { 02198 /* Sudden apparent big jump forwards in timestamp: 02199 What's likely happened is this is an old miniframe belonging to the previous 02200 top-16-bit timestamp that has turned up out of order. 02201 Adjust the timestamp appropriately. */ 02202 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02203 if (option_debug && iaxdebug) 02204 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02205 } 02206 } 02207 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2211 of file chan_iax2.c.
References ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, sched, and signal_condition().
Referenced by __get_from_jb(), and schedule_delivery().
02212 { 02213 int when; 02214 02215 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02216 02217 when = jb_next(pvt->jb) - when; 02218 02219 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02220 02221 if(when <= 0) { 02222 /* XXX should really just empty until when > 0.. */ 02223 when = 1; 02224 } 02225 02226 pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02227 02228 /* Signal scheduler thread */ 02229 signal_condition(&sched_lock, &sched_cond); 02230 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1144 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno().
01145 { 01146 int max = 1; 01147 int x; 01148 /* XXX Prolly don't need locks here XXX */ 01149 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01150 if (iaxs[x]) 01151 max = x + 1; 01152 } 01153 maxnontrunkcall = max; 01154 if (option_debug && iaxdebug) 01155 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01156 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1130 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy().
01131 { 01132 int max = TRUNK_CALL_START; 01133 int x; 01134 /* XXX Prolly don't need locks here XXX */ 01135 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01136 if (iaxs[x]) 01137 max = x + 1; 01138 } 01139 maxtrunkcall = max; 01140 if (option_debug && iaxdebug) 01141 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01142 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1822 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().
01823 { 01824 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 01825 struct ast_iax2_full_hdr *fh = f->data; 01826 /* Mark this as a retransmission */ 01827 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 01828 /* Update iseqno */ 01829 f->iseqno = iaxs[f->callno]->iseqno; 01830 fh->iseqno = f->iseqno; 01831 return 0; 01832 }
static int update_registry | ( | const char * | name, | |
struct sockaddr_in * | sin, | |||
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5608 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_sched_add(), ast_sched_del(), ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_peer(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, 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, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05609 { 05610 /* Called from IAX thread only, with proper iaxsl lock */ 05611 struct iax_ie_data ied; 05612 struct iax2_peer *p; 05613 int msgcount; 05614 char data[80]; 05615 int version; 05616 05617 memset(&ied, 0, sizeof(ied)); 05618 05619 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05620 if (!(p = find_peer(name, 1))) { 05621 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05622 return -1; 05623 } 05624 05625 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 05626 if (sin->sin_addr.s_addr) { 05627 time_t nowtime; 05628 time(&nowtime); 05629 realtime_update_peer(name, sin, nowtime); 05630 } else { 05631 realtime_update_peer(name, sin, 0); 05632 } 05633 } 05634 if (inaddrcmp(&p->addr, sin)) { 05635 if (iax2_regfunk) 05636 iax2_regfunk(p->name, 1); 05637 /* Stash the IP address from which they registered */ 05638 memcpy(&p->addr, sin, sizeof(p->addr)); 05639 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05640 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05641 ast_db_put("IAX/Registry", p->name, data); 05642 if (option_verbose > 2) 05643 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05644 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 05645 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05646 register_peer_exten(p, 1); 05647 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05648 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05649 if (option_verbose > 2) 05650 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05651 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05652 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05653 register_peer_exten(p, 0); 05654 ast_db_del("IAX/Registry", p->name); 05655 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05656 } 05657 /* Update the host */ 05658 /* Verify that the host is really there */ 05659 iax2_poke_peer(p, callno); 05660 } 05661 05662 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 05663 if (!iaxs[callno]) 05664 return 0; 05665 05666 /* Store socket fd */ 05667 p->sockfd = fd; 05668 /* Setup the expiry */ 05669 if (p->expire > -1) 05670 ast_sched_del(sched, p->expire); 05671 /* treat an unspecified refresh interval as the minimum */ 05672 if (!refresh) 05673 refresh = min_reg_expire; 05674 if (refresh > max_reg_expire) { 05675 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05676 p->name, max_reg_expire, refresh); 05677 p->expiry = max_reg_expire; 05678 } else if (refresh < min_reg_expire) { 05679 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05680 p->name, min_reg_expire, refresh); 05681 p->expiry = min_reg_expire; 05682 } else { 05683 p->expiry = refresh; 05684 } 05685 if (p->expiry && sin->sin_addr.s_addr) 05686 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05687 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05688 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05689 if (sin->sin_addr.s_addr) { 05690 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05691 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05692 if (!ast_strlen_zero(p->mailbox)) { 05693 int new, old; 05694 ast_app_inboxcount(p->mailbox, &new, &old); 05695 if (new > 255) 05696 new = 255; 05697 if (old > 255) 05698 old = 255; 05699 msgcount = (old << 8) | new; 05700 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05701 } 05702 if (ast_test_flag(p, IAX_HASCALLERID)) { 05703 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05704 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05705 } 05706 } 05707 version = iax_check_version(devtype); 05708 if (version) 05709 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05710 if (ast_test_flag(p, IAX_TEMPONLY)) 05711 destroy_peer(p); 05712 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05713 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 5893 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().
05894 { 05895 struct iax_frame *f; 05896 05897 AST_LIST_LOCK(&iaxq.queue); 05898 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 05899 /* Send a copy immediately */ 05900 if ((f->callno == callno) && iaxs[f->callno] && 05901 (f->oseqno >= last)) { 05902 send_packet(f); 05903 } 05904 } 05905 AST_LIST_UNLOCK(&iaxq.queue); 05906 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), rpt_call(), sip_new(), skinny_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
int amaflags = 0 [static] |
Definition at line 221 of file chan_iax2.c.
Referenced by build_device(), build_gateway(), and pgsql_log().
int authdebug = 1 [static] |
int autokill = 0 [static] |
Definition at line 159 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 9941 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 9946 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 9956 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 9951 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 9936 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 143 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 9910 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 9902 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 9894 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 175 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 223 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
int global_rtautoclear = 120 [static] |
Definition at line 273 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 226 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(), realtime_peer(), realtime_user(), reload_config(), send_trunk(), sendmail(), set_config(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 204 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 224 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 177 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 9852 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 804 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 9918 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 451 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 164 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 450 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 767 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(), 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_frame(), 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_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 768 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_fail(), auth_reject(), auto_hangup(), cache_get_callno_locked(), delete_users(), destroy_peer(), 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_frame(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), send_command_locked(), socket_process(), and unlock_both().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 448 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 208 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
struct io_context* io [static] |
Definition at line 201 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 151 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 145 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
Definition at line 769 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 169 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 149 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 148 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 154 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 156 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 153 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 152 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 168 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 219 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 173 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 9914 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 9906 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 9898 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 174 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 7898 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 7900 of file chan_iax2.c.
int ping_time = 20 [static] |
Definition at line 150 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 139 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(), 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 9848 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 7899 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 146 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 155 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 202 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 231 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 9840 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 9868 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 9886 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 9872 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 9844 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 9880 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 9856 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 9890 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 9836 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 9876 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 9863 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 141 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 210 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 171 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 166 of file chan_iax2.c.
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 157 of file chan_iax2.c.
struct 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().