#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.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 "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_peer_list |
The peer list: Peers and Friends ---. More... | |
struct | ast_user_list |
The user list: Users and friends ---. More... | |
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_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#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 %-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 %-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 | 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 | NEWJB |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#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) } |
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_MESSAGEDETAIL = (1 << 8), 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_MAXAUTHREQ = (1 << 23) } |
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 } |
Functions | |
static int | __do_deliver (void *data) |
static int | __iax2_show_peers (int manager, int fd, int argc, char *argv[]) |
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 int | __unload_module (void) |
static int | apply_context (struct iax2_context *con, char *context) |
static int | ast_cli_netstats (int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static int | attempt_transmit (void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (void *nothing) |
static int | authenticate (char *challenge, char *secret, 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, char *override, 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 *nothing) |
static int | auto_hangup (void *nothing) |
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, int temponly) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, int temponly) |
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) |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (char *line, 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) |
char * | description () |
Provides a description of the module. | |
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, char *context, char *callednum, 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_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 char * | 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) |
static unsigned int | iax2_datetime (char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_nolock (int callno) |
static int | iax2_devicestate (void *data) |
static int | iax2_digit (struct ast_channel *c, char digit) |
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, int newstack, const char *data) |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
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) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
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 int | iax2_predestroy_nolock (int callno) |
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 (char *line, 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_set_jitter (int fd, int argc, char *argv[]) |
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[]) |
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_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1) |
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 | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
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, struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, 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) |
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) |
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 (char *name, int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
static void | reload_firmware (void) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
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) |
static void | set_timing (void) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid) |
static int | start_network_thread (void) |
static int | 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) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
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 (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
int | usecount () |
Provides a usecount. | |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static const char | channeltype [] = "IAX2" |
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 const char | desc [] = "Inter Asterisk eXchange (Ver 2)" |
static struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static struct ast_cli_entry | iax2_cli [] |
static int | iax2_dropcount = DEFAULT_DROP |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(* | iax2_regfunk )(char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static const struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
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 | iaxtrunkdebug = 0 |
static struct io_context * | io |
static char | jitter_usage [] |
static int | jittershrinkrate = 2 |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static struct timeval | lastused [IAX_MAX_CALLS] |
static int | max_jitter_buffer = MAX_JITTER_BUFFER |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 0 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_jitter_buffer = MIN_JITTER_BUFFER |
static int | min_reg_expire |
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 char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ast_peer_list | peerl |
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 struct iax2_registry * | registrations |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
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_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static int | tos = 0 |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static int | usecnt |
static struct ast_user_list | userl |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
|
Extension can exist Definition at line 634 of file chan_iax2.c. Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache(). |
|
Extension exists Definition at line 630 of file chan_iax2.c. Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache(). |
|
Matchmore Definition at line 644 of file chan_iax2.c. Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache(). |
|
Extension is nonexistent Definition at line 632 of file chan_iax2.c. Referenced by complete_dpreply(), and iax2_show_cache(). |
|
Waiting to hear back response Definition at line 636 of file chan_iax2.c. Referenced by complete_dpreply(), find_cache(), and iax2_show_cache(). |
|
Timed out Definition at line 638 of file chan_iax2.c. Referenced by find_cache(), and iax2_show_cache(). |
|
Request transmitted Definition at line 640 of file chan_iax2.c. Referenced by iax2_dprequest(), iax2_show_cache(), and socket_read(). |
|
Timeout Definition at line 642 of file chan_iax2.c. Referenced by complete_dpreply(), and iax2_show_cache(). |
|
Definition at line 123 of file chan_iax2.c. Referenced by ast_iax2_new(), and iax2_call(). |
|
Definition at line 132 of file chan_iax2.c. |
|
Definition at line 127 of file chan_iax2.c. |
|
Definition at line 204 of file chan_iax2.c. Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer(). |
|
Definition at line 203 of file chan_iax2.c. Referenced by build_peer(), and handle_response_peerpoke(). |
|
Definition at line 202 of file chan_iax2.c. |
|
Definition at line 125 of file chan_iax2.c. Referenced by complete_transfer(), and find_callno(). |
|
40ms, uncompressed linear * 10 channels Definition at line 421 of file chan_iax2.c. Referenced by iax2_trunk_queue(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Referenced by iax2_show_channels(). |
|
Definition at line 137 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 349 of file chan_iax2.c. Referenced by iax2_trunk_queue(). |
|
Definition at line 187 of file chan_iax2.c. Referenced by cache_get_callno_locked(), and set_config(). |
|
Value: Definition at line 194 of file chan_iax2.c. Referenced by set_config(). |
|
Value: Definition at line 198 of file chan_iax2.c. |
|
Value: (IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW) Definition at line 189 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 106 of file chan_iax2.c. |
|
Definition at line 418 of file chan_iax2.c. |
|
Definition at line 416 of file chan_iax2.c. Referenced by attempt_transmit(), and iax2_send(). |
|
maximum difference between actual and predicted ts for sending Definition at line 424 of file chan_iax2.c. |
|
40ms, uncompressed linear * 200 channels Definition at line 422 of file chan_iax2.c. Referenced by iax2_trunk_queue(), and timing_read(). |
|
Definition at line 126 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 419 of file chan_iax2.c. |
|
Definition at line 415 of file chan_iax2.c. Referenced by iax2_send(). |
|
Definition at line 134 of file chan_iax2.c. Referenced by find_callno(), and make_trunk(). |
|
Definition at line 949 of file chan_iax2.c. Referenced by find_callno(), and socket_read(). |
|
Definition at line 950 of file chan_iax2.c. Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request(). |
|
Definition at line 948 of file chan_iax2.c. Referenced by socket_read(). |
|
Definition at line 99 of file chan_iax2.c. |
|
Definition at line 122 of file chan_iax2.c. Referenced by auto_congest(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write(). |
|
Definition at line 130 of file chan_iax2.c. Referenced by find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk(). |
|
Definition at line 427 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 234 of file chan_iax2.c. 00234 { 00235 IAX_STATE_STARTED = (1 << 0), 00236 IAX_STATE_AUTHENTICATED = (1 << 1), 00237 IAX_STATE_TBD = (1 << 2) 00238 } iax2_state;
|
|
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 IAX_MESSAGEDETAIL = (1 << 8), /*!< Show exact numbers */ 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_MAXAUTHREQ = (1 << 23) /*!< Maximum outstanding AUTHREQ restriction is in place */ 00270 } iax2_flags;
|
|
Definition at line 380 of file chan_iax2.c. 00380 { 00381 REG_STATE_UNREGISTERED = 0, 00382 REG_STATE_REGSENT, 00383 REG_STATE_AUTHSENT, 00384 REG_STATE_REGISTERED, 00385 REG_STATE_REJECTED, 00386 REG_STATE_TIMEOUT, 00387 REG_STATE_NOAUTH 00388 };
|
|
Definition at line 390 of file chan_iax2.c. 00390 { 00391 TRANSFER_NONE = 0, 00392 TRANSFER_BEGIN, 00393 TRANSFER_READY, 00394 TRANSFER_RELEASED, 00395 TRANSFER_PASSTHROUGH 00396 };
|
|
Definition at line 1415 of file chan_iax2.c. References iax_frame::af, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, and iax_frame::retrans. Referenced by get_from_jb(), and schedule_delivery(). 01416 { 01417 /* Just deliver the packet by using queueing. This is called by 01418 the IAX thread with the iaxsl lock held. */ 01419 struct iax_frame *fr = data; 01420 fr->retrans = -1; 01421 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01422 iax2_queue_frame(fr->callno, &fr->af); 01423 /* Free our iax frame */ 01424 iax2_frame_free(fr); 01425 /* And don't run again */ 01426 return 0; 01427 }
|
|
Definition at line 4197 of file chan_iax2.c. References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, ast_peer_list::lock, iax2_peer::mask, iax2_peer::name, name, iax2_peer::next, peer_status(), peerl, ast_peer_list::peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::username. Referenced by iax2_show_peers(), and manager_iax2_show_peers(). 04198 { 04199 regex_t regexbuf; 04200 int havepattern = 0; 04201 int total_peers = 0; 04202 int online_peers = 0; 04203 int offline_peers = 0; 04204 int unmonitored_peers = 0; 04205 04206 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04207 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04208 04209 struct iax2_peer *peer; 04210 char name[256]; 04211 char iabuf[INET_ADDRSTRLEN]; 04212 int registeredonly=0; 04213 char *term = manager ? "\r\n" : "\n"; 04214 04215 switch (argc) { 04216 case 6: 04217 if (!strcasecmp(argv[3], "registered")) 04218 registeredonly = 1; 04219 else 04220 return RESULT_SHOWUSAGE; 04221 if (!strcasecmp(argv[4], "like")) { 04222 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04223 return RESULT_SHOWUSAGE; 04224 havepattern = 1; 04225 } else 04226 return RESULT_SHOWUSAGE; 04227 break; 04228 case 5: 04229 if (!strcasecmp(argv[3], "like")) { 04230 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04231 return RESULT_SHOWUSAGE; 04232 havepattern = 1; 04233 } else 04234 return RESULT_SHOWUSAGE; 04235 break; 04236 case 4: 04237 if (!strcasecmp(argv[3], "registered")) 04238 registeredonly = 1; 04239 else 04240 return RESULT_SHOWUSAGE; 04241 break; 04242 case 3: 04243 break; 04244 default: 04245 return RESULT_SHOWUSAGE; 04246 } 04247 04248 ast_mutex_lock(&peerl.lock); 04249 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04250 for (peer = peerl.peers;peer;peer = peer->next) { 04251 char nm[20]; 04252 char status[20]; 04253 char srch[2000]; 04254 int retstatus; 04255 04256 if (registeredonly && !peer->addr.sin_addr.s_addr) 04257 continue; 04258 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04259 continue; 04260 04261 if (!ast_strlen_zero(peer->username)) 04262 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04263 else 04264 ast_copy_string(name, peer->name, sizeof(name)); 04265 04266 retstatus = peer_status(peer, status, sizeof(status)); 04267 if (retstatus > 0) 04268 online_peers++; 04269 else if (!retstatus) 04270 offline_peers++; 04271 else 04272 unmonitored_peers++; 04273 04274 ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)); 04275 04276 snprintf(srch, sizeof(srch), FORMAT, name, 04277 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04278 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04279 nm, 04280 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04281 peer->encmethods ? "(E)" : " ", status, term); 04282 04283 ast_cli(fd, FORMAT, name, 04284 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04285 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04286 nm, 04287 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04288 peer->encmethods ? "(E)" : " ", status, term); 04289 total_peers++; 04290 } 04291 ast_mutex_unlock(&peerl.lock); 04292 04293 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04294 04295 if (havepattern) 04296 regfree(®exbuf); 04297 04298 return RESULT_SUCCESS; 04299 #undef FORMAT 04300 #undef FORMAT2 04301 }
|
|
Definition at line 4663 of file chan_iax2.c. References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass. Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer(). 04665 { 04666 struct ast_frame f; 04667 f.frametype = type; 04668 f.subclass = command; 04669 f.datalen = datalen; 04670 f.samples = 0; 04671 f.mallocd = 0; 04672 f.offset = 0; 04673 f.src = (char *)__FUNCTION__; 04674 f.data = (char *)data; 04675 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04676 }
|
|
|
Definition at line 4716 of file chan_iax2.c. References iax2_context::context, and iax2_context::next. Referenced by check_access(). 04717 { 04718 while(con) { 04719 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04720 return -1; 04721 con = con->next; 04722 } 04723 return 0; 04724 }
|
|
Definition at line 4483 of file chan_iax2.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, chan_iax2_pvt::frames_dropped, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr. Referenced by iax2_show_netstats(), and manager_iax2_show_netstats(). 04484 { 04485 int x; 04486 int numchans = 0; 04487 for (x=0;x<IAX_MAX_CALLS;x++) { 04488 ast_mutex_lock(&iaxsl[x]); 04489 if (iaxs[x]) { 04490 #ifdef BRIDGE_OPTIMIZATION 04491 if (iaxs[x]->bridgecallno) { 04492 if (limit_fmt) 04493 ast_cli(fd, "%-25.25s <NATIVE BRIDGED>", 04494 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04495 else 04496 ast_cli(fd, "%s <NATIVE BRIDGED>", 04497 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04498 } else 04499 #endif 04500 { 04501 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04502 char *fmt; 04503 #ifdef NEWJB 04504 jb_info jbinfo; 04505 04506 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04507 jb_getinfo(iaxs[x]->jb, &jbinfo); 04508 localjitter = jbinfo.jitter; 04509 localdelay = jbinfo.current - jbinfo.min; 04510 locallost = jbinfo.frames_lost; 04511 locallosspct = jbinfo.losspct/1000; 04512 localdropped = jbinfo.frames_dropped; 04513 localooo = jbinfo.frames_ooo; 04514 } else { 04515 localjitter = -1; 04516 localdelay = 0; 04517 locallost = -1; 04518 locallosspct = -1; 04519 localdropped = 0; 04520 localooo = -1; 04521 } 04522 #else 04523 localjitter = iaxs[x]->jitter; 04524 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) 04525 { 04526 localdelay = jitterbufsize(iaxs[x]); 04527 localdropped = iaxs[x]->frames_dropped; 04528 } else { 04529 localdelay = localdropped = 0; 04530 } 04531 locallost = locallosspct = localooo = -1; 04532 #endif 04533 if (limit_fmt) 04534 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04535 else 04536 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04537 ast_cli(fd, fmt, 04538 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04539 iaxs[x]->pingtime, 04540 localjitter, 04541 localdelay, 04542 locallost, 04543 locallosspct, 04544 localdropped, 04545 localooo, 04546 iaxs[x]->frames_received/1000, 04547 iaxs[x]->remote_rr.jitter, 04548 iaxs[x]->remote_rr.delay, 04549 iaxs[x]->remote_rr.losscnt, 04550 iaxs[x]->remote_rr.losspct, 04551 iaxs[x]->remote_rr.dropped, 04552 iaxs[x]->remote_rr.ooo, 04553 iaxs[x]->remote_rr.packets/1000 04554 ); 04555 } 04556 numchans++; 04557 } 04558 ast_mutex_unlock(&iaxsl[x]); 04559 } 04560 return numchans; 04561 }
|
|
|
|
|
|
|
|
|
Definition at line 1727 of file chan_iax2.c. References iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax_frame::callno, ast_iax2_queue::count, chan_iax2_pvt::error, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, ast_iax2_queue::head, iax2_destroy_nolock(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxsl, ast_iax2_queue::lock, LOG_WARNING, max_retries, MAX_RETRY_TIME, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, REG_STATE_TIMEOUT, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, and update_packet(). Referenced by network_thread(). 01728 { 01729 /* Attempt to transmit the frame to the remote peer... 01730 Called without iaxsl held. */ 01731 struct iax_frame *f = data; 01732 int freeme=0; 01733 int callno = f->callno; 01734 char iabuf[INET_ADDRSTRLEN]; 01735 /* Make sure this call is still active */ 01736 if (callno) 01737 ast_mutex_lock(&iaxsl[callno]); 01738 if ((f->callno) && iaxs[f->callno]) { 01739 if ((f->retries < 0) /* Already ACK'd */ || 01740 (f->retries >= max_retries) /* Too many attempts */) { 01741 /* Record an error if we've transmitted too many times */ 01742 if (f->retries >= max_retries) { 01743 if (f->transfer) { 01744 /* Transfer timeout */ 01745 send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 01746 } else if (f->final) { 01747 if (f->final) 01748 iax2_destroy_nolock(f->callno); 01749 } else { 01750 if (iaxs[f->callno]->owner) 01751 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); 01752 iaxs[f->callno]->error = ETIMEDOUT; 01753 if (iaxs[f->callno]->owner) { 01754 struct ast_frame fr = { 0, }; 01755 /* Hangup the fd */ 01756 fr.frametype = AST_FRAME_CONTROL; 01757 fr.subclass = AST_CONTROL_HANGUP; 01758 iax2_queue_frame(f->callno, &fr); 01759 /* Remember, owner could disappear */ 01760 if (iaxs[f->callno]->owner) 01761 iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01762 } else { 01763 if (iaxs[f->callno]->reg) { 01764 memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us)); 01765 iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT; 01766 iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 01767 } 01768 iax2_destroy_nolock(f->callno); 01769 } 01770 } 01771 01772 } 01773 freeme++; 01774 } else { 01775 /* Update it if it needs it */ 01776 update_packet(f); 01777 /* Attempt transmission */ 01778 send_packet(f); 01779 f->retries++; 01780 /* Try again later after 10 times as long */ 01781 f->retrytime *= 10; 01782 if (f->retrytime > MAX_RETRY_TIME) 01783 f->retrytime = MAX_RETRY_TIME; 01784 /* Transfer messages max out at one second */ 01785 if (f->transfer && (f->retrytime > 1000)) 01786 f->retrytime = 1000; 01787 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 01788 } 01789 } else { 01790 /* Make sure it gets freed */ 01791 f->retries = -1; 01792 freeme++; 01793 } 01794 if (callno) 01795 ast_mutex_unlock(&iaxsl[callno]); 01796 /* Do not try again */ 01797 if (freeme) { 01798 /* Don't attempt delivery, just remove it from the queue */ 01799 ast_mutex_lock(&iaxq.lock); 01800 if (f->prev) 01801 f->prev->next = f->next; 01802 else 01803 iaxq.head = f->next; 01804 if (f->next) 01805 f->next->prev = f->prev; 01806 else 01807 iaxq.tail = f->prev; 01808 iaxq.count--; 01809 ast_mutex_unlock(&iaxq.lock); 01810 f->retrans = -1; 01811 /* Free the IAX frame */ 01812 iax2_frame_free(f); 01813 } 01814 return 0; 01815 }
|
|
Definition at line 5926 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, delayreject, and iaxsl. Referenced by socket_read(). 05927 { 05928 /* Schedule sending the authentication failure in one second, to prevent 05929 guessing */ 05930 ast_mutex_lock(&iaxsl[callno]); 05931 iaxs[callno]->authfail = failcode; 05932 if (delayreject) { 05933 if (iaxs[callno]->authid > -1) 05934 ast_sched_del(sched, iaxs[callno]->authid); 05935 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 05936 } else 05937 auth_reject((void *)(long)callno); 05938 ast_mutex_unlock(&iaxsl[callno]); 05939 return 0; 05940 }
|
|
Definition at line 5904 of file chan_iax2.c. References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxsl, and send_command_final(). Referenced by auth_fail(). 05905 { 05906 /* Called from IAX thread only, without iaxs lock */ 05907 int callno = (int)(long)(nothing); 05908 struct iax_ie_data ied; 05909 ast_mutex_lock(&iaxsl[callno]); 05910 if (iaxs[callno]) { 05911 iaxs[callno]->authid = -1; 05912 memset(&ied, 0, sizeof(ied)); 05913 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 05914 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 05915 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 05916 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 05917 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 05918 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 05919 } 05920 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 05921 } 05922 ast_mutex_unlock(&iaxsl[callno]); 05923 return 0; 05924 }
|
|
Definition at line 5234 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, MD5Final(), MD5Init(), and MD5Update(). 05235 { 05236 int res = -1; 05237 int x; 05238 char iabuf[INET_ADDRSTRLEN]; 05239 if (!ast_strlen_zero(keyn)) { 05240 if (!(authmethods & IAX_AUTH_RSA)) { 05241 if (ast_strlen_zero(secret)) 05242 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05243 } else if (ast_strlen_zero(challenge)) { 05244 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05245 } else { 05246 char sig[256]; 05247 struct ast_key *key; 05248 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05249 if (!key) { 05250 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05251 } else { 05252 if (ast_sign(key, challenge, sig)) { 05253 ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n"); 05254 res = -1; 05255 } else { 05256 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05257 res = 0; 05258 } 05259 } 05260 } 05261 } 05262 /* Fall back */ 05263 if (res && !ast_strlen_zero(secret)) { 05264 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05265 struct MD5Context md5; 05266 unsigned char digest[16]; 05267 char digres[128]; 05268 MD5Init(&md5); 05269 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05270 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05271 MD5Final(digest, &md5); 05272 /* If they support md5, authenticate with it. */ 05273 for (x=0;x<16;x++) 05274 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05275 if (ecx && dcx) 05276 build_enc_keys(digest, ecx, dcx); 05277 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05278 res = 0; 05279 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05280 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05281 res = 0; 05282 } else 05283 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), authmethods); 05284 } 05285 return res; 05286 }
|
|
Definition at line 5288 of file chan_iax2.c. References iax2_peer::addr, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, authenticate(), iax_ies::authmethods, iax2_peer::authmethods, chan_iax2_pvt::challenge, iax_ies::challenge, destroy_peer(), iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::next, iax2_peer::outkey, peerl, ast_peer_list::peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, chan_iax2_pvt::username, and iax_ies::username. Referenced by socket_read(). 05289 { 05290 struct iax2_peer *peer; 05291 /* Start pessimistic */ 05292 int res = -1; 05293 int authmethods = 0; 05294 struct iax_ie_data ied; 05295 05296 memset(&ied, 0, sizeof(ied)); 05297 05298 if (ies->username) 05299 ast_copy_string(p->username, ies->username, sizeof(p->username)); 05300 if (ies->challenge) 05301 ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge)); 05302 if (ies->authmethods) 05303 authmethods = ies->authmethods; 05304 if (authmethods & IAX_AUTH_MD5) 05305 merge_encryption(p, ies->encmethods); 05306 else 05307 p->encmethods = 0; 05308 05309 /* Check for override RSA authentication first */ 05310 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05311 /* Normal password authentication */ 05312 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05313 } else { 05314 ast_mutex_lock(&peerl.lock); 05315 peer = peerl.peers; 05316 while(peer) { 05317 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05318 /* No peer specified at our end, or this is the peer */ 05319 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05320 /* No username specified in peer rule, or this is the right username */ 05321 && (!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))) 05322 /* No specified host, or this is our host */ 05323 ) { 05324 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05325 if (!res) 05326 break; 05327 } 05328 peer = peer->next; 05329 } 05330 ast_mutex_unlock(&peerl.lock); 05331 if (!peer) { 05332 /* We checked our list and didn't find one. It's unlikely, but possible, 05333 that we're trying to authenticate *to* a realtime peer */ 05334 if ((peer = realtime_peer(p->peer, NULL))) { 05335 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05336 if (ast_test_flag(peer, IAX_TEMPONLY)) 05337 destroy_peer(peer); 05338 } 05339 } 05340 } 05341 if (ies->encmethods) 05342 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05343 if (!res) 05344 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05345 return res; 05346 }
|
|
Definition at line 4958 of file chan_iax2.c. References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, iax2_user::curauthreq, 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, ast_user_list::lock, iax2_user::maxauthreq, iax2_user::name, iax2_user::next, send_command(), send_command_final(), user, userl, and ast_user_list::users. Referenced by socket_read(). 04959 { 04960 struct iax2_user *user = NULL; 04961 struct iax_ie_data ied; 04962 int res = -1, authreq_restrict = 0; 04963 04964 memset(&ied, 0, sizeof(ied)); 04965 04966 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 04967 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04968 ast_mutex_lock(&userl.lock); 04969 user = userl.users; 04970 while (user) { 04971 if (!strcmp(user->name, p->username)) { 04972 if (user->curauthreq == user->maxauthreq) 04973 authreq_restrict = 1; 04974 else 04975 user->curauthreq++; 04976 break; 04977 } 04978 user = user->next; 04979 } 04980 ast_mutex_unlock(&userl.lock); 04981 } 04982 04983 /* If the AUTHREQ limit test failed, send back an error */ 04984 if (authreq_restrict) { 04985 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 04986 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 04987 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 04988 return 0; 04989 } 04990 04991 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 04992 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 04993 snprintf(p->challenge, sizeof(p->challenge), "%d", rand()); 04994 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 04995 } 04996 if (p->encmethods) 04997 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 04998 04999 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05000 05001 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05002 05003 if (p->encmethods) 05004 ast_set_flag(p, IAX_ENCRYPTED); 05005 05006 return res; 05007 }
|
|
Definition at line 5009 of file chan_iax2.c. References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, key(), ast_user_list::lock, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, iax2_user::next, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, userl, chan_iax2_pvt::username, and ast_user_list::users. Referenced by socket_read(). 05010 { 05011 char requeststr[256]; 05012 char md5secret[256] = ""; 05013 char secret[256] = ""; 05014 char rsasecret[256] = ""; 05015 int res = -1; 05016 int x; 05017 struct iax2_user *user = NULL; 05018 05019 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05020 ast_mutex_lock(&userl.lock); 05021 user = userl.users; 05022 while (user) { 05023 if (!strcmp(user->name, p->username)) { 05024 user->curauthreq--; 05025 break; 05026 } 05027 user = user->next; 05028 } 05029 ast_mutex_unlock(&userl.lock); 05030 ast_clear_flag(p, IAX_MAXAUTHREQ); 05031 } 05032 05033 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05034 return res; 05035 if (ies->password) 05036 ast_copy_string(secret, ies->password, sizeof(secret)); 05037 if (ies->md5_result) 05038 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05039 if (ies->rsa_result) 05040 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05041 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05042 struct ast_key *key; 05043 char *keyn; 05044 char tmpkey[256]; 05045 char *stringp=NULL; 05046 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05047 stringp=tmpkey; 05048 keyn = strsep(&stringp, ":"); 05049 while(keyn) { 05050 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05051 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05052 res = 0; 05053 break; 05054 } else if (!key) 05055 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05056 keyn = strsep(&stringp, ":"); 05057 } 05058 } else if (p->authmethods & IAX_AUTH_MD5) { 05059 struct MD5Context md5; 05060 unsigned char digest[16]; 05061 char *tmppw, *stringp; 05062 05063 tmppw = ast_strdupa(p->secret); 05064 stringp = tmppw; 05065 while((tmppw = strsep(&stringp, ";"))) { 05066 MD5Init(&md5); 05067 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05068 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05069 MD5Final(digest, &md5); 05070 /* If they support md5, authenticate with it. */ 05071 for (x=0;x<16;x++) 05072 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05073 if (!strcasecmp(requeststr, md5secret)) { 05074 res = 0; 05075 break; 05076 } 05077 } 05078 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05079 if (!strcmp(secret, p->secret)) 05080 res = 0; 05081 } 05082 return res; 05083 }
|
|
Definition at line 2852 of file chan_iax2.c. References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, iax2_queue_frame(), iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO. Referenced by iax2_call(), and sip_call(). 02853 { 02854 int callno = PTR_TO_CALLNO(nothing); 02855 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02856 ast_mutex_lock(&iaxsl[callno]); 02857 if (iaxs[callno]) { 02858 iaxs[callno]->initid = -1; 02859 iax2_queue_frame(callno, &f); 02860 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02861 } 02862 ast_mutex_unlock(&iaxsl[callno]); 02863 return 0; 02864 }
|
|
Definition at line 5942 of file chan_iax2.c. References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxsl, and send_command_final(). Referenced by iax2_dprequest(), and iax2_provision(). 05943 { 05944 /* Called from IAX thread only, without iaxs lock */ 05945 int callno = (int)(long)(nothing); 05946 struct iax_ie_data ied; 05947 ast_mutex_lock(&iaxsl[callno]); 05948 if (iaxs[callno]) { 05949 iaxs[callno]->autoid = -1; 05950 memset(&ied, 0, sizeof(ied)); 05951 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 05952 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 05953 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 05954 } 05955 ast_mutex_unlock(&iaxsl[callno]); 05956 return 0; 05957 }
|
|
Definition at line 8088 of file chan_iax2.c. References iax2_context::context, malloc, and iax2_context::next. Referenced by build_user(). 08089 { 08090 struct iax2_context *con = malloc(sizeof(struct iax2_context)); 08091 if (con) { 08092 ast_copy_string(con->context, context, sizeof(con->context)); 08093 con->next = NULL; 08094 } 08095 return con; 08096 }
|
|
Definition at line 3798 of file chan_iax2.c. References aes_decrypt_key128(), and aes_encrypt_key128(). Referenced by authenticate(), and decrypt_frame(). 03799 { 03800 aes_encrypt_key128(digest, ecx); 03801 aes_decrypt_key128(digest, dcx); 03802 }
|
|
Definition at line 8199 of file chan_iax2.c. References ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_true(), DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, defaultsockfd, free, get_auth_methods(), get_encrypt_methods(), iax2_capability, iax2_encryption, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, malloc, min_reg_expire, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::next, peer_set_srcaddr(), peerl, ast_peer_list::peers, timingfd, and ast_variable::value. 08200 { 08201 struct iax2_peer *peer; 08202 struct iax2_peer *prev; 08203 struct ast_ha *oldha = NULL; 08204 int maskfound=0; 08205 int found=0; 08206 prev = NULL; 08207 ast_mutex_lock(&peerl.lock); 08208 if (!temponly) { 08209 peer = peerl.peers; 08210 while(peer) { 08211 if (!strcmp(peer->name, name)) { 08212 break; 08213 } 08214 prev = peer; 08215 peer = peer->next; 08216 } 08217 } else 08218 peer = NULL; 08219 if (peer) { 08220 found++; 08221 oldha = peer->ha; 08222 peer->ha = NULL; 08223 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08224 if (prev) { 08225 prev->next = peer->next; 08226 } else { 08227 peerl.peers = peer->next; 08228 } 08229 ast_mutex_unlock(&peerl.lock); 08230 } else { 08231 ast_mutex_unlock(&peerl.lock); 08232 peer = malloc(sizeof(struct iax2_peer)); 08233 if (peer) { 08234 memset(peer, 0, sizeof(struct iax2_peer)); 08235 peer->expire = -1; 08236 peer->pokeexpire = -1; 08237 peer->sockfd = defaultsockfd; 08238 } 08239 } 08240 if (peer) { 08241 ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08242 peer->encmethods = iax2_encryption; 08243 peer->secret[0] = '\0'; 08244 if (!found) { 08245 ast_copy_string(peer->name, name, sizeof(peer->name)); 08246 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08247 peer->expiry = min_reg_expire; 08248 } 08249 peer->prefs = prefs; 08250 peer->capability = iax2_capability; 08251 peer->smoothing = 0; 08252 peer->pokefreqok = DEFAULT_FREQ_OK; 08253 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08254 peer->context[0] = '\0'; 08255 peer->peercontext[0] = '\0'; 08256 while(v) { 08257 if (!strcasecmp(v->name, "secret")) { 08258 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 08259 } else if (!strcasecmp(v->name, "mailbox")) { 08260 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 08261 } else if (!strcasecmp(v->name, "dbsecret")) { 08262 ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret)); 08263 } else if (!strcasecmp(v->name, "mailboxdetail")) { 08264 ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 08265 } else if (!strcasecmp(v->name, "trunk")) { 08266 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08267 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08268 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08269 ast_clear_flag(peer, IAX_TRUNK); 08270 } 08271 } else if (!strcasecmp(v->name, "auth")) { 08272 peer->authmethods = get_auth_methods(v->value); 08273 } else if (!strcasecmp(v->name, "encryption")) { 08274 peer->encmethods = get_encrypt_methods(v->value); 08275 } else if (!strcasecmp(v->name, "notransfer")) { 08276 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08277 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08278 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08279 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08280 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08281 } else if (!strcasecmp(v->name, "host")) { 08282 if (!strcasecmp(v->value, "dynamic")) { 08283 /* They'll register with us */ 08284 ast_set_flag(peer, IAX_DYNAMIC); 08285 if (!found) { 08286 /* Initialize stuff iff we're not found, otherwise 08287 we keep going with what we had */ 08288 memset(&peer->addr.sin_addr, 0, 4); 08289 if (peer->addr.sin_port) { 08290 /* If we've already got a port, make it the default rather than absolute */ 08291 peer->defaddr.sin_port = peer->addr.sin_port; 08292 peer->addr.sin_port = 0; 08293 } 08294 } 08295 } else { 08296 /* Non-dynamic. Make sure we become that way if we're not */ 08297 if (peer->expire > -1) 08298 ast_sched_del(sched, peer->expire); 08299 peer->expire = -1; 08300 ast_clear_flag(peer, IAX_DYNAMIC); 08301 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08302 free(peer); 08303 return NULL; 08304 } 08305 if (!peer->addr.sin_port) 08306 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08307 } 08308 if (!maskfound) 08309 inet_aton("255.255.255.255", &peer->mask); 08310 } else if (!strcasecmp(v->name, "defaultip")) { 08311 if (ast_get_ip(&peer->defaddr, v->value)) { 08312 free(peer); 08313 return NULL; 08314 } 08315 } else if (!strcasecmp(v->name, "sourceaddress")) { 08316 peer_set_srcaddr(peer, v->value); 08317 } else if (!strcasecmp(v->name, "permit") || 08318 !strcasecmp(v->name, "deny")) { 08319 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08320 } else if (!strcasecmp(v->name, "mask")) { 08321 maskfound++; 08322 inet_aton(v->value, &peer->mask); 08323 } else if (!strcasecmp(v->name, "context")) { 08324 if (ast_strlen_zero(peer->context)) 08325 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 08326 } else if (!strcasecmp(v->name, "regexten")) { 08327 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 08328 } else if (!strcasecmp(v->name, "peercontext")) { 08329 if (ast_strlen_zero(peer->peercontext)) 08330 ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext)); 08331 } else if (!strcasecmp(v->name, "port")) { 08332 if (ast_test_flag(peer, IAX_DYNAMIC)) 08333 peer->defaddr.sin_port = htons(atoi(v->value)); 08334 else 08335 peer->addr.sin_port = htons(atoi(v->value)); 08336 } else if (!strcasecmp(v->name, "username")) { 08337 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 08338 } else if (!strcasecmp(v->name, "allow")) { 08339 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08340 } else if (!strcasecmp(v->name, "disallow")) { 08341 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08342 } else if (!strcasecmp(v->name, "callerid")) { 08343 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), 08344 peer->cid_num, sizeof(peer->cid_num)); 08345 ast_set_flag(peer, IAX_HASCALLERID); 08346 } else if (!strcasecmp(v->name, "sendani")) { 08347 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08348 } else if (!strcasecmp(v->name, "inkeys")) { 08349 ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys)); 08350 } else if (!strcasecmp(v->name, "outkey")) { 08351 ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey)); 08352 } else if (!strcasecmp(v->name, "qualify")) { 08353 if (!strcasecmp(v->value, "no")) { 08354 peer->maxms = 0; 08355 } else if (!strcasecmp(v->value, "yes")) { 08356 peer->maxms = DEFAULT_MAXMS; 08357 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08358 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); 08359 peer->maxms = 0; 08360 } 08361 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08362 peer->smoothing = ast_true(v->value); 08363 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08364 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08365 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); 08366 } 08367 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08368 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08369 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); 08370 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08371 } else if (!strcasecmp(v->name, "timezone")) { 08372 ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag)); 08373 }/* else if (strcasecmp(v->name,"type")) */ 08374 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08375 v=v->next; 08376 } 08377 if (!peer->authmethods) 08378 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08379 ast_clear_flag(peer, IAX_DELME); 08380 /* Make sure these are IPv4 addresses */ 08381 peer->addr.sin_family = AF_INET; 08382 } 08383 if (oldha) 08384 ast_free_ha(oldha); 08385 return peer; 08386 }
|
|
Definition at line 8389 of file chan_iax2.c. References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), build_context(), format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_capability, iax2_encryption, 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_TRUNK, IAX_USEJITTERBUF, language, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::next, timingfd, user, userl, ast_user_list::users, and ast_variable::value. 08390 { 08391 struct iax2_user *prev, *user; 08392 struct iax2_context *con, *conl = NULL; 08393 struct ast_ha *oldha = NULL; 08394 struct iax2_context *oldcon = NULL; 08395 int format; 08396 int oldcurauthreq = 0; 08397 char *varname = NULL, *varval = NULL; 08398 struct ast_variable *tmpvar = NULL; 08399 08400 prev = NULL; 08401 ast_mutex_lock(&userl.lock); 08402 if (!temponly) { 08403 user = userl.users; 08404 while(user) { 08405 if (!strcmp(user->name, name)) { 08406 break; 08407 } 08408 prev = user; 08409 user = user->next; 08410 } 08411 } else 08412 user = NULL; 08413 08414 if (user) { 08415 oldcurauthreq = user->curauthreq; 08416 oldha = user->ha; 08417 oldcon = user->contexts; 08418 user->ha = NULL; 08419 user->contexts = NULL; 08420 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08421 if (prev) { 08422 prev->next = user->next; 08423 } else { 08424 userl.users = user->next; 08425 } 08426 ast_mutex_unlock(&userl.lock); 08427 } else { 08428 ast_mutex_unlock(&userl.lock); 08429 user = malloc(sizeof(struct iax2_user)); 08430 if (user) 08431 memset(user, 0, sizeof(struct iax2_user)); 08432 } 08433 08434 if (user) { 08435 memset(user, 0, sizeof(struct iax2_user)); 08436 user->maxauthreq = maxauthreq; 08437 user->curauthreq = oldcurauthreq; 08438 user->prefs = prefs; 08439 user->capability = iax2_capability; 08440 user->encmethods = iax2_encryption; 08441 ast_copy_string(user->name, name, sizeof(user->name)); 08442 ast_copy_string(user->language, language, sizeof(user->language)); 08443 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08444 while(v) { 08445 if (!strcasecmp(v->name, "context")) { 08446 con = build_context(v->value); 08447 if (con) { 08448 if (conl) 08449 conl->next = con; 08450 else 08451 user->contexts = con; 08452 conl = con; 08453 } 08454 } else if (!strcasecmp(v->name, "permit") || 08455 !strcasecmp(v->name, "deny")) { 08456 user->ha = ast_append_ha(v->name, v->value, user->ha); 08457 } else if (!strcasecmp(v->name, "setvar")) { 08458 varname = ast_strdupa(v->value); 08459 if (varname && (varval = strchr(varname,'='))) { 08460 *varval = '\0'; 08461 varval++; 08462 if((tmpvar = ast_variable_new(varname, varval))) { 08463 tmpvar->next = user->vars; 08464 user->vars = tmpvar; 08465 } 08466 } 08467 } else if (!strcasecmp(v->name, "allow")) { 08468 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08469 } else if (!strcasecmp(v->name, "disallow")) { 08470 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08471 } else if (!strcasecmp(v->name, "trunk")) { 08472 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08473 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08474 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08475 ast_clear_flag(user, IAX_TRUNK); 08476 } 08477 } else if (!strcasecmp(v->name, "auth")) { 08478 user->authmethods = get_auth_methods(v->value); 08479 } else if (!strcasecmp(v->name, "encryption")) { 08480 user->encmethods = get_encrypt_methods(v->value); 08481 } else if (!strcasecmp(v->name, "notransfer")) { 08482 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08483 } else if (!strcasecmp(v->name, "codecpriority")) { 08484 if(!strcasecmp(v->value, "caller")) 08485 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08486 else if(!strcasecmp(v->value, "disabled")) 08487 ast_set_flag(user, IAX_CODEC_NOPREFS); 08488 else if(!strcasecmp(v->value, "reqonly")) { 08489 ast_set_flag(user, IAX_CODEC_NOCAP); 08490 ast_set_flag(user, IAX_CODEC_NOPREFS); 08491 } 08492 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08493 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08494 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08495 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08496 } else if (!strcasecmp(v->name, "dbsecret")) { 08497 ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret)); 08498 } else if (!strcasecmp(v->name, "secret")) { 08499 if (!ast_strlen_zero(user->secret)) { 08500 strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1); 08501 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); 08502 } else 08503 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 08504 } else if (!strcasecmp(v->name, "callerid")) { 08505 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 08506 ast_set_flag(user, IAX_HASCALLERID); 08507 } else if (!strcasecmp(v->name, "accountcode")) { 08508 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 08509 } else if (!strcasecmp(v->name, "language")) { 08510 ast_copy_string(user->language, v->value, sizeof(user->language)); 08511 } else if (!strcasecmp(v->name, "amaflags")) { 08512 format = ast_cdr_amaflags2int(v->value); 08513 if (format < 0) { 08514 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08515 } else { 08516 user->amaflags = format; 08517 } 08518 } else if (!strcasecmp(v->name, "inkeys")) { 08519 ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys)); 08520 } else if (!strcasecmp(v->name, "maxauthreq")) { 08521 user->maxauthreq = atoi(v->value); 08522 if (user->maxauthreq < 0) 08523 user->maxauthreq = 0; 08524 }/* else if (strcasecmp(v->name,"type")) */ 08525 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08526 v = v->next; 08527 } 08528 if (!user->authmethods) { 08529 if (!ast_strlen_zero(user->secret)) { 08530 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08531 if (!ast_strlen_zero(user->inkeys)) 08532 user->authmethods |= IAX_AUTH_RSA; 08533 } else if (!ast_strlen_zero(user->inkeys)) { 08534 user->authmethods = IAX_AUTH_RSA; 08535 } else { 08536 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08537 } 08538 } 08539 ast_clear_flag(user, IAX_DELME); 08540 } 08541 if (oldha) 08542 ast_free_ha(oldha); 08543 if (oldcon) 08544 free_context(oldcon); 08545 return user; 08546 }
|
|
Definition at line 8974 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, 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_MAX_CALLS, IAX_PROTO_VERSION, iaxsl, LOG_WARNING, NEW_FORCE, chan_iax2_pvt::outkey, parse_dial_string(), chan_iax2_pvt::secret, secret, and send_command(). Referenced by find_cache(). 08975 { 08976 struct sockaddr_in sin; 08977 int x; 08978 int callno; 08979 struct iax_ie_data ied; 08980 struct create_addr_info cai; 08981 struct parsed_dial_string pds; 08982 char *tmpstr; 08983 08984 for (x=0; x<IAX_MAX_CALLS; x++) { 08985 /* Look for an *exact match* call. Once a call is negotiated, it can only 08986 look up entries for a single context */ 08987 if (!ast_mutex_trylock(&iaxsl[x])) { 08988 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 08989 return x; 08990 ast_mutex_unlock(&iaxsl[x]); 08991 } 08992 } 08993 08994 /* No match found, we need to create a new one */ 08995 08996 memset(&cai, 0, sizeof(cai)); 08997 memset(&ied, 0, sizeof(ied)); 08998 memset(&pds, 0, sizeof(pds)); 08999 09000 tmpstr = ast_strdupa(data); 09001 parse_dial_string(tmpstr, &pds); 09002 09003 /* Populate our address from the given */ 09004 if (create_addr(pds.peer, &sin, &cai)) 09005 return -1; 09006 09007 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 09008 pds.peer, pds.username, pds.password, pds.context); 09009 09010 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 09011 if (callno < 1) { 09012 ast_log(LOG_WARNING, "Unable to create call\n"); 09013 return -1; 09014 } 09015 09016 ast_mutex_lock(&iaxsl[callno]); 09017 ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot)); 09018 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 09019 09020 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 09021 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 09022 /* the string format is slightly different from a standard dial string, 09023 because the context appears in the 'exten' position 09024 */ 09025 if (pds.exten) 09026 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 09027 if (pds.username) 09028 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 09029 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 09030 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 09031 /* Keep password handy */ 09032 if (pds.password) 09033 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 09034 if (pds.key) 09035 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 09036 /* Start the call going */ 09037 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 09038 09039 return callno; 09040 }
|
|
Definition at line 3661 of file chan_iax2.c. References ast_log(), ast_tvsub(), chan_iax2_pvt::callno, iaxdebug, and chan_iax2_pvt::rxcore. 03662 { 03663 /* Returns where in "receive time" we are. That is, how many ms 03664 since we received (or would have received) the frame with timestamp 0 */ 03665 int ms; 03666 #ifdef IAXTESTS 03667 int jit; 03668 #endif /* IAXTESTS */ 03669 /* Setup rxcore if necessary */ 03670 if (ast_tvzero(p->rxcore)) { 03671 p->rxcore = ast_tvnow(); 03672 if (option_debug && iaxdebug) 03673 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03674 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03675 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03676 #if 1 03677 if (option_debug && iaxdebug) 03678 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03679 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03680 #endif 03681 } 03682 03683 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03684 #ifdef IAXTESTS 03685 if (test_jit) { 03686 if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) { 03687 jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0)); 03688 if ((int)(2.0 * rand() / (RAND_MAX + 1.0))) 03689 jit = -jit; 03690 ms += jit; 03691 } 03692 } 03693 if (test_late) { 03694 ms += test_late; 03695 test_late = 0; 03696 } 03697 #endif /* IAXTESTS */ 03698 return ms; 03699 }
|
|
Definition at line 3517 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, ast_frame::delivery, ast_frame::frametype, iaxdebug, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, and ast_frame::samples. Referenced by iax2_send(), and socket_read(). 03518 { 03519 int ms; 03520 int voice = 0; 03521 int genuine = 0; 03522 int adjust; 03523 struct timeval *delivery = NULL; 03524 03525 03526 /* What sort of frame do we have?: voice is self-explanatory 03527 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03528 non-genuine frames are CONTROL frames [ringing etc], DTMF 03529 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03530 the others need a timestamp slaved to the voice frames so that they go in sequence 03531 */ 03532 if (f) { 03533 if (f->frametype == AST_FRAME_VOICE) { 03534 voice = 1; 03535 delivery = &f->delivery; 03536 } else if (f->frametype == AST_FRAME_IAX) { 03537 genuine = 1; 03538 } else if (f->frametype == AST_FRAME_CNG) { 03539 p->notsilenttx = 0; 03540 } 03541 } 03542 if (ast_tvzero(p->offset)) { 03543 gettimeofday(&p->offset, NULL); 03544 /* Round to nearest 20ms for nice looking traces */ 03545 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03546 } 03547 /* If the timestamp is specified, just send it as is */ 03548 if (ts) 03549 return ts; 03550 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03551 if (delivery && !ast_tvzero(*delivery)) { 03552 ms = ast_tvdiff_ms(*delivery, p->offset); 03553 if (option_debug > 2 && iaxdebug) 03554 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03555 } else { 03556 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03557 if (ms < 0) 03558 ms = 0; 03559 if (voice) { 03560 /* On a voice frame, use predicted values if appropriate */ 03561 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03562 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03563 /* AN EXPLANATION: 03564 When we send voice, we usually send "calculated" timestamps worked out 03565 on the basis of the number of samples sent. When we send other frames, 03566 we usually send timestamps worked out from the real clock. 03567 The problem is that they can tend to drift out of step because the 03568 source channel's clock and our clock may not be exactly at the same rate. 03569 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03570 for this call. Moving it adjusts timestamps for non-voice frames. 03571 We make the adjustment in the style of a moving average. Each time we 03572 adjust p->offset by 10% of the difference between our clock-derived 03573 timestamp and the predicted timestamp. That's why you see "10000" 03574 below even though IAX2 timestamps are in milliseconds. 03575 The use of a moving average avoids offset moving too radically. 03576 Generally, "adjust" roams back and forth around 0, with offset hardly 03577 changing at all. But if a consistent different starts to develop it 03578 will be eliminated over the course of 10 frames (200-300msecs) 03579 */ 03580 adjust = (ms - p->nextpred); 03581 if (adjust < 0) 03582 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03583 else if (adjust > 0) 03584 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03585 03586 if (!p->nextpred) { 03587 p->nextpred = ms; /*f->samples / 8;*/ 03588 if (p->nextpred <= p->lastsent) 03589 p->nextpred = p->lastsent + 3; 03590 } 03591 ms = p->nextpred; 03592 } else { 03593 /* in this case, just use the actual 03594 * time, since we're either way off 03595 * (shouldn't happen), or we're ending a 03596 * silent period -- and seed the next 03597 * predicted time. Also, round ms to the 03598 * next multiple of frame size (so our 03599 * silent periods are multiples of 03600 * frame size too) */ 03601 03602 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03603 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03604 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03605 03606 if (f->samples >= 8) /* check to make sure we dont core dump */ 03607 { 03608 int diff = ms % (f->samples / 8); 03609 if (diff) 03610 ms += f->samples/8 - diff; 03611 } 03612 03613 p->nextpred = ms; 03614 p->notsilenttx = 1; 03615 } 03616 } else { 03617 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03618 it's a genuine frame */ 03619 if (genuine) { 03620 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03621 if (ms <= p->lastsent) 03622 ms = p->lastsent + 3; 03623 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03624 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03625 ms = p->lastsent + 3; 03626 } 03627 } 03628 } 03629 p->lastsent = ms; 03630 if (voice) 03631 p->nextpred = p->nextpred + f->samples / 8; 03632 return ms; 03633 }
|
|
Definition at line 3473 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(). 03474 { 03475 unsigned long int mssincetx; /* unsigned to handle overflows */ 03476 long int ms, pred; 03477 03478 tpeer->trunkact = *tv; 03479 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03480 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03481 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03482 tpeer->txtrunktime = *tv; 03483 tpeer->lastsent = 999999; 03484 } 03485 /* Update last transmit time now */ 03486 tpeer->lasttxtime = *tv; 03487 03488 /* Calculate ms offset */ 03489 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03490 /* Predict from last value */ 03491 pred = tpeer->lastsent + sampms; 03492 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03493 ms = pred; 03494 03495 /* We never send the same timestamp twice, so fudge a little if we must */ 03496 if (ms == tpeer->lastsent) 03497 ms = tpeer->lastsent + 1; 03498 tpeer->lastsent = ms; 03499 return ms; 03500 }
|
|
Definition at line 4727 of file chan_iax2.c. References chan_iax2_pvt::accountcode, accountcode, iax2_user::accountcode, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, chan_iax2_pvt::ani, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, chan_iax2_pvt::cid_name, cid_name, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, destroy_user(), chan_iax2_pvt::dnid, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, chan_iax2_pvt::exten, exten, iax_ies::format, 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_TRUNK, IAX_USEJITTERBUF, chan_iax2_pvt::inkeys, iax2_user::inkeys, key(), iax2_user::language, chan_iax2_pvt::language, language, iax_ies::language, ast_user_list::lock, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, realtime_user(), chan_iax2_pvt::secret, secret, iax2_user::secret, user, userl, chan_iax2_pvt::username, username, iax_ies::username, ast_user_list::users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version. Referenced by socket_read(). 04728 { 04729 /* Start pessimistic */ 04730 int res = -1; 04731 int version = 2; 04732 struct iax2_user *user, *best = NULL; 04733 int bestscore = 0; 04734 int gotcapability = 0; 04735 char iabuf[INET_ADDRSTRLEN]; 04736 struct ast_variable *v = NULL, *tmpvar = NULL; 04737 04738 if (!iaxs[callno]) 04739 return res; 04740 if (ies->called_number) 04741 ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten)); 04742 if (ies->calling_number) { 04743 ast_shrink_phone_number(ies->calling_number); 04744 ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num)); 04745 } 04746 if (ies->calling_name) 04747 ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name)); 04748 if (ies->calling_ani) 04749 ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani)); 04750 if (ies->dnid) 04751 ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid)); 04752 if (ies->called_context) 04753 ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context)); 04754 if (ies->language) 04755 ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language)); 04756 if (ies->username) 04757 ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username)); 04758 if (ies->calling_ton > -1) 04759 iaxs[callno]->calling_ton = ies->calling_ton; 04760 if (ies->calling_tns > -1) 04761 iaxs[callno]->calling_tns = ies->calling_tns; 04762 if (ies->calling_pres > -1) 04763 iaxs[callno]->calling_pres = ies->calling_pres; 04764 if (ies->format) 04765 iaxs[callno]->peerformat = ies->format; 04766 if (ies->adsicpe) 04767 iaxs[callno]->peeradsicpe = ies->adsicpe; 04768 if (ies->capability) { 04769 gotcapability = 1; 04770 iaxs[callno]->peercapability = ies->capability; 04771 } 04772 if (ies->version) 04773 version = ies->version; 04774 04775 /* Use provided preferences until told otherwise for actual preferences */ 04776 if(ies->codec_prefs) { 04777 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04778 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04779 } 04780 04781 if (!gotcapability) 04782 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04783 if (version > IAX_PROTO_VERSION) { 04784 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04785 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version); 04786 return res; 04787 } 04788 ast_mutex_lock(&userl.lock); 04789 /* Search the userlist for a compatible entry, and fill in the rest */ 04790 user = userl.users; 04791 while(user) { 04792 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04793 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04794 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04795 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04796 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04797 if (!ast_strlen_zero(iaxs[callno]->username)) { 04798 /* Exact match, stop right now. */ 04799 best = user; 04800 break; 04801 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04802 /* No required authentication */ 04803 if (user->ha) { 04804 /* There was host authentication and we passed, bonus! */ 04805 if (bestscore < 4) { 04806 bestscore = 4; 04807 best = user; 04808 } 04809 } else { 04810 /* No host access, but no secret, either, not bad */ 04811 if (bestscore < 3) { 04812 bestscore = 3; 04813 best = user; 04814 } 04815 } 04816 } else { 04817 if (user->ha) { 04818 /* Authentication, but host access too, eh, it's something.. */ 04819 if (bestscore < 2) { 04820 bestscore = 2; 04821 best = user; 04822 } 04823 } else { 04824 /* Authentication and no host access... This is our baseline */ 04825 if (bestscore < 1) { 04826 bestscore = 1; 04827 best = user; 04828 } 04829 } 04830 } 04831 } 04832 user = user->next; 04833 } 04834 ast_mutex_unlock(&userl.lock); 04835 user = best; 04836 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 04837 user = realtime_user(iaxs[callno]->username); 04838 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04839 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04840 destroy_user(user); 04841 user = NULL; 04842 } 04843 } 04844 if (user) { 04845 /* We found our match (use the first) */ 04846 /* copy vars */ 04847 for (v = user->vars ; v ; v = v->next) { 04848 if((tmpvar = ast_variable_new(v->name, v->value))) { 04849 tmpvar->next = iaxs[callno]->vars; 04850 iaxs[callno]->vars = tmpvar; 04851 } 04852 } 04853 /* If a max AUTHREQ restriction is in place, activate it */ 04854 if (user->maxauthreq > 0) 04855 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 04856 iaxs[callno]->prefs = user->prefs; 04857 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04858 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04859 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04860 iaxs[callno]->encmethods = user->encmethods; 04861 /* Store the requested username if not specified */ 04862 if (ast_strlen_zero(iaxs[callno]->username)) 04863 ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username)); 04864 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04865 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04866 iaxs[callno]->capability = user->capability; 04867 /* And use the default context */ 04868 if (ast_strlen_zero(iaxs[callno]->context)) { 04869 if (user->contexts) 04870 ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context)); 04871 else 04872 ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context)); 04873 } 04874 /* And any input keys */ 04875 ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys)); 04876 /* And the permitted authentication methods */ 04877 iaxs[callno]->authmethods = user->authmethods; 04878 /* If they have callerid, override the given caller id. Always store the ANI */ 04879 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 04880 if (ast_test_flag(user, IAX_HASCALLERID)) { 04881 iaxs[callno]->calling_tns = 0; 04882 iaxs[callno]->calling_ton = 0; 04883 ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num)); 04884 ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name)); 04885 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 04886 } 04887 if (ast_strlen_zero(iaxs[callno]->ani)) 04888 ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani)); 04889 } else { 04890 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 04891 } 04892 if (!ast_strlen_zero(user->accountcode)) 04893 ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode)); 04894 if (user->amaflags) 04895 iaxs[callno]->amaflags = user->amaflags; 04896 if (!ast_strlen_zero(user->language)) 04897 ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language)); 04898 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04899 /* Keep this check last */ 04900 if (!ast_strlen_zero(user->dbsecret)) { 04901 char *family, *key=NULL; 04902 family = ast_strdupa(user->dbsecret); 04903 if (family) { 04904 key = strchr(family, '/'); 04905 if (key) { 04906 *key = '\0'; 04907 key++; 04908 } 04909 } 04910 if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret))) { 04911 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 04912 if (ast_test_flag(user, IAX_TEMPONLY)) { 04913 destroy_user(user); 04914 user = NULL; 04915 } 04916 } 04917 } else 04918 ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)); 04919 res = 0; 04920 } 04921 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 04922 return res; 04923 }
|
|
Definition at line 6279 of file chan_iax2.c. References ast_log(), iax2_provision(), and iax_provision_version(). Referenced by socket_read(). 06280 { 06281 unsigned int ourver; 06282 char rsi[80]; 06283 snprintf(rsi, sizeof(rsi), "si-%s", si); 06284 if (iax_provision_version(&ourver, rsi, 1)) 06285 return 0; 06286 if (option_debug) 06287 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06288 if (ourver != ver) 06289 iax2_provision(sin, sockfd, NULL, rsi, 1); 06290 return 0; 06291 }
|
|
Definition at line 8117 of file chan_iax2.c. References ast_log(), and LOG_ERROR. Referenced by peer_set_srcaddr(). 08118 { 08119 int sd; 08120 int res; 08121 08122 sd = socket(AF_INET, SOCK_DGRAM, 0); 08123 if (sd < 0) { 08124 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08125 return -1; 08126 } 08127 08128 res = bind(sd, sa, salen); 08129 if (res < 0) { 08130 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08131 close(sd); 08132 return 1; 08133 } 08134 08135 close(sd); 08136 return 0; 08137 }
|
|
Definition at line 5387 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iaxdefaultdpcache, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters. Referenced by socket_read(). 05388 { 05389 char exten[256] = ""; 05390 int status = CACHE_FLAG_UNKNOWN; 05391 int expiry = iaxdefaultdpcache; 05392 int x; 05393 int matchmore = 0; 05394 struct iax2_dpcache *dp, *prev; 05395 05396 if (ies->called_number) 05397 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05398 05399 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05400 status = CACHE_FLAG_EXISTS; 05401 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05402 status = CACHE_FLAG_CANEXIST; 05403 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05404 status = CACHE_FLAG_NONEXISTENT; 05405 05406 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05407 /* Don't really do anything with this */ 05408 } 05409 if (ies->refresh) 05410 expiry = ies->refresh; 05411 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05412 matchmore = CACHE_FLAG_MATCHMORE; 05413 ast_mutex_lock(&dpcache_lock); 05414 prev = NULL; 05415 dp = pvt->dpentries; 05416 while(dp) { 05417 if (!strcmp(dp->exten, exten)) { 05418 /* Let them go */ 05419 if (prev) 05420 prev->peer = dp->peer; 05421 else 05422 pvt->dpentries = dp->peer; 05423 dp->peer = NULL; 05424 dp->callno = 0; 05425 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05426 if (dp->flags & CACHE_FLAG_PENDING) { 05427 dp->flags &= ~CACHE_FLAG_PENDING; 05428 dp->flags |= status; 05429 dp->flags |= matchmore; 05430 } 05431 /* Wake up waiters */ 05432 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05433 if (dp->waiters[x] > -1) 05434 write(dp->waiters[x], "asdf", 4); 05435 } 05436 prev = dp; 05437 dp = dp->peer; 05438 } 05439 ast_mutex_unlock(&dpcache_lock); 05440 return 0; 05441 }
|
|
Definition at line 2007 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and strdup. 02008 { 02009 int which = 0; 02010 struct iax2_peer *p; 02011 char *res = NULL; 02012 02013 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02014 if(pos == 3) { 02015 ast_mutex_lock(&peerl.lock); 02016 for(p = peerl.peers ; p ; p = p->next) { 02017 if(!strncasecmp(p->name, word, strlen(word))) { 02018 if(++which > state) { 02019 res = strdup(p->name); 02020 break; 02021 } 02022 } 02023 } 02024 ast_mutex_unlock(&peerl.lock); 02025 } 02026 02027 return res; 02028 }
|
|
Definition at line 5443 of file chan_iax2.c. References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, ast_iax2_queue::head, iax2_frame_free(), iaxq, 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, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, 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_read(). 05444 { 05445 int peercallno = 0; 05446 struct chan_iax2_pvt *pvt = iaxs[callno]; 05447 struct iax_frame *cur; 05448 05449 if (ies->callno) 05450 peercallno = ies->callno; 05451 05452 if (peercallno < 1) { 05453 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05454 return -1; 05455 } 05456 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05457 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05458 /* Reset sequence numbers */ 05459 pvt->oseqno = 0; 05460 pvt->rseqno = 0; 05461 pvt->iseqno = 0; 05462 pvt->aseqno = 0; 05463 pvt->peercallno = peercallno; 05464 pvt->transferring = TRANSFER_NONE; 05465 pvt->svoiceformat = -1; 05466 pvt->voiceformat = 0; 05467 pvt->svideoformat = -1; 05468 pvt->videoformat = 0; 05469 pvt->transfercallno = -1; 05470 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05471 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05472 #ifdef NEWJB 05473 { /* reset jitterbuffer */ 05474 jb_frame frame; 05475 while(jb_getall(pvt->jb,&frame) == JB_OK) 05476 iax2_frame_free(frame.data); 05477 05478 jb_reset(pvt->jb); 05479 } 05480 #else 05481 memset(&pvt->history, 0, sizeof(pvt->history)); 05482 pvt->jitterbuffer = 0; 05483 pvt->jitter = 0; 05484 pvt->historicjitter = 0; 05485 #endif 05486 pvt->lag = 0; 05487 pvt->last = 0; 05488 pvt->lastsent = 0; 05489 pvt->nextpred = 0; 05490 pvt->pingtime = DEFAULT_RETRY_TIME; 05491 ast_mutex_lock(&iaxq.lock); 05492 for (cur = iaxq.head; cur ; cur = cur->next) { 05493 /* We must cancel any packets that would have been transmitted 05494 because now we're talking to someone new. It's okay, they 05495 were transmitted to someone that didn't care anyway. */ 05496 if (callno == cur->callno) 05497 cur->retries = -1; 05498 } 05499 ast_mutex_unlock(&iaxq.lock); 05500 return 0; 05501 }
|
|
Definition at line 817 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(). 00818 { 00819 int x; 00820 int power=-1; 00821 /* If it's 128 or smaller, just return it */ 00822 if (subclass < IAX_FLAG_SC_LOG) 00823 return subclass; 00824 /* Otherwise find its power */ 00825 for (x = 0; x < IAX_MAX_SHIFT; x++) { 00826 if (subclass & (1 << x)) { 00827 if (power > -1) { 00828 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 00829 return 0; 00830 } else 00831 power = x; 00832 } 00833 } 00834 return power | IAX_FLAG_SC_LOG; 00835 }
|
|
|
Definition at line 2764 of file chan_iax2.c. References iax2_peer::addr, 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, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, defaultsockfd, 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_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::outkey, create_addr_info::outkey, iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag. 02765 { 02766 struct ast_hostent ahp; 02767 struct hostent *hp; 02768 struct iax2_peer *peer; 02769 02770 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02771 cai->sockfd = defaultsockfd; 02772 cai->maxtime = 0; 02773 sin->sin_family = AF_INET; 02774 02775 if (!(peer = find_peer(peername, 1))) { 02776 cai->found = 0; 02777 02778 hp = ast_gethostbyname(peername, &ahp); 02779 if (hp) { 02780 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02781 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02782 /* use global iax prefs for unknown peer/user */ 02783 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02784 return 0; 02785 } else { 02786 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02787 return -1; 02788 } 02789 } 02790 02791 cai->found = 1; 02792 02793 /* if the peer has no address (current or default), return failure */ 02794 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 02795 if (ast_test_flag(peer, IAX_TEMPONLY)) 02796 destroy_peer(peer); 02797 return -1; 02798 } 02799 02800 /* if the peer is being monitored and is currently unreachable, return failure */ 02801 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) { 02802 if (ast_test_flag(peer, IAX_TEMPONLY)) 02803 destroy_peer(peer); 02804 return -1; 02805 } 02806 02807 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02808 cai->maxtime = peer->maxms; 02809 cai->capability = peer->capability; 02810 cai->encmethods = peer->encmethods; 02811 cai->sockfd = peer->sockfd; 02812 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02813 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02814 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02815 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02816 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02817 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02818 if (ast_strlen_zero(peer->dbsecret)) { 02819 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02820 } else { 02821 char *family; 02822 char *key = NULL; 02823 02824 family = ast_strdupa(peer->dbsecret); 02825 if (family) { 02826 key = strchr(family, '/'); 02827 if (key) 02828 *key++ = '\0'; 02829 } 02830 if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02831 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02832 if (ast_test_flag(peer, IAX_TEMPONLY)) 02833 destroy_peer(peer); 02834 return -1; 02835 } 02836 } 02837 02838 if (peer->addr.sin_addr.s_addr) { 02839 sin->sin_addr = peer->addr.sin_addr; 02840 sin->sin_port = peer->addr.sin_port; 02841 } else { 02842 sin->sin_addr = peer->defaddr.sin_addr; 02843 sin->sin_port = peer->defaddr.sin_port; 02844 } 02845 02846 if (ast_test_flag(peer, IAX_TEMPONLY)) 02847 destroy_peer(peer); 02848 02849 return 0; 02850 }
|
|
Definition at line 3852 of file chan_iax2.c. References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, iaxdebug, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass(). Referenced by decrypt_frame(). 03853 { 03854 int padding; 03855 unsigned char *workspace; 03856 workspace = alloca(*datalen); 03857 if (!workspace) 03858 return -1; 03859 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03860 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03861 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03862 return -1; 03863 /* Decrypt */ 03864 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03865 03866 padding = 16 + (workspace[15] & 0xf); 03867 if (option_debug && iaxdebug) 03868 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03869 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03870 return -1; 03871 03872 *datalen -= padding; 03873 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03874 f->frametype = fh->type; 03875 if (f->frametype == AST_FRAME_VIDEO) { 03876 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03877 } else { 03878 f->subclass = uncompress_subclass(fh->csub); 03879 } 03880 } else { 03881 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03882 if (option_debug && iaxdebug) 03883 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03884 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03885 return -1; 03886 /* Decrypt */ 03887 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03888 padding = 16 + (workspace[15] & 0x0f); 03889 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03890 return -1; 03891 *datalen -= padding; 03892 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03893 } 03894 return 0; 03895 }
|
|
Definition at line 3938 of file chan_iax2.c. References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), secret, and strsep(). Referenced by socket_read(). 03939 { 03940 int res=-1; 03941 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 03942 /* Search for possible keys, given secrets */ 03943 struct MD5Context md5; 03944 unsigned char digest[16]; 03945 char *tmppw, *stringp; 03946 03947 tmppw = ast_strdupa(iaxs[callno]->secret); 03948 stringp = tmppw; 03949 while((tmppw = strsep(&stringp, ";"))) { 03950 MD5Init(&md5); 03951 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 03952 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 03953 MD5Final(digest, &md5); 03954 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 03955 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03956 if (!res) { 03957 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 03958 break; 03959 } 03960 } 03961 } else 03962 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03963 return res; 03964 }
|
|
Definition at line 8548 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_registry::callno, iax2_registry::expire, free, iax2_destroy_nolock(), IAX_DELME, iaxsl, ast_peer_list::lock, ast_user_list::lock, iax2_registry::next, peerl, ast_peer_list::peers, chan_iax2_pvt::reg, regl, user, userl, and ast_user_list::users. 08549 { 08550 struct iax2_user *user; 08551 struct iax2_peer *peer; 08552 struct iax2_registry *reg, *regl; 08553 08554 ast_mutex_lock(&userl.lock); 08555 for (user=userl.users;user;) { 08556 ast_set_flag(user, IAX_DELME); 08557 user = user->next; 08558 } 08559 ast_mutex_unlock(&userl.lock); 08560 for (reg = registrations;reg;) { 08561 regl = reg; 08562 reg = reg->next; 08563 if (regl->expire > -1) { 08564 ast_sched_del(sched, regl->expire); 08565 } 08566 if (regl->callno) { 08567 /* XXX Is this a potential lock? I don't think so, but you never know */ 08568 ast_mutex_lock(&iaxsl[regl->callno]); 08569 if (iaxs[regl->callno]) { 08570 iaxs[regl->callno]->reg = NULL; 08571 iax2_destroy_nolock(regl->callno); 08572 } 08573 ast_mutex_unlock(&iaxsl[regl->callno]); 08574 } 08575 free(regl); 08576 } 08577 registrations = NULL; 08578 ast_mutex_lock(&peerl.lock); 08579 for (peer=peerl.peers;peer;) { 08580 /* Assume all will be deleted, and we'll find out for sure later */ 08581 ast_set_flag(peer, IAX_DELME); 08582 peer = peer->next; 08583 } 08584 ast_mutex_unlock(&peerl.lock); 08585 }
|
|
Provides a description of the module.
Definition at line 9727 of file chan_iax2.c. References desc. 09728 { 09729 return (char *) desc; 09730 }
|
|
Definition at line 1149 of file chan_iax2.c. References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh. Referenced by reload_firmware(). 01150 { 01151 /* Close firmware */ 01152 if (cur->fwh) { 01153 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01154 } 01155 close(cur->fd); 01156 free(cur); 01157 }
|
|
|
Definition at line 8587 of file chan_iax2.c. References ast_free_ha(), ast_variables_destroy(), iax2_user::contexts, free, free_context(), iax2_user::ha, and iax2_user::vars. Referenced by check_access(), and prune_users(). 08588 { 08589 ast_free_ha(user->ha); 08590 free_context(user->contexts); 08591 if(user->vars) { 08592 ast_variables_destroy(user->vars); 08593 user->vars = NULL; 08594 } 08595 free(user); 08596 }
|
|
|
Definition at line 6168 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(). 06169 { 06170 /* Look up for dpreq */ 06171 struct dpreq_data *dpr = data; 06172 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06173 if (dpr->callerid) 06174 free(dpr->callerid); 06175 free(dpr); 06176 return NULL; 06177 }
|
|
Definition at line 3897 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, iaxdebug, memcpy_encrypt(), ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type. Referenced by iax2_send(). 03898 { 03899 int padding; 03900 unsigned char *workspace; 03901 workspace = alloca(*datalen + 32); 03902 if (!workspace) 03903 return -1; 03904 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03905 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03906 if (option_debug && iaxdebug) 03907 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03908 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03909 padding = 16 + (padding & 0xf); 03910 memcpy(workspace, poo, padding); 03911 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03912 workspace[15] &= 0xf0; 03913 workspace[15] |= (padding & 0xf); 03914 if (option_debug && iaxdebug) 03915 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]); 03916 *datalen += padding; 03917 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03918 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03919 memcpy(poo, workspace + *datalen - 32, 32); 03920 } else { 03921 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03922 if (option_debug && iaxdebug) 03923 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03924 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03925 padding = 16 + (padding & 0xf); 03926 memcpy(workspace, poo, padding); 03927 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03928 workspace[15] &= 0xf0; 03929 workspace[15] |= (padding & 0x0f); 03930 *datalen += padding; 03931 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 03932 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 03933 memcpy(poo, workspace + *datalen - 32, 32); 03934 } 03935 return 0; 03936 }
|
|
Definition at line 5638 of file chan_iax2.c. References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_test_flag, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_TEMPONLY, min_reg_expire, iax2_peer::name, prune_peers(), and register_peer_exten(). Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry(). 05639 { 05640 struct iax2_peer *p = data; 05641 05642 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name); 05643 /* Reset the address */ 05644 memset(&p->addr, 0, sizeof(p->addr)); 05645 /* Reset expire notice */ 05646 p->expire = -1; 05647 /* Reset expiry value */ 05648 p->expiry = min_reg_expire; 05649 if (!ast_test_flag(p, IAX_TEMPONLY)) 05650 ast_db_del("IAX/Registry", p->name); 05651 register_peer_exten(p, 0); 05652 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05653 if (iax2_regfunk) 05654 iax2_regfunk(p->name, 0); 05655 05656 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) { 05657 ast_set_flag(p, IAX_DELME); 05658 prune_peers(); 05659 } 05660 05661 return 0; 05662 }
|
|
Definition at line 9042 of file chan_iax2.c. References 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, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxdefaultdpcache, iaxdefaulttimeout, iaxsl, LOG_WARNING, malloc, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters. Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore(). 09043 { 09044 struct iax2_dpcache *dp, *prev = NULL, *next; 09045 struct timeval tv; 09046 int x; 09047 int com[2]; 09048 int timeout; 09049 int old=0; 09050 int outfd; 09051 int abort; 09052 int callno; 09053 struct ast_channel *c; 09054 struct ast_frame *f; 09055 gettimeofday(&tv, NULL); 09056 dp = dpcache; 09057 while(dp) { 09058 next = dp->next; 09059 /* Expire old caches */ 09060 if (ast_tvcmp(tv, dp->expiry) > 0) { 09061 /* It's expired, let it disappear */ 09062 if (prev) 09063 prev->next = dp->next; 09064 else 09065 dpcache = dp->next; 09066 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 09067 /* Free memory and go again */ 09068 free(dp); 09069 } else { 09070 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); 09071 } 09072 dp = next; 09073 continue; 09074 } 09075 /* We found an entry that matches us! */ 09076 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 09077 break; 09078 prev = dp; 09079 dp = next; 09080 } 09081 if (!dp) { 09082 /* No matching entry. Create a new one. */ 09083 /* First, can we make a callno? */ 09084 callno = cache_get_callno_locked(data); 09085 if (callno < 0) { 09086 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09087 return NULL; 09088 } 09089 dp = malloc(sizeof(struct iax2_dpcache)); 09090 if (!dp) { 09091 ast_mutex_unlock(&iaxsl[callno]); 09092 return NULL; 09093 } 09094 memset(dp, 0, sizeof(struct iax2_dpcache)); 09095 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09096 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09097 gettimeofday(&dp->expiry, NULL); 09098 dp->orig = dp->expiry; 09099 /* Expires in 30 mins by default */ 09100 dp->expiry.tv_sec += iaxdefaultdpcache; 09101 dp->next = dpcache; 09102 dp->flags = CACHE_FLAG_PENDING; 09103 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09104 dp->waiters[x] = -1; 09105 dpcache = dp; 09106 dp->peer = iaxs[callno]->dpentries; 09107 iaxs[callno]->dpentries = dp; 09108 /* Send the request if we're already up */ 09109 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 09110 iax2_dprequest(dp, callno); 09111 ast_mutex_unlock(&iaxsl[callno]); 09112 } 09113 /* By here we must have a dp */ 09114 if (dp->flags & CACHE_FLAG_PENDING) { 09115 /* Okay, here it starts to get nasty. We need a pipe now to wait 09116 for a reply to come back so long as it's pending */ 09117 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09118 /* Find an empty slot */ 09119 if (dp->waiters[x] < 0) 09120 break; 09121 } 09122 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09123 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09124 return NULL; 09125 } 09126 if (pipe(com)) { 09127 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09128 return NULL; 09129 } 09130 dp->waiters[x] = com[1]; 09131 /* Okay, now we wait */ 09132 timeout = iaxdefaulttimeout * 1000; 09133 /* Temporarily unlock */ 09134 ast_mutex_unlock(&dpcache_lock); 09135 /* Defer any dtmf */ 09136 if (chan) 09137 old = ast_channel_defer_dtmf(chan); 09138 abort = 0; 09139 while(timeout) { 09140 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09141 if (outfd > -1) { 09142 break; 09143 } 09144 if (c) { 09145 f = ast_read(c); 09146 if (f) 09147 ast_frfree(f); 09148 else { 09149 /* Got hung up on, abort! */ 09150 break; 09151 abort = 1; 09152 } 09153 } 09154 } 09155 if (!timeout) { 09156 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09157 } 09158 ast_mutex_lock(&dpcache_lock); 09159 dp->waiters[x] = -1; 09160 close(com[1]); 09161 close(com[0]); 09162 if (abort) { 09163 /* Don't interpret anything, just abort. Not sure what th epoint 09164 of undeferring dtmf on a hung up channel is but hey whatever */ 09165 if (!old && chan) 09166 ast_channel_undefer_dtmf(chan); 09167 return NULL; 09168 } 09169 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09170 /* Now to do non-independent analysis the results of our wait */ 09171 if (dp->flags & CACHE_FLAG_PENDING) { 09172 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09173 pending. Don't let it take as long to timeout. */ 09174 dp->flags &= ~CACHE_FLAG_PENDING; 09175 dp->flags |= CACHE_FLAG_TIMEOUT; 09176 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09177 systems without leaving it unavailable once the server comes back online */ 09178 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09179 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09180 if (dp->waiters[x] > -1) 09181 write(dp->waiters[x], "asdf", 4); 09182 } 09183 } 09184 /* Our caller will obtain the rest */ 09185 if (!old && chan) 09186 ast_channel_undefer_dtmf(chan); 09187 } 09188 return dp; 09189 }
|
|
Definition at line 1047 of file chan_iax2.c. References accountcode, chan_iax2_pvt::addr, amaflags, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, host, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, iaxdebug, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, min_reg_expire, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, ping_time, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, 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_read(). 01048 { 01049 int res = 0; 01050 int x; 01051 struct timeval now; 01052 char iabuf[INET_ADDRSTRLEN]; 01053 char host[80]; 01054 if (new <= NEW_ALLOW) { 01055 /* Look for an existing connection first */ 01056 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01057 ast_mutex_lock(&iaxsl[x]); 01058 if (iaxs[x]) { 01059 /* Look for an exact match */ 01060 if (match(sin, callno, dcallno, iaxs[x])) { 01061 res = x; 01062 } 01063 } 01064 ast_mutex_unlock(&iaxsl[x]); 01065 } 01066 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01067 ast_mutex_lock(&iaxsl[x]); 01068 if (iaxs[x]) { 01069 /* Look for an exact match */ 01070 if (match(sin, callno, dcallno, iaxs[x])) { 01071 res = x; 01072 } 01073 } 01074 ast_mutex_unlock(&iaxsl[x]); 01075 } 01076 } 01077 if ((res < 1) && (new >= NEW_ALLOW)) { 01078 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) 01079 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 01080 gettimeofday(&now, NULL); 01081 for (x=1;x<TRUNK_CALL_START;x++) { 01082 /* Find first unused call number that hasn't been used in a while */ 01083 ast_mutex_lock(&iaxsl[x]); 01084 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01085 ast_mutex_unlock(&iaxsl[x]); 01086 } 01087 /* We've still got lock held if we found a spot */ 01088 if (x >= TRUNK_CALL_START) { 01089 ast_log(LOG_WARNING, "No more space\n"); 01090 return 0; 01091 } 01092 iaxs[x] = new_iax(sin, lockpeer, host); 01093 update_max_nontrunk(); 01094 if (iaxs[x]) { 01095 if (option_debug && iaxdebug) 01096 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01097 iaxs[x]->sockfd = sockfd; 01098 iaxs[x]->addr.sin_port = sin->sin_port; 01099 iaxs[x]->addr.sin_family = sin->sin_family; 01100 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01101 iaxs[x]->peercallno = callno; 01102 iaxs[x]->callno = x; 01103 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01104 iaxs[x]->expiry = min_reg_expire; 01105 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01106 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01107 iaxs[x]->amaflags = amaflags; 01108 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01109 ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode)); 01110 } else { 01111 ast_log(LOG_WARNING, "Out of resources\n"); 01112 ast_mutex_unlock(&iaxsl[x]); 01113 return 0; 01114 } 01115 ast_mutex_unlock(&iaxsl[x]); 01116 res = x; 01117 } 01118 return res; 01119 }
|
|
Definition at line 851 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer(). 00852 { 00853 struct iax2_peer *peer; 00854 ast_mutex_lock(&peerl.lock); 00855 for(peer = peerl.peers; peer; peer = peer->next) { 00856 if (!strcasecmp(peer->name, name)) { 00857 break; 00858 } 00859 } 00860 ast_mutex_unlock(&peerl.lock); 00861 if(!peer && realtime) 00862 peer = realtime_peer(name, NULL); 00863 return peer; 00864 }
|
|
Definition at line 3701 of file chan_iax2.c. References iax2_trunk_peer::addr, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lock, malloc, iax2_trunk_peer::next, iax2_trunk_peer::sockfd, and tpeers. Referenced by iax2_trunk_queue(), and socket_read(). 03702 { 03703 struct iax2_trunk_peer *tpeer; 03704 char iabuf[INET_ADDRSTRLEN]; 03705 /* Finds and locks trunk peer */ 03706 ast_mutex_lock(&tpeerlock); 03707 tpeer = tpeers; 03708 while(tpeer) { 03709 /* We don't lock here because tpeer->addr *never* changes */ 03710 if (!inaddrcmp(&tpeer->addr, sin)) { 03711 ast_mutex_lock(&tpeer->lock); 03712 break; 03713 } 03714 tpeer = tpeer->next; 03715 } 03716 if (!tpeer) { 03717 tpeer = malloc(sizeof(struct iax2_trunk_peer)); 03718 if (tpeer) { 03719 memset(tpeer, 0, sizeof(struct iax2_trunk_peer)); 03720 ast_mutex_init(&tpeer->lock); 03721 tpeer->lastsent = 9999; 03722 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03723 tpeer->trunkact = ast_tvnow(); 03724 ast_mutex_lock(&tpeer->lock); 03725 tpeer->next = tpeers; 03726 tpeer->sockfd = fd; 03727 tpeers = tpeer; 03728 #ifdef SO_NO_CHECK 03729 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03730 #endif 03731 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03732 } 03733 } 03734 ast_mutex_unlock(&tpeerlock); 03735 return tpeer; 03736 }
|
|
Definition at line 3502 of file chan_iax2.c. References chan_iax2_pvt::rxcore. Referenced by socket_read(). 03503 { 03504 long ms; /* NOT unsigned */ 03505 if (ast_tvzero(iaxs[callno]->rxcore)) { 03506 /* Initialize rxcore time if appropriate */ 03507 gettimeofday(&iaxs[callno]->rxcore, NULL); 03508 /* Round to nearest 20ms so traces look pretty */ 03509 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03510 } 03511 /* Calculate difference between trunk and channel */ 03512 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03513 /* Return as the sum of trunk time and the difference between trunk and real time */ 03514 return ms + ts; 03515 }
|
|
Definition at line 7928 of file chan_iax2.c. References free, and iax2_context::next. Referenced by build_user(), and destroy_user(). 07929 { 07930 struct iax2_context *conl; 07931 while(con) { 07932 conl = con; 07933 con = con->next; 07934 free(conl); 07935 } 07936 }
|
|
Definition at line 9314 of file chan_iax2.c. References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, LOG_ERROR, iax2_peer::mailbox, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, and ast_channel::tech_pvt. 09315 { 09316 char *ret = NULL; 09317 struct iax2_peer *peer; 09318 char *peername, *colname; 09319 char iabuf[INET_ADDRSTRLEN]; 09320 09321 if (!(peername = ast_strdupa(data))) { 09322 ast_log(LOG_ERROR, "Memory Error!\n"); 09323 return ret; 09324 } 09325 09326 /* if our channel, return the IP address of the endpoint of current channel */ 09327 if (!strcmp(peername,"CURRENTCHANNEL")) { 09328 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt); 09329 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len); 09330 return buf; 09331 } 09332 09333 if ((colname = strchr(peername, ':'))) { 09334 *colname = '\0'; 09335 colname++; 09336 } else { 09337 colname = "ip"; 09338 } 09339 if (!(peer = find_peer(peername, 1))) 09340 return ret; 09341 09342 if (!strcasecmp(colname, "ip")) { 09343 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09344 } else if (!strcasecmp(colname, "status")) { 09345 peer_status(peer, buf, len); 09346 } else if (!strcasecmp(colname, "mailbox")) { 09347 ast_copy_string(buf, peer->mailbox, len); 09348 } else if (!strcasecmp(colname, "context")) { 09349 ast_copy_string(buf, peer->context, len); 09350 } else if (!strcasecmp(colname, "expire")) { 09351 snprintf(buf, len, "%d", peer->expire); 09352 } else if (!strcasecmp(colname, "dynamic")) { 09353 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09354 } else if (!strcasecmp(colname, "callerid_name")) { 09355 ast_copy_string(buf, peer->cid_name, len); 09356 } else if (!strcasecmp(colname, "callerid_num")) { 09357 ast_copy_string(buf, peer->cid_num, len); 09358 } else if (!strcasecmp(colname, "codecs")) { 09359 ast_getformatname_multiple(buf, len -1, peer->capability); 09360 } else if (!strncasecmp(colname, "codec[", 6)) { 09361 char *codecnum, *ptr; 09362 int index = 0, codec = 0; 09363 09364 codecnum = strchr(colname, '['); 09365 *codecnum = '\0'; 09366 codecnum++; 09367 if ((ptr = strchr(codecnum, ']'))) { 09368 *ptr = '\0'; 09369 } 09370 index = atoi(codecnum); 09371 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09372 ast_copy_string(buf, ast_getformatname(codec), len); 09373 } 09374 } 09375 ret = buf; 09376 09377 return ret; 09378 }
|
|
Definition at line 8098 of file chan_iax2.c. References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA. Referenced by build_peer(), and build_user(). 08099 { 08100 int methods = 0; 08101 if (strstr(value, "rsa")) 08102 methods |= IAX_AUTH_RSA; 08103 if (strstr(value, "md5")) 08104 methods |= IAX_AUTH_MD5; 08105 if (strstr(value, "plaintext")) 08106 methods |= IAX_AUTH_PLAINTEXT; 08107 return methods; 08108 }
|
|
Definition at line 791 of file chan_iax2.c. References ast_true(), and IAX_ENCRYPT_AES128. Referenced by build_peer(), build_user(), and set_config(). 00792 { 00793 int e; 00794 if (!strcasecmp(s, "aes128")) 00795 e = IAX_ENCRYPT_AES128; 00796 else if (ast_true(s)) 00797 e = IAX_ENCRYPT_AES128; 00798 else 00799 e = 0; 00800 return e; 00801 }
|
|
Definition at line 2198 of file chan_iax2.c. References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), chan_iax2_pvt::callno, ast_frame::data, jb_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, ast_frame::mallocd, jb_frame::ms, iax_frame::next, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat. Referenced by update_jbsched(). 02199 { 02200 /* make sure pvt is valid! */ 02201 struct chan_iax2_pvt *pvt = p; 02202 struct iax_frame *fr; 02203 jb_frame frame; 02204 int ret; 02205 long now; 02206 long next; 02207 struct timeval tv; 02208 02209 ast_mutex_lock(&iaxsl[pvt->callno]); 02210 pvt->jbid = -1; 02211 02212 gettimeofday(&tv,NULL); 02213 /* round up a millisecond since ast_sched_runq does; */ 02214 /* prevents us from spinning while waiting for our now */ 02215 /* to catch up with runq's now */ 02216 tv.tv_usec += 1000; 02217 02218 now = ast_tvdiff_ms(tv, pvt->rxcore); 02219 02220 if(now >= (next = jb_next(pvt->jb))) { 02221 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02222 switch(ret) { 02223 case JB_OK: 02224 fr = frame.data; 02225 __do_deliver(fr); 02226 break; 02227 case JB_INTERP: 02228 { 02229 struct ast_frame af; 02230 02231 /* create an interpolation frame */ 02232 af.frametype = AST_FRAME_VOICE; 02233 af.subclass = pvt->voiceformat; 02234 af.datalen = 0; 02235 af.samples = frame.ms * 8; 02236 af.mallocd = 0; 02237 af.src = "IAX2 JB interpolation"; 02238 af.data = NULL; 02239 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02240 af.offset=AST_FRIENDLY_OFFSET; 02241 02242 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02243 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02244 if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE)) 02245 iax2_queue_frame(pvt->callno, &af); 02246 } 02247 break; 02248 case JB_DROP: 02249 iax2_frame_free(frame.data); 02250 break; 02251 case JB_NOFRAME: 02252 case JB_EMPTY: 02253 /* do nothing */ 02254 break; 02255 default: 02256 /* shouldn't happen */ 02257 break; 02258 } 02259 } 02260 update_jbsched(pvt); 02261 ast_mutex_unlock(&iaxsl[pvt->callno]); 02262 return 0; 02263 }
|
|
Definition at line 1443 of file chan_iax2.c. References ast_inet_ntoa(), ast_log(), LOG_WARNING, and netsocket. Referenced by send_packet(), socket_read(), and transmit_trunk(). 01444 { 01445 /* XXX Ideally we should figure out why an error occured and then abort those 01446 rather than continuing to try. Unfortunately, the published interface does 01447 not seem to work XXX */ 01448 #if 0 01449 struct sockaddr_in *sin; 01450 int res; 01451 struct msghdr m; 01452 struct sock_extended_err e; 01453 m.msg_name = NULL; 01454 m.msg_namelen = 0; 01455 m.msg_iov = NULL; 01456 m.msg_control = &e; 01457 m.msg_controllen = sizeof(e); 01458 m.msg_flags = 0; 01459 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01460 if (res < 0) 01461 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01462 else { 01463 if (m.msg_controllen) { 01464 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01465 if (sin) 01466 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 01467 else 01468 ast_log(LOG_WARNING, "No address detected??\n"); 01469 } else { 01470 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01471 } 01472 } 01473 #endif 01474 return 0; 01475 }
|
|
Acknowledgment received for OUR registration.
Definition at line 5504 of file chan_iax2.c. References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3. Referenced by socket_read(). 05505 { 05506 struct iax2_registry *reg; 05507 /* Start pessimistic */ 05508 char peer[256] = ""; 05509 char msgstatus[40]; 05510 int refresh = 0; 05511 char ourip[256] = "<Unspecified>"; 05512 struct sockaddr_in oldus; 05513 struct sockaddr_in us; 05514 char iabuf[INET_ADDRSTRLEN]; 05515 int oldmsgs; 05516 05517 memset(&us, 0, sizeof(us)); 05518 if (ies->apparent_addr) 05519 bcopy(ies->apparent_addr, &us, sizeof(us)); 05520 if (ies->username) 05521 ast_copy_string(peer, ies->username, sizeof(peer)); 05522 if (ies->refresh) 05523 refresh = ies->refresh; 05524 if (ies->calling_number) { 05525 /* We don't do anything with it really, but maybe we should */ 05526 } 05527 reg = iaxs[callno]->reg; 05528 if (!reg) { 05529 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05530 return -1; 05531 } 05532 memcpy(&oldus, ®->us, sizeof(oldus)); 05533 oldmsgs = reg->messages; 05534 if (inaddrcmp(®->addr, sin)) { 05535 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05536 return -1; 05537 } 05538 memcpy(®->us, &us, sizeof(reg->us)); 05539 reg->messages = ies->msgcount; 05540 /* always refresh the registration at the interval requested by the server 05541 we are registering to 05542 */ 05543 reg->refresh = refresh; 05544 if (reg->expire > -1) 05545 ast_sched_del(sched, reg->expire); 05546 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05547 if ((inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) { 05548 if (reg->messages > 65534) 05549 snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n"); 05550 else if (reg->messages > 1) 05551 snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages); 05552 else if (reg->messages > 0) 05553 snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n"); 05554 else 05555 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05556 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 05557 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip, msgstatus); 05558 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05559 } 05560 reg->regstate = REG_STATE_REGISTERED; 05561 return 0; 05562 }
|
|
Definition at line 3357 of file chan_iax2.c. References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03358 { 03359 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03360 if (option_debug) 03361 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03362 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03363 }
|
|
Definition at line 3191 of file chan_iax2.c. References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, channeltype, ast_frame::frametype, iax2_start_transfer(), IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, iaxdebug, iaxsl, last, lock_both(), LOG_WARNING, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, TRANSFER_RELEASED, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3. 03192 { 03193 struct ast_channel *cs[3]; 03194 struct ast_channel *who; 03195 int to = -1; 03196 int res = -1; 03197 int transferstarted=0; 03198 struct ast_frame *f; 03199 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03200 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03201 struct timeval waittimer = {0, 0}, tv; 03202 03203 lock_both(callno0, callno1); 03204 /* Put them in native bridge mode */ 03205 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03206 iaxs[callno0]->bridgecallno = callno1; 03207 iaxs[callno1]->bridgecallno = callno0; 03208 } 03209 unlock_both(callno0, callno1); 03210 03211 /* If not, try to bridge until we can execute a transfer, if we can */ 03212 cs[0] = c0; 03213 cs[1] = c1; 03214 for (/* ever */;;) { 03215 /* Check in case we got masqueraded into */ 03216 if ((c0->type != channeltype) || (c1->type != channeltype)) { 03217 if (option_verbose > 2) 03218 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03219 /* Remove from native mode */ 03220 if (c0->type == channeltype) { 03221 ast_mutex_lock(&iaxsl[callno0]); 03222 iaxs[callno0]->bridgecallno = 0; 03223 ast_mutex_unlock(&iaxsl[callno0]); 03224 } 03225 if (c1->type == channeltype) { 03226 ast_mutex_lock(&iaxsl[callno1]); 03227 iaxs[callno1]->bridgecallno = 0; 03228 ast_mutex_unlock(&iaxsl[callno1]); 03229 } 03230 return AST_BRIDGE_FAILED_NOWARN; 03231 } 03232 if (c0->nativeformats != c1->nativeformats) { 03233 if (option_verbose > 2) { 03234 char buf0[255]; 03235 char buf1[255]; 03236 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03237 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03238 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03239 } 03240 /* Remove from native mode */ 03241 lock_both(callno0, callno1); 03242 iaxs[callno0]->bridgecallno = 0; 03243 iaxs[callno1]->bridgecallno = 0; 03244 unlock_both(callno0, callno1); 03245 return AST_BRIDGE_FAILED_NOWARN; 03246 } 03247 /* check if transfered and if we really want native bridging */ 03248 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) && 03249 !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03250 /* Try the transfer */ 03251 if (iax2_start_transfer(callno0, callno1)) 03252 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03253 transferstarted = 1; 03254 } 03255 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03256 /* Call has been transferred. We're no longer involved */ 03257 gettimeofday(&tv, NULL); 03258 if (ast_tvzero(waittimer)) { 03259 waittimer = tv; 03260 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03261 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03262 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03263 *fo = NULL; 03264 *rc = c0; 03265 res = AST_BRIDGE_COMPLETE; 03266 break; 03267 } 03268 } 03269 to = 1000; 03270 who = ast_waitfor_n(cs, 2, &to); 03271 if (timeoutms > -1) { 03272 timeoutms -= (1000 - to); 03273 if (timeoutms < 0) 03274 timeoutms = 0; 03275 } 03276 if (!who) { 03277 if (!timeoutms) { 03278 res = AST_BRIDGE_RETRY; 03279 break; 03280 } 03281 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03282 res = AST_BRIDGE_FAILED; 03283 break; 03284 } 03285 continue; 03286 } 03287 f = ast_read(who); 03288 if (!f) { 03289 *fo = NULL; 03290 *rc = who; 03291 res = AST_BRIDGE_COMPLETE; 03292 break; 03293 } 03294 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03295 *fo = f; 03296 *rc = who; 03297 res = AST_BRIDGE_COMPLETE; 03298 break; 03299 } 03300 if ((f->frametype == AST_FRAME_VOICE) || 03301 (f->frametype == AST_FRAME_TEXT) || 03302 (f->frametype == AST_FRAME_VIDEO) || 03303 (f->frametype == AST_FRAME_IMAGE) || 03304 (f->frametype == AST_FRAME_DTMF)) { 03305 if ((f->frametype == AST_FRAME_DTMF) && 03306 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03307 if ((who == c0)) { 03308 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 03309 *rc = c0; 03310 *fo = f; 03311 res = AST_BRIDGE_COMPLETE; 03312 /* Remove from native mode */ 03313 break; 03314 } else 03315 goto tackygoto; 03316 } else 03317 if ((who == c1)) { 03318 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 03319 *rc = c1; 03320 *fo = f; 03321 res = AST_BRIDGE_COMPLETE; 03322 break; 03323 } else 03324 goto tackygoto; 03325 } 03326 } else { 03327 #if 0 03328 if (iaxdebug && option_debug) 03329 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03330 if (who == last) 03331 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03332 last = who; 03333 #endif 03334 tackygoto: 03335 if (who == c0) 03336 ast_write(c1, f); 03337 else 03338 ast_write(c0, f); 03339 } 03340 ast_frfree(f); 03341 } else 03342 ast_frfree(f); 03343 /* Swap who gets priority */ 03344 cs[2] = cs[0]; 03345 cs[0] = cs[1]; 03346 cs[1] = cs[2]; 03347 } 03348 lock_both(callno0, callno1); 03349 if(iaxs[callno0]) 03350 iaxs[callno0]->bridgecallno = 0; 03351 if(iaxs[callno1]) 03352 iaxs[callno1]->bridgecallno = 0; 03353 unlock_both(callno0, callno1); 03354 return res; 03355 }
|
|
|
Definition at line 9215 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. 09216 { 09217 int res = 0; 09218 struct iax2_dpcache *dp; 09219 #if 0 09220 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09221 #endif 09222 if ((priority != 1) && (priority != 2)) 09223 return 0; 09224 ast_mutex_lock(&dpcache_lock); 09225 dp = find_cache(chan, data, context, exten, priority); 09226 if (dp) { 09227 if (dp->flags & CACHE_FLAG_CANEXIST) 09228 res= 1; 09229 } 09230 ast_mutex_unlock(&dpcache_lock); 09231 if (!dp) { 09232 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09233 } 09234 return res; 09235 }
|
|
Definition at line 2866 of file chan_iax2.c. References ast_localtime(), ast_strlen_zero(), and t. Referenced by iax2_call(), and update_registry(). 02867 { 02868 time_t t; 02869 struct tm tm; 02870 unsigned int tmp; 02871 time(&t); 02872 localtime_r(&t, &tm); 02873 if (!ast_strlen_zero(tz)) 02874 ast_localtime(&t, &tm, tz); 02875 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02876 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02877 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02878 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02879 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02880 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02881 return tmp; 02882 }
|
|
Definition at line 1601 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_translator_free_path(), ast_variables_destroy(), iax_frame::callno, iax2_user::curauthreq, jb_frame::data, free, ast_iax2_queue::head, iax2_frame_free(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxq, iaxsl, jb_destroy(), jb_getall(), JB_OK, lastused, ast_user_list::lock, LOG_NOTICE, iax2_user::name, iax_frame::next, iax2_user::next, chan_iax2_pvt::owner, iax_frame::retries, update_max_trunk(), user, userl, and ast_user_list::users. Referenced by __unload_module(), destroy_peer(), iax2_destroy_nolock(), iax2_poke_noanswer(), and iax2_poke_peer(). 01602 { 01603 struct chan_iax2_pvt *pvt; 01604 struct iax_frame *cur; 01605 struct ast_channel *owner; 01606 struct iax2_user *user; 01607 01608 retry: 01609 ast_mutex_lock(&iaxsl[callno]); 01610 pvt = iaxs[callno]; 01611 gettimeofday(&lastused[callno], NULL); 01612 01613 if (pvt) 01614 owner = pvt->owner; 01615 else 01616 owner = NULL; 01617 if (owner) { 01618 if (ast_mutex_trylock(&owner->lock)) { 01619 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01620 ast_mutex_unlock(&iaxsl[callno]); 01621 usleep(1); 01622 goto retry; 01623 } 01624 } 01625 if (!owner) 01626 iaxs[callno] = NULL; 01627 if (pvt) { 01628 if (!owner) 01629 pvt->owner = NULL; 01630 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01631 ast_mutex_lock(&userl.lock); 01632 user = userl.users; 01633 while (user) { 01634 if (!strcmp(user->name, pvt->username)) { 01635 user->curauthreq--; 01636 break; 01637 } 01638 user = user->next; 01639 } 01640 ast_mutex_unlock(&userl.lock); 01641 } 01642 /* No more pings or lagrq's */ 01643 if (pvt->pingid > -1) 01644 ast_sched_del(sched, pvt->pingid); 01645 if (pvt->lagid > -1) 01646 ast_sched_del(sched, pvt->lagid); 01647 if (pvt->autoid > -1) 01648 ast_sched_del(sched, pvt->autoid); 01649 if (pvt->authid > -1) 01650 ast_sched_del(sched, pvt->authid); 01651 if (pvt->initid > -1) 01652 ast_sched_del(sched, pvt->initid); 01653 #ifdef NEWJB 01654 if (pvt->jbid > -1) 01655 ast_sched_del(sched, pvt->jbid); 01656 pvt->jbid = -1; 01657 #endif 01658 pvt->pingid = -1; 01659 pvt->lagid = -1; 01660 pvt->autoid = -1; 01661 pvt->authid = -1; 01662 pvt->initid = -1; 01663 if (pvt->bridgetrans) 01664 ast_translator_free_path(pvt->bridgetrans); 01665 pvt->bridgetrans = NULL; 01666 01667 /* Already gone */ 01668 ast_set_flag(pvt, IAX_ALREADYGONE); 01669 01670 if (owner) { 01671 /* If there's an owner, prod it to give up */ 01672 owner->_softhangup |= AST_SOFTHANGUP_DEV; 01673 ast_queue_hangup(owner); 01674 } 01675 01676 for (cur = iaxq.head; cur ; cur = cur->next) { 01677 /* Cancel any pending transmissions */ 01678 if (cur->callno == pvt->callno) 01679 cur->retries = -1; 01680 } 01681 if (pvt->reg) { 01682 pvt->reg->callno = 0; 01683 } 01684 if (!owner) { 01685 if (pvt->vars) { 01686 ast_variables_destroy(pvt->vars); 01687 pvt->vars = NULL; 01688 } 01689 #ifdef NEWJB 01690 { 01691 jb_frame frame; 01692 while(jb_getall(pvt->jb,&frame) == JB_OK) 01693 iax2_frame_free(frame.data); 01694 jb_destroy(pvt->jb); 01695 } 01696 #endif 01697 free(pvt); 01698 } 01699 } 01700 if (owner) { 01701 ast_mutex_unlock(&owner->lock); 01702 } 01703 ast_mutex_unlock(&iaxsl[callno]); 01704 if (callno & 0x4000) 01705 update_max_trunk(); 01706 }
|
|
Definition at line 1707 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax2_destroy(), and iaxsl. Referenced by attempt_transmit(), delete_users(), iax2_hangup(), and socket_read(). 01708 { 01709 /* Actually it's easier to unlock, kill it, and relock */ 01710 ast_mutex_unlock(&iaxsl[callno]); 01711 iax2_destroy(callno); 01712 ast_mutex_lock(&iaxsl[callno]); 01713 }
|
|
Definition at line 9403 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, and parse_dial_string(). 09404 { 09405 struct parsed_dial_string pds; 09406 char *tmp = ast_strdupa(data); 09407 struct iax2_peer *p; 09408 int res = AST_DEVICE_INVALID; 09409 09410 memset(&pds, 0, sizeof(pds)); 09411 parse_dial_string(tmp, &pds); 09412 if (!pds.peer || ast_strlen_zero(pds.peer)) 09413 return res; 09414 09415 if (option_debug > 2) 09416 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 09417 09418 /* SLD: FIXME: second call to find_peer during registration */ 09419 if (!(p = find_peer(pds.peer, 1))) 09420 return res; 09421 09422 res = AST_DEVICE_UNAVAILABLE; 09423 if (option_debug > 2) 09424 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09425 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09426 09427 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09428 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09429 /* Peer is registered, or have default IP address 09430 and a valid registration */ 09431 if (p->historicms == 0 || p->historicms <= p->maxms) 09432 /* let the core figure out whether it is in use or not */ 09433 res = AST_DEVICE_UNKNOWN; 09434 } 09435 09436 if (ast_test_flag(p, IAX_TEMPONLY)) 09437 destroy_peer(p); 09438 09439 return res; 09440 }
|
|
Definition at line 2555 of file chan_iax2.c. References AST_FRAME_DTMF, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 02556 { 02557 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1); 02558 }
|
|
Definition at line 4575 of file chan_iax2.c. References ast_cli(), iaxdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04576 { 04577 if (argc != 2) 04578 return RESULT_SHOWUSAGE; 04579 iaxdebug = 1; 04580 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04581 return RESULT_SUCCESS; 04582 }
|
|
Definition at line 4593 of file chan_iax2.c. References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04594 { 04595 if (argc != 3) 04596 return RESULT_SHOWUSAGE; 04597 #ifdef NEWJB 04598 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04599 #endif 04600 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04601 return RESULT_SUCCESS; 04602 }
|
|
Definition at line 7719 of file chan_iax2.c. References iax2_registry::addr, AST_FRAME_IAX, ast_log(), ast_sched_add(), ast_sched_del(), iax2_registry::callno, defaultsockfd, iax2_registry::expire, find_callno(), iax2_do_register_s(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxdebug, LOG_WARNING, NEW_FORCE, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, iax2_registry::regstate, send_command(), and iax2_registry::username. Referenced by iax2_do_register_s(), and load_module(). 07720 { 07721 struct iax_ie_data ied; 07722 if (option_debug && iaxdebug) 07723 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07724 if (!reg->callno) { 07725 if (option_debug) 07726 ast_log(LOG_DEBUG, "Allocate call number\n"); 07727 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07728 if (reg->callno < 1) { 07729 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07730 return -1; 07731 } else if (option_debug) 07732 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07733 iaxs[reg->callno]->reg = reg; 07734 } 07735 /* Schedule the next registration attempt */ 07736 if (reg->expire > -1) 07737 ast_sched_del(sched, reg->expire); 07738 /* Setup the next registration a little early */ 07739 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07740 /* Send the request */ 07741 memset(&ied, 0, sizeof(ied)); 07742 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07743 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07744 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07745 reg->regstate = REG_STATE_REGSENT; 07746 return 0; 07747 }
|
|
Definition at line 5350 of file chan_iax2.c. References iax2_registry::expire, and iax2_do_register(). Referenced by iax2_ack_registry(), and iax2_do_register(). 05351 { 05352 struct iax2_registry *reg = data; 05353 reg->expire = -1; 05354 iax2_do_register(reg); 05355 return 0; 05356 }
|
|
Definition at line 4584 of file chan_iax2.c. References ast_cli(), iaxtrunkdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04585 { 04586 if (argc != 3) 04587 return RESULT_SHOWUSAGE; 04588 iaxtrunkdebug = 1; 04589 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04590 return RESULT_SUCCESS; 04591 }
|
|
Definition at line 5959 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, and send_command(). Referenced by find_cache(), and socket_read(). 05960 { 05961 struct iax_ie_data ied; 05962 /* Auto-hangup with 30 seconds of inactivity */ 05963 if (iaxs[callno]->autoid > -1) 05964 ast_sched_del(sched, iaxs[callno]->autoid); 05965 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 05966 memset(&ied, 0, sizeof(ied)); 05967 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 05968 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 05969 dp->flags |= CACHE_FLAG_TRANSMITTED; 05970 }
|
|
Definition at line 9261 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. 09262 { 09263 char odata[256]; 09264 char req[256]; 09265 char *ncontext; 09266 char *dialstatus; 09267 struct iax2_dpcache *dp; 09268 struct ast_app *dial; 09269 #if 0 09270 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); 09271 #endif 09272 if (priority == 2) { 09273 /* Indicate status, can be overridden in dialplan */ 09274 dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09275 if (dialstatus) { 09276 dial = pbx_findapp(dialstatus); 09277 if (dial) 09278 pbx_exec(chan, dial, "", newstack); 09279 } 09280 return -1; 09281 } else if (priority != 1) 09282 return -1; 09283 ast_mutex_lock(&dpcache_lock); 09284 dp = find_cache(chan, data, context, exten, priority); 09285 if (dp) { 09286 if (dp->flags & CACHE_FLAG_EXISTS) { 09287 ast_copy_string(odata, data, sizeof(odata)); 09288 ncontext = strchr(odata, '/'); 09289 if (ncontext) { 09290 *ncontext = '\0'; 09291 ncontext++; 09292 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09293 } else { 09294 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09295 } 09296 if (option_verbose > 2) 09297 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09298 } else { 09299 ast_mutex_unlock(&dpcache_lock); 09300 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09301 return -1; 09302 } 09303 } 09304 ast_mutex_unlock(&dpcache_lock); 09305 dial = pbx_findapp("Dial"); 09306 if (dial) { 09307 return pbx_exec(chan, dial, req, newstack); 09308 } else { 09309 ast_log(LOG_WARNING, "No dial application registered\n"); 09310 } 09311 return -1; 09312 }
|
|
Definition at line 9192 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. 09193 { 09194 struct iax2_dpcache *dp; 09195 int res = 0; 09196 #if 0 09197 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09198 #endif 09199 if ((priority != 1) && (priority != 2)) 09200 return 0; 09201 ast_mutex_lock(&dpcache_lock); 09202 dp = find_cache(chan, data, context, exten, priority); 09203 if (dp) { 09204 if (dp->flags & CACHE_FLAG_EXISTS) 09205 res= 1; 09206 } 09207 ast_mutex_unlock(&dpcache_lock); 09208 if (!dp) { 09209 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09210 } 09211 return res; 09212 }
|
|
Definition at line 2577 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt. 02578 { 02579 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02580 ast_mutex_lock(&iaxsl[callno]); 02581 if (iaxs[callno]) 02582 iaxs[callno]->owner = newchan; 02583 else 02584 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02585 ast_mutex_unlock(&iaxsl[callno]); 02586 return 0; 02587 }
|
|
Definition at line 1121 of file chan_iax2.c. References ast_sched_del(), iax_frame_free(), and iax_frame::retrans. Referenced by __do_deliver(), attempt_transmit(), complete_transfer(), get_from_jb(), iax2_destroy(), and schedule_delivery(). 01122 { 01123 if (fr->retrans > -1) 01124 ast_sched_del(sched, fr->retrans); 01125 iax_frame_free(fr); 01126 }
|
|
Definition at line 866 of file chan_iax2.c. References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_peer(), IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer(). Referenced by find_callno(). 00867 { 00868 struct iax2_peer *peer; 00869 int res = 0; 00870 00871 if (lockpeer) 00872 ast_mutex_lock(&peerl.lock); 00873 peer = peerl.peers; 00874 while (peer) { 00875 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 00876 (peer->addr.sin_port == sin.sin_port)) { 00877 ast_copy_string(host, peer->name, len); 00878 res = 1; 00879 break; 00880 } 00881 peer = peer->next; 00882 } 00883 if (lockpeer) 00884 ast_mutex_unlock(&peerl.lock); 00885 if (!peer) { 00886 peer = realtime_peer(NULL, &sin); 00887 if (peer) { 00888 ast_copy_string(host, peer->name, len); 00889 if (ast_test_flag(peer, IAX_TEMPONLY)) 00890 destroy_peer(peer); 00891 res = 1; 00892 } 00893 } 00894 00895 return res; 00896 }
|
|
Definition at line 3396 of file chan_iax2.c. References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, IAX_TRUNK, ast_peer_list::lock, iax2_peer::next, peerl, and ast_peer_list::peers. Referenced by check_access(). 03397 { 03398 struct iax2_peer *peer; 03399 int res = 0; 03400 ast_mutex_lock(&peerl.lock); 03401 peer = peerl.peers; 03402 while(peer) { 03403 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03404 (peer->addr.sin_port == sin.sin_port)) { 03405 res = ast_test_flag(peer, IAX_TRUNK); 03406 break; 03407 } 03408 peer = peer->next; 03409 } 03410 ast_mutex_unlock(&peerl.lock); 03411 return res; 03412 }
|
|
Definition at line 3084 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_nolock(), iax2_predestroy_nolock(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxsl, ast_channel::name, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3. 03085 { 03086 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03087 int alreadygone; 03088 struct iax_ie_data ied; 03089 memset(&ied, 0, sizeof(ied)); 03090 ast_mutex_lock(&iaxsl[callno]); 03091 if (callno && iaxs[callno]) { 03092 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03093 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03094 /* Send the hangup unless we have had a transmission error or are already gone */ 03095 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03096 if (!iaxs[callno]->error && !alreadygone) 03097 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03098 /* Explicitly predestroy it */ 03099 iax2_predestroy_nolock(callno); 03100 /* If we were already gone to begin with, destroy us now */ 03101 if (alreadygone) { 03102 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03103 iax2_destroy_nolock(callno); 03104 } 03105 } 03106 ast_mutex_unlock(&iaxsl[callno]); 03107 if (option_verbose > 2) 03108 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03109 return 0; 03110 }
|
|
Definition at line 3365 of file chan_iax2.c. References AST_FRAME_CONTROL, ast_log(), iaxdebug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03366 { 03367 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03368 if (option_debug && iaxdebug) 03369 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03370 return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1); 03371 }
|
|
Definition at line 9238 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. 09239 { 09240 int res = 0; 09241 struct iax2_dpcache *dp; 09242 #if 0 09243 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09244 #endif 09245 if ((priority != 1) && (priority != 2)) 09246 return 0; 09247 ast_mutex_lock(&dpcache_lock); 09248 dp = find_cache(chan, data, context, exten, priority); 09249 if (dp) { 09250 if (dp->flags & CACHE_FLAG_MATCHMORE) 09251 res= 1; 09252 } 09253 ast_mutex_unlock(&dpcache_lock); 09254 if (!dp) { 09255 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09256 } 09257 return res; 09258 }
|
|
Definition at line 4604 of file chan_iax2.c. References ast_cli(), iaxdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04605 { 04606 if (argc != 3) 04607 return RESULT_SHOWUSAGE; 04608 iaxdebug = 0; 04609 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04610 return RESULT_SUCCESS; 04611 }
|
|
Definition at line 4622 of file chan_iax2.c. References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04623 { 04624 if (argc != 4) 04625 return RESULT_SHOWUSAGE; 04626 #ifdef NEWJB 04627 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04628 jb_debug_output("\n"); 04629 #endif 04630 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04631 return RESULT_SUCCESS; 04632 }
|
|
Definition at line 4613 of file chan_iax2.c. References ast_cli(), iaxtrunkdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04614 { 04615 if (argc != 4) 04616 return RESULT_SHOWUSAGE; 04617 iaxtrunkdebug = 0; 04618 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04619 return RESULT_SUCCESS; 04620 }
|
|
Definition at line 7870 of file chan_iax2.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok. Referenced by iax2_poke_peer(). 07871 { 07872 struct iax2_peer *peer = data; 07873 peer->pokeexpire = -1; 07874 if (peer->lastms > -1) { 07875 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07876 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07877 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07878 } 07879 if (peer->callno > 0) 07880 iax2_destroy(peer->callno); 07881 peer->callno = 0; 07882 peer->lastms = -1; 07883 /* Try again quickly */ 07884 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07885 return 0; 07886 }
|
|
Definition at line 7888 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, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, send_command(), and iax2_peer::sockfd. Referenced by iax2_poke_peer_s(), load_module(), reg_source_db(), and update_registry(). 07889 { 07890 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07891 /* IF we have no IP, or this isn't to be monitored, return 07892 imeediately after clearing things out */ 07893 peer->lastms = 0; 07894 peer->historicms = 0; 07895 peer->pokeexpire = -1; 07896 peer->callno = 0; 07897 return 0; 07898 } 07899 if (peer->callno > 0) { 07900 ast_log(LOG_NOTICE, "Still have a callno...\n"); 07901 iax2_destroy(peer->callno); 07902 } 07903 if (heldcall) 07904 ast_mutex_unlock(&iaxsl[heldcall]); 07905 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 07906 if (heldcall) 07907 ast_mutex_lock(&iaxsl[heldcall]); 07908 if (peer->callno < 1) { 07909 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 07910 return -1; 07911 } 07912 if (peer->pokeexpire > -1) 07913 ast_sched_del(sched, peer->pokeexpire); 07914 /* Speed up retransmission times */ 07915 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 07916 iaxs[peer->callno]->peerpoke = peer; 07917 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 07918 07919 /* If the host is already unreachable then use the unreachable interval instead */ 07920 if (peer->lastms < 0) { 07921 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 07922 } else 07923 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 07924 07925 return 0; 07926 }
|
|
Definition at line 5993 of file chan_iax2.c. References iax2_poke_peer(), and iax2_peer::pokeexpire. Referenced by iax2_poke_noanswer(), and socket_read(). 05994 { 05995 struct iax2_peer *peer = data; 05996 peer->pokeexpire = -1; 05997 iax2_poke_peer(peer, 0); 05998 return 0; 05999 }
|
|
Definition at line 1528 of file chan_iax2.c. References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_update_use_count(), iax2_user::curauthreq, IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxsl, ast_user_list::lock, LOG_WARNING, iax2_user::name, iax2_user::next, chan_iax2_pvt::owner, ast_channel::tech_pvt, usecnt, usecnt_lock, user, userl, and ast_user_list::users. Referenced by iax2_predestroy_nolock(). 01529 { 01530 struct ast_channel *c; 01531 struct chan_iax2_pvt *pvt; 01532 struct iax2_user *user; 01533 ast_mutex_lock(&iaxsl[callno]); 01534 pvt = iaxs[callno]; 01535 if (!pvt) { 01536 ast_mutex_unlock(&iaxsl[callno]); 01537 return -1; 01538 } 01539 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01540 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01541 ast_mutex_lock(&userl.lock); 01542 user = userl.users; 01543 while (user) { 01544 if (!strcmp(user->name, pvt->username)) { 01545 user->curauthreq--; 01546 break; 01547 } 01548 user = user->next; 01549 } 01550 ast_mutex_unlock(&userl.lock); 01551 } 01552 /* No more pings or lagrq's */ 01553 if (pvt->pingid > -1) 01554 ast_sched_del(sched, pvt->pingid); 01555 if (pvt->lagid > -1) 01556 ast_sched_del(sched, pvt->lagid); 01557 if (pvt->autoid > -1) 01558 ast_sched_del(sched, pvt->autoid); 01559 if (pvt->authid > -1) 01560 ast_sched_del(sched, pvt->authid); 01561 if (pvt->initid > -1) 01562 ast_sched_del(sched, pvt->initid); 01563 #ifdef NEWJB 01564 if (pvt->jbid > -1) 01565 ast_sched_del(sched, pvt->jbid); 01566 pvt->jbid = -1; 01567 #endif 01568 pvt->pingid = -1; 01569 pvt->lagid = -1; 01570 pvt->autoid = -1; 01571 pvt->initid = -1; 01572 pvt->authid = -1; 01573 ast_set_flag(pvt, IAX_ALREADYGONE); 01574 } 01575 c = pvt->owner; 01576 if (c) { 01577 c->_softhangup |= AST_SOFTHANGUP_DEV; 01578 c->tech_pvt = NULL; 01579 ast_queue_hangup(c); 01580 pvt->owner = NULL; 01581 ast_mutex_lock(&usecnt_lock); 01582 usecnt--; 01583 if (usecnt < 0) 01584 ast_log(LOG_WARNING, "Usecnt < 0???\n"); 01585 ast_mutex_unlock(&usecnt_lock); 01586 } 01587 ast_mutex_unlock(&iaxsl[callno]); 01588 ast_update_use_count(); 01589 return 0; 01590 }
|
|
Definition at line 1592 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax2_predestroy(), and iaxsl. Referenced by iax2_hangup(), and send_command_final(). 01593 { 01594 int res; 01595 ast_mutex_unlock(&iaxsl[callno]); 01596 res = iax2_predestroy(callno); 01597 ast_mutex_lock(&iaxsl[callno]); 01598 return res; 01599 }
|
|
Definition at line 7848 of file chan_iax2.c. References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 07849 { 07850 int force = 0; 07851 int res; 07852 if (argc < 4) 07853 return RESULT_SHOWUSAGE; 07854 if ((argc > 4)) { 07855 if (!strcasecmp(argv[4], "forced")) 07856 force = 1; 07857 else 07858 return RESULT_SHOWUSAGE; 07859 } 07860 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07861 if (res < 0) 07862 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07863 else if (res < 1) 07864 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07865 else 07866 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07867 return RESULT_SUCCESS; 07868 }
|
|
Definition at line 7749 of file chan_iax2.c. References iax_prov_complete_template(). 07750 { 07751 if (pos != 3) 07752 return NULL; 07753 return iax_prov_complete_template(line, word, pos, state); 07754 }
|
|
Definition at line 7756 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(), iaxsl, NEW_FORCE, iax_ie_data::pos, and send_command(). Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd(). 07757 { 07758 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07759 is found for template */ 07760 struct iax_ie_data provdata; 07761 struct iax_ie_data ied; 07762 unsigned int sig; 07763 struct sockaddr_in sin; 07764 int callno; 07765 struct create_addr_info cai; 07766 07767 memset(&cai, 0, sizeof(cai)); 07768 07769 if (option_debug) 07770 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07771 07772 if (iax_provision_build(&provdata, &sig, template, force)) { 07773 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07774 return 0; 07775 } 07776 07777 if (end) { 07778 memcpy(&sin, end, sizeof(sin)); 07779 cai.sockfd = sockfd; 07780 } else if (create_addr(dest, &sin, &cai)) 07781 return -1; 07782 07783 /* Build the rest of the message */ 07784 memset(&ied, 0, sizeof(ied)); 07785 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07786 07787 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07788 if (!callno) 07789 return -1; 07790 07791 ast_mutex_lock(&iaxsl[callno]); 07792 if (iaxs[callno]) { 07793 /* Schedule autodestruct in case they don't ever give us anything back */ 07794 if (iaxs[callno]->autoid > -1) 07795 ast_sched_del(sched, iaxs[callno]->autoid); 07796 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07797 ast_set_flag(iaxs[callno], IAX_PROVISION); 07798 /* Got a call number now, so go ahead and send the provisioning information */ 07799 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07800 } 07801 ast_mutex_unlock(&iaxsl[callno]); 07802 07803 return 1; 07804 }
|
|
Definition at line 1853 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. 01854 { 01855 struct iax2_peer *peer; 01856 01857 if (argc != 4) 01858 return RESULT_SHOWUSAGE; 01859 if (!strcmp(argv[3],"all")) { 01860 reload_config(); 01861 ast_cli(fd, "OK cache is flushed.\n"); 01862 } else if ((peer = find_peer(argv[3], 0))) { 01863 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 01864 ast_set_flag(peer, IAX_RTAUTOCLEAR); 01865 expire_registry(peer); 01866 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 01867 } else { 01868 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 01869 } 01870 } else { 01871 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 01872 } 01873 01874 return RESULT_SUCCESS; 01875 }
|
|
Definition at line 1128 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), and iaxsl. Referenced by __do_deliver(), attempt_transmit(), auto_congest(), get_from_jb(), and socket_read(). 01129 { 01130 /* Assumes lock for callno is already held... */ 01131 for (;;) { 01132 if (iaxs[callno] && iaxs[callno]->owner) { 01133 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01134 /* Avoid deadlock by pausing and trying again */ 01135 ast_mutex_unlock(&iaxsl[callno]); 01136 usleep(1); 01137 ast_mutex_lock(&iaxsl[callno]); 01138 } else { 01139 ast_queue_frame(iaxs[callno]->owner, f); 01140 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01141 break; 01142 } 01143 } else 01144 break; 01145 } 01146 return 0; 01147 }
|
|
Definition at line 3141 of file chan_iax2.c. References AST_FRAME_NULL, ast_log(), and LOG_NOTICE. 03142 { 03143 static struct ast_frame f = { AST_FRAME_NULL, }; 03144 ast_log(LOG_NOTICE, "I should never be called!\n"); 03145 return &f; 03146 }
|
|
Definition at line 5564 of file chan_iax2.c. References ast_gethostbyname(), ast_log(), iax2_registry::callno, copy(), hostname, hp, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_ERROR, LOG_WARNING, malloc, secret, strsep(), and username. Referenced by set_config(). 05565 { 05566 struct iax2_registry *reg; 05567 char copy[256]; 05568 char *username, *hostname, *secret; 05569 char *porta; 05570 char *stringp=NULL; 05571 05572 struct ast_hostent ahp; struct hostent *hp; 05573 if (!value) 05574 return -1; 05575 ast_copy_string(copy, value, sizeof(copy)); 05576 stringp=copy; 05577 username = strsep(&stringp, "@"); 05578 hostname = strsep(&stringp, "@"); 05579 if (!hostname) { 05580 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno); 05581 return -1; 05582 } 05583 stringp=username; 05584 username = strsep(&stringp, ":"); 05585 secret = strsep(&stringp, ":"); 05586 stringp=hostname; 05587 hostname = strsep(&stringp, ":"); 05588 porta = strsep(&stringp, ":"); 05589 05590 if (porta && !atoi(porta)) { 05591 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05592 return -1; 05593 } 05594 hp = ast_gethostbyname(hostname, &ahp); 05595 if (!hp) { 05596 ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno); 05597 return -1; 05598 } 05599 reg = malloc(sizeof(struct iax2_registry)); 05600 if (reg) { 05601 memset(reg, 0, sizeof(struct iax2_registry)); 05602 ast_copy_string(reg->username, username, sizeof(reg->username)); 05603 if (secret) 05604 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05605 reg->expire = -1; 05606 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05607 reg->addr.sin_family = AF_INET; 05608 memcpy(®->addr.sin_addr, hp->h_addr, sizeof(®->addr.sin_addr)); 05609 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05610 reg->next = registrations; 05611 reg->callno = 0; 05612 registrations = reg; 05613 } else { 05614 ast_log(LOG_ERROR, "Out of memory\n"); 05615 return -1; 05616 } 05617 return 0; 05618 }
|
|
Definition at line 8964 of file chan_iax2.c. References reload_config(). 08965 { 08966 return reload_config(); 08967 }
|
|
Definition at line 7938 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_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), fmt, chan_iax2_pvt::host, host, iax2_capability, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat. 07939 { 07940 int callno; 07941 int res; 07942 int fmt, native; 07943 struct sockaddr_in sin; 07944 struct ast_channel *c; 07945 struct parsed_dial_string pds; 07946 struct create_addr_info cai; 07947 char *tmpstr; 07948 07949 memset(&pds, 0, sizeof(pds)); 07950 tmpstr = ast_strdupa(data); 07951 parse_dial_string(tmpstr, &pds); 07952 07953 memset(&cai, 0, sizeof(cai)); 07954 cai.capability = iax2_capability; 07955 07956 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07957 07958 if (!pds.peer) { 07959 ast_log(LOG_WARNING, "No peer given\n"); 07960 return NULL; 07961 } 07962 07963 07964 /* Populate our address from the given */ 07965 if (create_addr(pds.peer, &sin, &cai)) { 07966 *cause = AST_CAUSE_UNREGISTERED; 07967 return NULL; 07968 } 07969 07970 if (pds.port) 07971 sin.sin_port = htons(atoi(pds.port)); 07972 07973 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07974 if (callno < 1) { 07975 ast_log(LOG_WARNING, "Unable to create call\n"); 07976 *cause = AST_CAUSE_CONGESTION; 07977 return NULL; 07978 } 07979 07980 ast_mutex_lock(&iaxsl[callno]); 07981 07982 /* If this is a trunk, update it now */ 07983 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07984 if (ast_test_flag(&cai, IAX_TRUNK)) 07985 callno = make_trunk(callno, 1); 07986 iaxs[callno]->maxtime = cai.maxtime; 07987 if (cai.found) 07988 ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host)); 07989 07990 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 07991 07992 ast_mutex_unlock(&iaxsl[callno]); 07993 07994 if (c) { 07995 /* Choose a format we can live with */ 07996 if (c->nativeformats & format) 07997 c->nativeformats &= format; 07998 else { 07999 native = c->nativeformats; 08000 fmt = format; 08001 res = ast_translator_best_choice(&fmt, &native); 08002 if (res < 0) { 08003 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08004 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08005 ast_hangup(c); 08006 return NULL; 08007 } 08008 c->nativeformats = native; 08009 } 08010 c->readformat = ast_best_codec(c->nativeformats); 08011 c->writeformat = c->readformat; 08012 } 08013 08014 return c; 08015 }
|
|
Definition at line 3966 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, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, iaxdebug, 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, 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_read(). 03967 { 03968 /* Queue a packet for delivery on a given private structure. Use "ts" for 03969 timestamp, or calculate if ts is 0. Send immediately without retransmission 03970 or delayed, with retransmission */ 03971 struct ast_iax2_full_hdr *fh; 03972 struct ast_iax2_mini_hdr *mh; 03973 struct ast_iax2_video_hdr *vh; 03974 struct { 03975 struct iax_frame fr2; 03976 unsigned char buffer[4096]; 03977 } frb; 03978 struct iax_frame *fr; 03979 int res; 03980 int sendmini=0; 03981 unsigned int lastsent; 03982 unsigned int fts; 03983 03984 if (!pvt) { 03985 ast_log(LOG_WARNING, "No private structure for packet?\n"); 03986 return -1; 03987 } 03988 03989 lastsent = pvt->lastsent; 03990 03991 /* Calculate actual timestamp */ 03992 fts = calc_timestamp(pvt, ts, f); 03993 03994 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 03995 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 03996 * increment the "predicted timestamps" for voice, if we're predecting */ 03997 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 03998 return 0; 03999 04000 04001 if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L))) 04002 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04003 (f->frametype == AST_FRAME_VOICE) 04004 /* is a voice frame */ && 04005 (f->subclass == pvt->svoiceformat) 04006 /* is the same type */ ) { 04007 /* Force immediate rather than delayed transmission */ 04008 now = 1; 04009 /* Mark that mini-style frame is appropriate */ 04010 sendmini = 1; 04011 } 04012 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 04013 (f->frametype == AST_FRAME_VIDEO) && 04014 ((f->subclass & ~0x1) == pvt->svideoformat)) { 04015 now = 1; 04016 sendmini = 1; 04017 } 04018 /* Allocate an iax_frame */ 04019 if (now) { 04020 fr = &frb.fr2; 04021 } else 04022 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen); 04023 if (!fr) { 04024 ast_log(LOG_WARNING, "Out of memory\n"); 04025 return -1; 04026 } 04027 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04028 iax_frame_wrap(fr, f); 04029 04030 fr->ts = fts; 04031 fr->callno = pvt->callno; 04032 fr->transfer = transfer; 04033 fr->final = final; 04034 if (!sendmini) { 04035 /* We need a full frame */ 04036 if (seqno > -1) 04037 fr->oseqno = seqno; 04038 else 04039 fr->oseqno = pvt->oseqno++; 04040 fr->iseqno = pvt->iseqno; 04041 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04042 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04043 fh->ts = htonl(fr->ts); 04044 fh->oseqno = fr->oseqno; 04045 if (transfer) { 04046 fh->iseqno = 0; 04047 } else 04048 fh->iseqno = fr->iseqno; 04049 /* Keep track of the last thing we've acknowledged */ 04050 if (!transfer) 04051 pvt->aseqno = fr->iseqno; 04052 fh->type = fr->af.frametype & 0xFF; 04053 if (fr->af.frametype == AST_FRAME_VIDEO) 04054 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04055 else 04056 fh->csub = compress_subclass(fr->af.subclass); 04057 if (transfer) { 04058 fr->dcallno = pvt->transfercallno; 04059 } else 04060 fr->dcallno = pvt->peercallno; 04061 fh->dcallno = htons(fr->dcallno); 04062 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04063 fr->data = fh; 04064 fr->retries = 0; 04065 /* Retry after 2x the ping time has passed */ 04066 fr->retrytime = pvt->pingtime * 2; 04067 if (fr->retrytime < MIN_RETRY_TIME) 04068 fr->retrytime = MIN_RETRY_TIME; 04069 if (fr->retrytime > MAX_RETRY_TIME) 04070 fr->retrytime = MAX_RETRY_TIME; 04071 /* Acks' don't get retried */ 04072 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04073 fr->retries = -1; 04074 else if (f->frametype == AST_FRAME_VOICE) 04075 pvt->svoiceformat = f->subclass; 04076 else if (f->frametype == AST_FRAME_VIDEO) 04077 pvt->svideoformat = f->subclass & ~0x1; 04078 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04079 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04080 if (iaxdebug) { 04081 if (fr->transfer) 04082 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04083 else 04084 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04085 } 04086 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04087 } else 04088 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04089 } 04090 04091 if (now) { 04092 res = send_packet(fr); 04093 } else 04094 res = iax2_transmit(fr); 04095 } else { 04096 if (ast_test_flag(pvt, IAX_TRUNK)) { 04097 iax2_trunk_queue(pvt, fr); 04098 res = 0; 04099 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04100 /* Video frame have no sequence number */ 04101 fr->oseqno = -1; 04102 fr->iseqno = -1; 04103 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04104 vh->zeros = 0; 04105 vh->callno = htons(0x8000 | fr->callno); 04106 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04107 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04108 fr->data = vh; 04109 fr->retries = -1; 04110 res = send_packet(fr); 04111 } else { 04112 /* Mini-frames have no sequence number */ 04113 fr->oseqno = -1; 04114 fr->iseqno = -1; 04115 /* Mini frame will do */ 04116 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04117 mh->callno = htons(fr->callno); 04118 mh->ts = htons(fr->ts & 0xFFFF); 04119 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04120 fr->data = mh; 04121 fr->retries = -1; 04122 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04123 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04124 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04125 } else 04126 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04127 } 04128 res = send_packet(fr); 04129 } 04130 } 04131 return res; 04132 }
|
|
Definition at line 2572 of file chan_iax2.c. References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 02573 { 02574 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02575 }
|
|
Definition at line 2567 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. 02568 { 02569 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02570 }
|
|
Definition at line 2560 of file chan_iax2.c. References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 02561 { 02562 02563 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02564 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02565 }
|
|
Definition at line 1817 of file chan_iax2.c. References ast_cli(), IAX_MAX_CALLS, max_jitter_buffer, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01818 { 01819 #ifdef NEWJB 01820 ast_cli(fd, "sorry, this command is deprecated\n"); 01821 return RESULT_SUCCESS; 01822 #else 01823 if ((argc != 4) && (argc != 5)) 01824 return RESULT_SHOWUSAGE; 01825 if (argc == 4) { 01826 max_jitter_buffer = atoi(argv[3]); 01827 if (max_jitter_buffer < 0) 01828 max_jitter_buffer = 0; 01829 } else { 01830 if (argc == 5) { 01831 if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) { 01832 if (iaxs[atoi(argv[3])]) { 01833 iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]); 01834 if (iaxs[atoi(argv[3])]->jitterbuffer < 0) 01835 iaxs[atoi(argv[3])]->jitterbuffer = 0; 01836 } else 01837 ast_cli(fd, "No such call '%d'\n", atoi(argv[3])); 01838 } else 01839 ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3])); 01840 } 01841 } 01842 return RESULT_SUCCESS; 01843 #endif 01844 }
|
|
Definition at line 3112 of file chan_iax2.c. References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_log(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, free, LOG_WARNING, malloc, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03113 { 03114 struct ast_option_header *h; 03115 int res; 03116 03117 switch (option) { 03118 case AST_OPTION_TXGAIN: 03119 case AST_OPTION_RXGAIN: 03120 /* these two cannot be sent, because they require a result */ 03121 errno = ENOSYS; 03122 return -1; 03123 default: 03124 h = malloc(datalen + sizeof(*h)); 03125 if (h) { 03126 h->flag = AST_OPTION_FLAG_REQUEST; 03127 h->option = htons(option); 03128 memcpy(h->data, data, datalen); 03129 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03130 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03131 datalen + sizeof(*h), -1); 03132 free(h); 03133 return res; 03134 } else { 03135 ast_log(LOG_WARNING, "Out of memory\n"); 03136 return -1; 03137 } 03138 } 03139 }
|
|
Definition at line 2050 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. 02051 { 02052 struct iax2_dpcache *dp; 02053 char tmp[1024], *pc; 02054 int s; 02055 int x,y; 02056 struct timeval tv; 02057 gettimeofday(&tv, NULL); 02058 ast_mutex_lock(&dpcache_lock); 02059 dp = dpcache; 02060 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02061 while(dp) { 02062 s = dp->expiry.tv_sec - tv.tv_sec; 02063 tmp[0] = '\0'; 02064 if (dp->flags & CACHE_FLAG_EXISTS) 02065 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02066 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02067 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02068 if (dp->flags & CACHE_FLAG_CANEXIST) 02069 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02070 if (dp->flags & CACHE_FLAG_PENDING) 02071 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02072 if (dp->flags & CACHE_FLAG_TIMEOUT) 02073 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02074 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02075 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02076 if (dp->flags & CACHE_FLAG_MATCHMORE) 02077 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02078 if (dp->flags & CACHE_FLAG_UNKNOWN) 02079 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02080 /* Trim trailing pipe */ 02081 if (!ast_strlen_zero(tmp)) 02082 tmp[strlen(tmp) - 1] = '\0'; 02083 else 02084 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02085 y=0; 02086 pc = strchr(dp->peercontext, '@'); 02087 if (!pc) 02088 pc = dp->peercontext; 02089 else 02090 pc++; 02091 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02092 if (dp->waiters[x] > -1) 02093 y++; 02094 if (s > 0) 02095 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02096 else 02097 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02098 dp = dp->next; 02099 } 02100 ast_mutex_unlock(&dpcache_lock); 02101 return RESULT_SUCCESS; 02102 }
|
|
Definition at line 4417 of file chan_iax2.c. References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, FORMATB, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and username. 04418 { 04419 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04420 #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" 04421 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04422 int x; 04423 int numchans = 0; 04424 char iabuf[INET_ADDRSTRLEN]; 04425 04426 if (argc != 3) 04427 return RESULT_SHOWUSAGE; 04428 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04429 for (x=0;x<IAX_MAX_CALLS;x++) { 04430 ast_mutex_lock(&iaxsl[x]); 04431 if (iaxs[x]) { 04432 #ifdef BRIDGE_OPTIMIZATION 04433 if (iaxs[x]->bridgecallno) 04434 ast_cli(fd, FORMATB, 04435 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04436 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04437 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04438 iaxs[x]->callno, iaxs[x]->peercallno, 04439 iaxs[x]->oseqno, iaxs[x]->iseqno, 04440 iaxs[x]->bridgecallno ); 04441 else 04442 #endif 04443 { 04444 int lag, jitter, localdelay; 04445 #ifdef NEWJB 04446 jb_info jbinfo; 04447 04448 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04449 jb_getinfo(iaxs[x]->jb, &jbinfo); 04450 jitter = jbinfo.jitter; 04451 localdelay = jbinfo.current - jbinfo.min; 04452 } else { 04453 jitter = -1; 04454 localdelay = 0; 04455 } 04456 #else 04457 jitter = iaxs[x]->jitter; 04458 localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0; 04459 #endif 04460 lag = iaxs[x]->remote_rr.delay; 04461 ast_cli(fd, FORMAT, 04462 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04463 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04464 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04465 iaxs[x]->callno, iaxs[x]->peercallno, 04466 iaxs[x]->oseqno, iaxs[x]->iseqno, 04467 lag, 04468 jitter, 04469 localdelay, 04470 ast_getformatname(iaxs[x]->voiceformat) ); 04471 } 04472 numchans++; 04473 } 04474 ast_mutex_unlock(&iaxsl[x]); 04475 } 04476 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04477 return RESULT_SUCCESS; 04478 #undef FORMAT 04479 #undef FORMAT2 04480 #undef FORMATB 04481 }
|
|
Definition at line 4314 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. 04315 { 04316 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04317 #if !defined(__FreeBSD__) 04318 #define FORMAT "%-15.15s %-15d %-15d\n" 04319 #else /* __FreeBSD__ */ 04320 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04321 #endif /* __FreeBSD__ */ 04322 struct iax_firmware *cur; 04323 if ((argc != 3) && (argc != 4)) 04324 return RESULT_SHOWUSAGE; 04325 ast_mutex_lock(&waresl.lock); 04326 04327 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04328 for (cur = waresl.wares;cur;cur = cur->next) { 04329 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04330 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04331 (int)ntohl(cur->fwh->datalen)); 04332 } 04333 ast_mutex_unlock(&waresl.lock); 04334 return RESULT_SUCCESS; 04335 #undef FORMAT 04336 #undef FORMAT2 04337 }
|
|
Definition at line 4563 of file chan_iax2.c. References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 04564 { 04565 int numchans = 0; 04566 if (argc != 3) 04567 return RESULT_SHOWUSAGE; 04568 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04569 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04570 numchans = ast_cli_netstats(fd, 1); 04571 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04572 return RESULT_SUCCESS; 04573 }
|
|
Definition at line 1946 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::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::defaddr, destroy_peer(), iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TEMPONLY, iax2_peer::mailbox, iax2_peer::name, peer_status(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username. 01947 { 01948 char status[30]; 01949 char cbuf[256]; 01950 char iabuf[INET_ADDRSTRLEN]; 01951 struct iax2_peer *peer; 01952 char codec_buf[512]; 01953 int x = 0, codec = 0, load_realtime = 0; 01954 01955 if (argc < 4) 01956 return RESULT_SHOWUSAGE; 01957 01958 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 01959 01960 peer = find_peer(argv[3], load_realtime); 01961 if (peer) { 01962 ast_cli(fd,"\n\n"); 01963 ast_cli(fd, " * Name : %s\n", peer->name); 01964 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 01965 ast_cli(fd, " Context : %s\n", peer->context); 01966 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 01967 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 01968 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 01969 ast_cli(fd, " Expire : %d\n", peer->expire); 01970 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 01971 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 01972 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 01973 ast_cli(fd, " Username : %s\n", peer->username); 01974 ast_cli(fd, " Codecs : "); 01975 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 01976 ast_cli(fd, "%s\n", codec_buf); 01977 01978 ast_cli(fd, " Codec Order : ("); 01979 for(x = 0; x < 32 ; x++) { 01980 codec = ast_codec_pref_index(&peer->prefs,x); 01981 if(!codec) 01982 break; 01983 ast_cli(fd, "%s", ast_getformatname(codec)); 01984 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 01985 ast_cli(fd, "|"); 01986 } 01987 01988 if (!x) 01989 ast_cli(fd, "none"); 01990 ast_cli(fd, ")\n"); 01991 01992 ast_cli(fd, " Status : "); 01993 peer_status(peer, status, sizeof(status)); 01994 ast_cli(fd, "%s\n",status); 01995 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 01996 ast_cli(fd,"\n"); 01997 if (ast_test_flag(peer, IAX_TEMPONLY)) 01998 destroy_peer(peer); 01999 } else { 02000 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02001 ast_cli(fd,"\n"); 02002 } 02003 02004 return RESULT_SUCCESS; 02005 }
|
|
Definition at line 4303 of file chan_iax2.c. References __iax2_show_peers(). 04304 { 04305 return __iax2_show_peers(0, fd, argc, argv); 04306 }
|
|
Definition at line 4375 of file chan_iax2.c. References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), FORMAT, FORMAT2, host, ast_peer_list::lock, iax2_registry::next, peerl, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username. 04376 { 04377 #define FORMAT2 "%-20.20s %-10.10s %-20.20s %8.8s %s\n" 04378 #define FORMAT "%-20.20s %-10.10s %-20.20s %8d %s\n" 04379 struct iax2_registry *reg; 04380 char host[80]; 04381 char perceived[80]; 04382 char iabuf[INET_ADDRSTRLEN]; 04383 if (argc != 3) 04384 return RESULT_SHOWUSAGE; 04385 ast_mutex_lock(&peerl.lock); 04386 ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State"); 04387 for (reg = registrations;reg;reg = reg->next) { 04388 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04389 if (reg->us.sin_addr.s_addr) 04390 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 04391 else 04392 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04393 ast_cli(fd, FORMAT, host, 04394 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04395 } 04396 ast_mutex_unlock(&peerl.lock); 04397 return RESULT_SUCCESS; 04398 #undef FORMAT 04399 #undef FORMAT2 04400 }
|
|
Definition at line 2030 of file chan_iax2.c. References ast_cli(), iax_frame::final, ast_iax2_queue::head, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries. 02031 { 02032 struct iax_frame *cur; 02033 int cnt = 0, dead=0, final=0; 02034 if (argc != 3) 02035 return RESULT_SHOWUSAGE; 02036 for (cur = iaxq.head; cur ; cur = cur->next) { 02037 if (cur->retries < 0) 02038 dead++; 02039 if (cur->final) 02040 final++; 02041 cnt++; 02042 } 02043 ast_cli(fd, " IAX Statistics\n"); 02044 ast_cli(fd, "---------------------\n"); 02045 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02046 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt); 02047 return RESULT_SUCCESS; 02048 }
|
|
Definition at line 4136 of file chan_iax2.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, context, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, ast_user_list::lock, iax2_user::name, iax2_user::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, user, userl, and ast_user_list::users. 04137 { 04138 regex_t regexbuf; 04139 int havepattern = 0; 04140 04141 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04142 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04143 04144 struct iax2_user *user; 04145 char auth[90]; 04146 char *pstr = ""; 04147 04148 switch (argc) { 04149 case 5: 04150 if (!strcasecmp(argv[3], "like")) { 04151 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04152 return RESULT_SHOWUSAGE; 04153 havepattern = 1; 04154 } else 04155 return RESULT_SHOWUSAGE; 04156 case 3: 04157 break; 04158 default: 04159 return RESULT_SHOWUSAGE; 04160 } 04161 04162 ast_mutex_lock(&userl.lock); 04163 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04164 for(user=userl.users;user;user=user->next) { 04165 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04166 continue; 04167 04168 if (!ast_strlen_zero(user->secret)) { 04169 ast_copy_string(auth,user->secret,sizeof(auth)); 04170 } else if (!ast_strlen_zero(user->inkeys)) { 04171 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04172 } else 04173 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04174 04175 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04176 pstr = "REQ Only"; 04177 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04178 pstr = "Disabled"; 04179 else 04180 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04181 04182 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04183 user->contexts ? user->contexts->context : context, 04184 user->ha ? "Yes" : "No", pstr); 04185 04186 } 04187 ast_mutex_unlock(&userl.lock); 04188 04189 if (havepattern) 04190 regfree(®exbuf); 04191 04192 return RESULT_SUCCESS; 04193 #undef FORMAT 04194 #undef FORMAT2 04195 }
|
|
Definition at line 3148 of file chan_iax2.c. References AST_FRAME_IAX, 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, send_command(), TRANSFER_BEGIN, and chan_iax2_pvt::transferring. Referenced by iax2_bridge(). 03149 { 03150 int res; 03151 struct iax_ie_data ied0; 03152 struct iax_ie_data ied1; 03153 unsigned int transferid = rand(); 03154 memset(&ied0, 0, sizeof(ied0)); 03155 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03156 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03157 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03158 03159 memset(&ied1, 0, sizeof(ied1)); 03160 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03161 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03162 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03163 03164 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03165 if (res) 03166 return -1; 03167 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03168 if (res) 03169 return -1; 03170 iaxs[callno0]->transferring = TRANSFER_BEGIN; 03171 iaxs[callno1]->transferring = TRANSFER_BEGIN; 03172 return 0; 03173 }
|
|
Definition at line 1877 of file chan_iax2.c. References RESULT_SHOWUSAGE, RESULT_SUCCESS, and test_losspct. 01878 { 01879 if (argc != 4) 01880 return RESULT_SHOWUSAGE; 01881 01882 test_losspct = atoi(argv[3]); 01883 01884 return RESULT_SUCCESS; 01885 }
|
|
Definition at line 3373 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03374 { 03375 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03376 struct iax_ie_data ied; 03377 char tmp[256], *context; 03378 ast_copy_string(tmp, dest, sizeof(tmp)); 03379 context = strchr(tmp, '@'); 03380 if (context) { 03381 *context = '\0'; 03382 context++; 03383 } 03384 memset(&ied, 0, sizeof(ied)); 03385 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03386 if (context) 03387 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03388 if (option_debug) 03389 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03390 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03391 }
|
|
Definition at line 2527 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_iax2_queue::count, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, netthreadid, iax_frame::next, iax_frame::prev, iax_frame::sentyet, and ast_iax2_queue::tail. Referenced by iax2_send(). 02528 { 02529 /* Lock the queue and place this packet at the end */ 02530 fr->next = NULL; 02531 fr->prev = NULL; 02532 /* By setting this to 0, the network thread will send it for us, and 02533 queue retransmission if necessary */ 02534 fr->sentyet = 0; 02535 ast_mutex_lock(&iaxq.lock); 02536 if (!iaxq.head) { 02537 /* Empty queue */ 02538 iaxq.head = fr; 02539 iaxq.tail = fr; 02540 } else { 02541 /* Double link */ 02542 iaxq.tail->next = fr; 02543 fr->prev = iaxq.tail; 02544 iaxq.tail = fr; 02545 } 02546 iaxq.count++; 02547 ast_mutex_unlock(&iaxq.lock); 02548 /* Wake up the network thread */ 02549 pthread_kill(netthreadid, SIGURG); 02550 return 0; 02551 }
|
|
Definition at line 6044 of file chan_iax2.c. References iax2_trunk_peer::trunkact. Referenced by timing_read(). 06045 { 06046 /* Drop when trunk is about 5 seconds idle */ 06047 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06048 return 1; 06049 return 0; 06050 }
|
|
Definition at line 3738 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_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, find_tpeer(), 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, realloc, 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(). 03739 { 03740 struct ast_frame *f; 03741 struct iax2_trunk_peer *tpeer; 03742 void *tmp, *ptr; 03743 struct ast_iax2_meta_trunk_entry *met; 03744 struct ast_iax2_meta_trunk_mini *mtm; 03745 char iabuf[INET_ADDRSTRLEN]; 03746 03747 f = &fr->af; 03748 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03749 if (tpeer) { 03750 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03751 /* Need to reallocate space */ 03752 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03753 tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE); 03754 if (tmp) { 03755 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03756 tpeer->trunkdata = tmp; 03757 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 03758 } else { 03759 ast_log(LOG_WARNING, "Insufficient memory to expand trunk data to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03760 ast_mutex_unlock(&tpeer->lock); 03761 return -1; 03762 } 03763 } else { 03764 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03765 ast_mutex_unlock(&tpeer->lock); 03766 return -1; 03767 } 03768 } 03769 03770 /* Append to meta frame */ 03771 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03772 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03773 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03774 mtm->len = htons(f->datalen); 03775 mtm->mini.callno = htons(pvt->callno); 03776 mtm->mini.ts = htons(0xffff & fr->ts); 03777 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03778 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03779 } else { 03780 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03781 /* Store call number and length in meta header */ 03782 met->callno = htons(pvt->callno); 03783 met->len = htons(f->datalen); 03784 /* Advance pointers/decrease length past trunk entry header */ 03785 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03786 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03787 } 03788 /* Copy actual trunk data */ 03789 memcpy(ptr, f->data, f->datalen); 03790 tpeer->trunkdatalen += f->datalen; 03791 03792 tpeer->calls++; 03793 ast_mutex_unlock(&tpeer->lock); 03794 } 03795 return 0; 03796 }
|
|
Definition at line 5972 of file chan_iax2.c. References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate(). Referenced by socket_read(). 05973 { 05974 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 05975 }
|
|
Definition at line 4634 of file chan_iax2.c. References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt. 04635 { 04636 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04637 int res = -1; 04638 ast_mutex_lock(&iaxsl[callno]); 04639 if (iaxs[callno]) { 04640 /* If there's an outstanding error, return failure now */ 04641 if (!iaxs[callno]->error) { 04642 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04643 res = 0; 04644 /* Don't waste bandwidth sending null frames */ 04645 else if (f->frametype == AST_FRAME_NULL) 04646 res = 0; 04647 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04648 res = 0; 04649 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04650 res = 0; 04651 else 04652 /* Simple, just queue for transmission */ 04653 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04654 } else { 04655 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04656 } 04657 } 04658 /* If it's already gone, just return */ 04659 ast_mutex_unlock(&iaxsl[callno]); 04660 return res; 04661 }
|
|
Definition at line 1306 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(). 01307 { 01308 int res = 0; 01309 struct iax_firmware *cur; 01310 if (!ast_strlen_zero(dev)) { 01311 ast_mutex_lock(&waresl.lock); 01312 cur = waresl.wares; 01313 while(cur) { 01314 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01315 res = ntohs(cur->fwh->version); 01316 break; 01317 } 01318 cur = cur->next; 01319 } 01320 ast_mutex_unlock(&waresl.lock); 01321 } 01322 return res; 01323 }
|
|
Definition at line 666 of file chan_iax2.c. References ast_verbose(), and iaxdebug. Referenced by load_module(). 00667 { 00668 if (iaxdebug) 00669 ast_verbose("%s", data); 00670 }
|
|
Definition at line 672 of file chan_iax2.c. References ast_log(), and LOG_WARNING. Referenced by load_module(). 00673 { 00674 ast_log(LOG_WARNING, "%s", data); 00675 }
|
|
Definition at line 1325 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_read(). 01326 { 01327 int res = -1; 01328 unsigned int bs = desc & 0xff; 01329 unsigned int start = (desc >> 8) & 0xffffff; 01330 unsigned int bytes; 01331 struct iax_firmware *cur; 01332 if (!ast_strlen_zero((char *)dev) && bs) { 01333 start *= bs; 01334 ast_mutex_lock(&waresl.lock); 01335 cur = waresl.wares; 01336 while(cur) { 01337 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01338 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01339 if (start < ntohl(cur->fwh->datalen)) { 01340 bytes = ntohl(cur->fwh->datalen) - start; 01341 if (bytes > bs) 01342 bytes = bs; 01343 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01344 } else { 01345 bytes = 0; 01346 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01347 } 01348 if (bytes == bs) 01349 res = 0; 01350 else 01351 res = 1; 01352 break; 01353 } 01354 cur = cur->next; 01355 } 01356 ast_mutex_unlock(&waresl.lock); 01357 } 01358 return res; 01359 }
|
|
Definition at line 6223 of file chan_iax2.c. References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat. Referenced by socket_read(). 06224 { 06225 struct iax_dual *d; 06226 struct ast_channel *chan1m, *chan2m; 06227 pthread_t th; 06228 chan1m = ast_channel_alloc(0); 06229 chan2m = ast_channel_alloc(0); 06230 if (chan2m && chan1m) { 06231 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 06232 /* Make formats okay */ 06233 chan1m->readformat = chan1->readformat; 06234 chan1m->writeformat = chan1->writeformat; 06235 ast_channel_masquerade(chan1m, chan1); 06236 /* Setup the extensions and such */ 06237 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06238 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06239 chan1m->priority = chan1->priority; 06240 06241 /* We make a clone of the peer channel too, so we can play 06242 back the announcement */ 06243 snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name); 06244 /* Make formats okay */ 06245 chan2m->readformat = chan2->readformat; 06246 chan2m->writeformat = chan2->writeformat; 06247 ast_channel_masquerade(chan2m, chan2); 06248 /* Setup the extensions and such */ 06249 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06250 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06251 chan2m->priority = chan2->priority; 06252 if (ast_do_masquerade(chan2m)) { 06253 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06254 ast_hangup(chan2m); 06255 return -1; 06256 } 06257 } else { 06258 if (chan1m) 06259 ast_hangup(chan1m); 06260 if (chan2m) 06261 ast_hangup(chan2m); 06262 return -1; 06263 } 06264 d = malloc(sizeof(struct iax_dual)); 06265 if (d) { 06266 memset(d, 0, sizeof(*d)); 06267 d->chan1 = chan1m; 06268 d->chan2 = chan2m; 06269 if (!ast_pthread_create(&th, NULL, iax_park_thread, d)) 06270 return 0; 06271 free(d); 06272 } 06273 return -1; 06274 }
|
|
Definition at line 6203 of file chan_iax2.c. References ast_frfree(), ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, free, and LOG_NOTICE. Referenced by iax_park(). 06204 { 06205 struct ast_channel *chan1, *chan2; 06206 struct iax_dual *d; 06207 struct ast_frame *f; 06208 int ext; 06209 int res; 06210 d = stuff; 06211 chan1 = d->chan1; 06212 chan2 = d->chan2; 06213 free(d); 06214 f = ast_read(chan1); 06215 if (f) 06216 ast_frfree(f); 06217 res = ast_park_call(chan1, chan2, 0, &ext); 06218 ast_hangup(chan2); 06219 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06220 return NULL; 06221 }
|
|
Definition at line 933 of file chan_iax2.c. References iax_frame::af, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap(). Referenced by socket_read(). 00934 { 00935 /* Malloc() a copy of a frame */ 00936 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen); 00937 if (new) { 00938 memcpy(new, fr, sizeof(struct iax_frame)); 00939 iax_frame_wrap(new, &fr->af); 00940 new->data = NULL; 00941 new->datalen = 0; 00942 new->direction = DIRECTION_INGRESS; 00943 new->retrans = -1; 00944 } 00945 return new; 00946 }
|
|
Definition at line 702 of file chan_iax2.c. References ast_verbose(). Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug(). 00703 { 00704 va_list args; 00705 char buf[1024]; 00706 00707 va_start(args, fmt); 00708 vsnprintf(buf, 1024, fmt, args); 00709 va_end(args); 00710 00711 ast_verbose(buf); 00712 }
|
|
Definition at line 678 of file chan_iax2.c. References ast_log(), and LOG_ERROR. Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module(). 00679 { 00680 va_list args; 00681 char buf[1024]; 00682 00683 va_start(args, fmt); 00684 vsnprintf(buf, 1024, fmt, args); 00685 va_end(args); 00686 00687 ast_log(LOG_ERROR, buf); 00688 }
|
|
Definition at line 690 of file chan_iax2.c. References ast_log(), and LOG_WARNING. Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module(). 00691 { 00692 va_list args; 00693 char buf[1024]; 00694 00695 va_start(args, fmt); 00696 vsnprintf(buf, 1024, fmt, args); 00697 va_end(args); 00698 00699 ast_log(LOG_WARNING, buf); 00700 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 9737 of file chan_iax2.c. References ASTERISK_GPL_KEY. 09738 { 09739 return ASTERISK_GPL_KEY; 09740 }
|
|
|
Definition at line 3175 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl. Referenced by iax2_bridge(). 03176 { 03177 ast_mutex_lock(&iaxsl[callno0]); 03178 while (ast_mutex_trylock(&iaxsl[callno1])) { 03179 ast_mutex_unlock(&iaxsl[callno0]); 03180 usleep(10); 03181 ast_mutex_lock(&iaxsl[callno0]); 03182 } 03183 }
|
|
Definition at line 1000 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, IAX_MAX_CALLS, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, ping_time, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk(). Referenced by iax2_request(), and socket_read(). 01001 { 01002 int x; 01003 int res= 0; 01004 struct timeval now; 01005 if (iaxs[callno]->oseqno) { 01006 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01007 return -1; 01008 } 01009 if (callno & TRUNK_CALL_START) { 01010 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01011 return -1; 01012 } 01013 gettimeofday(&now, NULL); 01014 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01015 ast_mutex_lock(&iaxsl[x]); 01016 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01017 iaxs[x] = iaxs[callno]; 01018 iaxs[x]->callno = x; 01019 iaxs[callno] = NULL; 01020 /* Update the two timers that should have been started */ 01021 if (iaxs[x]->pingid > -1) 01022 ast_sched_del(sched, iaxs[x]->pingid); 01023 if (iaxs[x]->lagid > -1) 01024 ast_sched_del(sched, iaxs[x]->lagid); 01025 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01026 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01027 if (locked) 01028 ast_mutex_unlock(&iaxsl[callno]); 01029 res = x; 01030 if (!locked) 01031 ast_mutex_unlock(&iaxsl[x]); 01032 break; 01033 } 01034 ast_mutex_unlock(&iaxsl[x]); 01035 } 01036 if (x >= IAX_MAX_CALLS - 1) { 01037 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01038 return -1; 01039 } 01040 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01041 /* We move this call from a non-trunked to a trunked call */ 01042 update_max_trunk(); 01043 update_max_nontrunk(); 01044 return res; 01045 }
|
|
Definition at line 4307 of file chan_iax2.c. References ast_cli(), ast_cli_netstats(), mansession::fd, and RESULT_SUCCESS. Referenced by load_module(). 04308 { 04309 ast_cli_netstats(s->fd, 0); 04310 ast_cli(s->fd, "\r\n"); 04311 return RESULT_SUCCESS; 04312 }
|
|
Definition at line 4340 of file chan_iax2.c. References __iax2_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), mansession::fd, and id. Referenced by load_module(). 04341 { 04342 char *a[] = { "iax2", "show", "users" }; 04343 int ret; 04344 char *id; 04345 id = astman_get_header(m,"ActionID"); 04346 if (!ast_strlen_zero(id)) 04347 ast_cli(s->fd, "ActionID: %s\r\n",id); 04348 ret = __iax2_show_peers(1, s->fd, 3, a ); 04349 ast_cli(s->fd, "\r\n\r\n" ); 04350 return ret; 04351 } /* /JDG */
|
|
Definition at line 952 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_extension_close(), ast_extension_match(), ast_parse_device_state(), complete_show_channels(), find_callno(), find_cli(), find_command(), key_matches(), pbx_find_extension(), realtime_switch_common(), schedule_delivery(), and softhangup_exec(). 00953 { 00954 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 00955 (cur->addr.sin_port == sin->sin_port)) { 00956 /* This is the main host */ 00957 if ((cur->peercallno == callno) || 00958 ((dcallno == cur->callno) && !cur->peercallno)) { 00959 /* That's us. Be sure we keep track of the peer call number */ 00960 return 1; 00961 } 00962 } 00963 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 00964 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 00965 /* We're transferring */ 00966 if (dcallno == cur->callno) 00967 return 1; 00968 } 00969 return 0; 00970 }
|
|
Definition at line 3804 of file chan_iax2.c. References aes_decrypt(), ast_log(), and LOG_WARNING. Referenced by decode_frame(). 03805 { 03806 #if 0 03807 /* Debug with "fake encryption" */ 03808 int x; 03809 if (len % 16) 03810 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03811 for (x=0;x<len;x++) 03812 dst[x] = src[x] ^ 0xff; 03813 #else 03814 unsigned char lastblock[16] = { 0 }; 03815 int x; 03816 while(len > 0) { 03817 aes_decrypt(src, dst, dcx); 03818 for (x=0;x<16;x++) 03819 dst[x] ^= lastblock[x]; 03820 memcpy(lastblock, src, sizeof(lastblock)); 03821 dst += 16; 03822 src += 16; 03823 len -= 16; 03824 } 03825 #endif 03826 }
|
|
Definition at line 3828 of file chan_iax2.c. References aes_encrypt(), ast_log(), and LOG_WARNING. Referenced by encrypt_frame(). 03829 { 03830 #if 0 03831 /* Debug with "fake encryption" */ 03832 int x; 03833 if (len % 16) 03834 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03835 for (x=0;x<len;x++) 03836 dst[x] = src[x] ^ 0xff; 03837 #else 03838 unsigned char curblock[16] = { 0 }; 03839 int x; 03840 while(len > 0) { 03841 for (x=0;x<16;x++) 03842 curblock[x] ^= src[x]; 03843 aes_encrypt(curblock, dst, ecx); 03844 memcpy(curblock, dst, sizeof(curblock)); 03845 dst += 16; 03846 src += 16; 03847 len -= 16; 03848 } 03849 #endif 03850 }
|
|
Definition at line 4946 of file chan_iax2.c. References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128. Referenced by authenticate_reply(), and socket_read(). 04947 { 04948 /* Select exactly one common encryption if there are any */ 04949 p->encmethods &= enc; 04950 if (p->encmethods) { 04951 if (p->encmethods & IAX_ENCRYPT_AES128) 04952 p->encmethods = IAX_ENCRYPT_AES128; 04953 else 04954 p->encmethods = 0; 04955 } 04956 }
|
|
Definition at line 8017 of file chan_iax2.c. References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_runq(), ast_sched_wait(), attempt_transmit(), iax_frame::callno, ast_iax2_queue::count, ast_iax2_queue::head, iax_frame_free(), iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::prev, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, ast_iax2_queue::tail, timing_read(), and timingfd. Referenced by start_network_thread(). 08018 { 08019 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08020 from the network, and queue them for delivery to the channels */ 08021 int res, count; 08022 struct iax_frame *f, *freeme; 08023 if (timingfd > -1) 08024 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08025 for(;;) { 08026 /* Go through the queue, sending messages which have not yet been 08027 sent, and scheduling retransmissions if appropriate */ 08028 ast_mutex_lock(&iaxq.lock); 08029 f = iaxq.head; 08030 count = 0; 08031 while(f) { 08032 freeme = NULL; 08033 if (!f->sentyet) { 08034 f->sentyet++; 08035 /* Send a copy immediately -- errors here are ok, so don't bother locking */ 08036 if (iaxs[f->callno]) { 08037 send_packet(f); 08038 count++; 08039 } 08040 if (f->retries < 0) { 08041 /* This is not supposed to be retransmitted */ 08042 if (f->prev) 08043 f->prev->next = f->next; 08044 else 08045 iaxq.head = f->next; 08046 if (f->next) 08047 f->next->prev = f->prev; 08048 else 08049 iaxq.tail = f->prev; 08050 iaxq.count--; 08051 /* Free the iax frame */ 08052 freeme = f; 08053 } else { 08054 /* We need reliable delivery. Schedule a retransmission */ 08055 f->retries++; 08056 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 08057 } 08058 } 08059 f = f->next; 08060 if (freeme) 08061 iax_frame_free(freeme); 08062 } 08063 ast_mutex_unlock(&iaxq.lock); 08064 if (count >= 20) 08065 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08066 08067 /* Now do the IO, and run scheduled tasks */ 08068 res = ast_sched_wait(sched); 08069 if ((res > 1000) || (res < 0)) 08070 res = 1000; 08071 res = ast_io_wait(io, res); 08072 if (res >= 0) { 08073 if (res >= 20) 08074 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08075 count = ast_sched_runq(sched); 08076 if (count >= 20) 08077 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08078 } 08079 } 08080 return NULL; 08081 }
|
|
Definition at line 898 of file chan_iax2.c. References jb_new(), jb_setconf(), malloc, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, maxjitterbuffer, maxjitterinterps, jb_conf::resync_threshold, and resyncthreshold. Referenced by find_callno(). 00899 { 00900 struct chan_iax2_pvt *tmp; 00901 tmp = malloc(sizeof(struct chan_iax2_pvt)); 00902 if (tmp) { 00903 memset(tmp, 0, sizeof(struct chan_iax2_pvt)); 00904 tmp->prefs = prefs; 00905 tmp->callno = 0; 00906 tmp->peercallno = 0; 00907 tmp->transfercallno = 0; 00908 tmp->bridgecallno = 0; 00909 tmp->pingid = -1; 00910 tmp->lagid = -1; 00911 tmp->autoid = -1; 00912 tmp->authid = -1; 00913 tmp->initid = -1; 00914 /* ast_copy_string(tmp->context, context, sizeof(tmp->context)); */ 00915 ast_copy_string(tmp->exten, "s", sizeof(tmp->exten)); 00916 ast_copy_string(tmp->host, host, sizeof(tmp->host)); 00917 #ifdef NEWJB 00918 { 00919 jb_conf jbconf; 00920 00921 tmp->jb = jb_new(); 00922 tmp->jbid = -1; 00923 jbconf.max_jitterbuf = maxjitterbuffer; 00924 jbconf.resync_threshold = resyncthreshold; 00925 jbconf.max_contig_interp = maxjitterinterps; 00926 jb_setconf(tmp->jb,&jbconf); 00927 } 00928 #endif 00929 } 00930 return tmp; 00931 }
|
|
Parses an IAX dial string into its component parts.
Definition at line 2913 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(). 02914 { 02915 if (ast_strlen_zero(data)) 02916 return; 02917 02918 pds->peer = strsep(&data, "/"); 02919 pds->exten = strsep(&data, "/"); 02920 pds->options = data; 02921 02922 if (pds->exten) { 02923 data = pds->exten; 02924 pds->exten = strsep(&data, "@"); 02925 pds->context = data; 02926 } 02927 02928 if (strchr(pds->peer, '@')) { 02929 data = pds->peer; 02930 pds->username = strsep(&data, "@"); 02931 pds->peer = data; 02932 } 02933 02934 if (pds->username) { 02935 data = pds->username; 02936 pds->username = strsep(&data, ":"); 02937 pds->password = data; 02938 } 02939 02940 data = pds->peer; 02941 pds->peer = strsep(&data, ":"); 02942 pds->port = data; 02943 02944 /* check for a key name wrapped in [] in the secret position, if found, 02945 move it to the key field instead 02946 */ 02947 if (pds->password && (pds->password[0] == '[')) { 02948 pds->key = ast_strip_quoted(pds->password, "[", "]"); 02949 pds->password = NULL; 02950 } 02951 }
|
|
Definition at line 8142 of file chan_iax2.c. References ast_get_ip(), ast_log(), ast_netsock_find(), ast_netsock_sockfd(), ast_strdupa, check_srcaddr(), defaultsockfd, IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, iax2_peer::sockfd, and strsep(). Referenced by build_peer(). 08143 { 08144 struct sockaddr_in sin; 08145 int nonlocal = 1; 08146 int port = IAX_DEFAULT_PORTNO; 08147 int sockfd = defaultsockfd; 08148 char *tmp; 08149 char *addr; 08150 char *portstr; 08151 08152 tmp = ast_strdupa(srcaddr); 08153 if (!tmp) { 08154 ast_log(LOG_WARNING, "Out of memory!\n"); 08155 return -1; 08156 } 08157 08158 addr = strsep(&tmp, ":"); 08159 portstr = tmp; 08160 08161 if (portstr) { 08162 port = atoi(portstr); 08163 if (port < 1) 08164 port = IAX_DEFAULT_PORTNO; 08165 } 08166 08167 if (!ast_get_ip(&sin, addr)) { 08168 struct ast_netsock *sock; 08169 int res; 08170 08171 sin.sin_port = 0; 08172 sin.sin_family = AF_INET; 08173 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08174 if (res == 0) { 08175 /* ip address valid. */ 08176 sin.sin_port = htons(port); 08177 sock = ast_netsock_find(netsock, &sin); 08178 if (sock) { 08179 sockfd = ast_netsock_sockfd(sock); 08180 nonlocal = 0; 08181 } 08182 } 08183 } 08184 08185 peer->sockfd = sockfd; 08186 08187 if (nonlocal) { 08188 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08189 srcaddr, peer->name); 08190 return -1; 08191 } else { 08192 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08193 return 0; 08194 } 08195 }
|
|
peer_status: Report Peer status in character string
Definition at line 1923 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(). 01924 { 01925 int res = 0; 01926 if (peer->maxms) { 01927 if (peer->lastms < 0) { 01928 ast_copy_string(status, "UNREACHABLE", statuslen); 01929 } else if (peer->lastms > peer->maxms) { 01930 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 01931 res = 1; 01932 } else if (peer->lastms) { 01933 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 01934 res = 1; 01935 } else { 01936 ast_copy_string(status, "UNKNOWN", statuslen); 01937 } 01938 } else { 01939 ast_copy_string(status, "Unmonitored", statuslen); 01940 res = -1; 01941 } 01942 return res; 01943 }
|
|
Definition at line 2189 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers. Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module(). 02190 { 02191 /* Prune peers who still are supposed to be deleted */ 02192 struct oh323_peer *peer, *peerlast, *peernext; 02193 ast_mutex_lock(&peerl.lock); 02194 peerlast = NULL; 02195 for (peer=peerl.peers;peer;) { 02196 peernext = peer->next; 02197 if (peer->delme) { 02198 free(peer); 02199 if (peerlast) { 02200 peerlast->next = peernext; 02201 } else { 02202 peerl.peers = peernext; 02203 } 02204 } else { 02205 peerlast = peer; 02206 } 02207 peer = peernext; 02208 } 02209 ast_mutex_unlock(&peerl.lock); 02210 }
|
|
Definition at line 8598 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_user(), IAX_DELME, ast_user_list::lock, iax2_user::next, user, userl, and ast_user_list::users. 08599 { 08600 struct iax2_user *user, *usernext, *userlast = NULL; 08601 ast_mutex_lock(&userl.lock); 08602 for (user=userl.users;user;) { 08603 usernext = user->next; 08604 if (ast_test_flag(user, IAX_DELME)) { 08605 destroy_user(user); 08606 if (userlast) 08607 userlast->next = usernext; 08608 else 08609 userl.users = usernext; 08610 } else 08611 userlast = user; 08612 user = usernext; 08613 } 08614 ast_mutex_unlock(&userl.lock); 08615 }
|
|
Definition at line 4925 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(), iaxdebug, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type. Referenced by socket_read(). 04926 { 04927 struct ast_iax2_full_hdr fh; 04928 char iabuf[INET_ADDRSTRLEN]; 04929 fh.scallno = htons(src | IAX_FLAG_FULL); 04930 fh.dcallno = htons(dst); 04931 fh.ts = 0; 04932 fh.oseqno = 0; 04933 fh.iseqno = 0; 04934 fh.type = AST_FRAME_IAX; 04935 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 04936 if (iaxdebug) 04937 iax_showframe(NULL, &fh, 0, sin, 0); 04938 #if 0 04939 if (option_debug) 04940 #endif 04941 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 04942 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst); 04943 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 04944 }
|
|
Definition at line 2595 of file chan_iax2.c. References iax2_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), destroy_peer(), expire_registry(), global_rtautoclear, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, reg_source_db(), ast_variable::value, and var. Referenced by authenticate_reply(), find_peer(), and iax2_getpeername(). 02596 { 02597 struct ast_variable *var; 02598 struct ast_variable *tmp; 02599 struct iax2_peer *peer=NULL; 02600 time_t regseconds, nowtime; 02601 int dynamic=0; 02602 02603 if (peername) 02604 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02605 else { 02606 char iabuf[INET_ADDRSTRLEN]; 02607 char porta[25]; 02608 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 02609 sprintf(porta, "%d", ntohs(sin->sin_port)); 02610 var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL); 02611 if (var) { 02612 /* We'll need the peer name in order to build the structure! */ 02613 tmp = var; 02614 while(tmp) { 02615 if (!strcasecmp(tmp->name, "name")) 02616 peername = tmp->value; 02617 tmp = tmp->next; 02618 } 02619 } 02620 } 02621 if (!var) 02622 return NULL; 02623 02624 peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02625 02626 if (!peer) 02627 return NULL; 02628 02629 tmp = var; 02630 while(tmp) { 02631 /* Make sure it's not a user only... */ 02632 if (!strcasecmp(tmp->name, "type")) { 02633 if (strcasecmp(tmp->value, "friend") && 02634 strcasecmp(tmp->value, "peer")) { 02635 /* Whoops, we weren't supposed to exist! */ 02636 destroy_peer(peer); 02637 peer = NULL; 02638 break; 02639 } 02640 } else if (!strcasecmp(tmp->name, "regseconds")) { 02641 if (sscanf(tmp->value, "%ld", (time_t *)®seconds) != 1) 02642 regseconds = 0; 02643 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02644 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02645 } else if (!strcasecmp(tmp->name, "port")) { 02646 peer->addr.sin_port = htons(atoi(tmp->value)); 02647 } else if (!strcasecmp(tmp->name, "host")) { 02648 if (!strcasecmp(tmp->value, "dynamic")) 02649 dynamic = 1; 02650 } 02651 tmp = tmp->next; 02652 } 02653 if (!peer) 02654 return NULL; 02655 02656 ast_variables_destroy(var); 02657 02658 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02659 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02660 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02661 if (peer->expire > -1) 02662 ast_sched_del(sched, peer->expire); 02663 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer); 02664 } 02665 ast_mutex_lock(&peerl.lock); 02666 peer->next = peerl.peers; 02667 peerl.peers = peer; 02668 ast_mutex_unlock(&peerl.lock); 02669 if (ast_test_flag(peer, IAX_DYNAMIC)) 02670 reg_source_db(peer); 02671 } else { 02672 ast_set_flag(peer, IAX_TEMPONLY); 02673 } 02674 02675 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02676 time(&nowtime); 02677 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02678 memset(&peer->addr, 0, sizeof(peer->addr)); 02679 if (option_debug) 02680 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02681 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02682 } 02683 else { 02684 if (option_debug) 02685 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02686 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02687 } 02688 } 02689 02690 return peer; 02691 }
|
|
Definition at line 2734 of file chan_iax2.c. References ast_inet_ntoa(), ast_update_realtime(), and ipaddr. Referenced by update_peer(), and update_registry(). 02735 { 02736 char port[10]; 02737 char ipaddr[20]; 02738 char regseconds[20]; 02739 time_t nowtime; 02740 02741 time(&nowtime); 02742 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); 02743 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 02744 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02745 ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL); 02746 }
|
|
Definition at line 2693 of file chan_iax2.c. References ast_load_realtime(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_user_list::lock, ast_variable::name, ast_variable::next, user, userl, ast_user_list::users, ast_variable::value, and var. Referenced by check_access(), and find_user(). 02694 { 02695 struct ast_variable *var; 02696 struct ast_variable *tmp; 02697 struct iax2_user *user=NULL; 02698 02699 var = ast_load_realtime("iaxusers", "name", username, NULL); 02700 if (!var) 02701 return NULL; 02702 02703 tmp = var; 02704 while(tmp) { 02705 /* Make sure it's not a peer only... */ 02706 if (!strcasecmp(tmp->name, "type")) { 02707 if (strcasecmp(tmp->value, "friend") && 02708 strcasecmp(tmp->value, "user")) { 02709 return NULL; 02710 } 02711 } 02712 tmp = tmp->next; 02713 } 02714 02715 user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02716 if (!user) 02717 return NULL; 02718 02719 ast_variables_destroy(var); 02720 02721 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02722 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02723 ast_mutex_lock(&userl.lock); 02724 user->next = userl.users; 02725 userl.users = user; 02726 ast_mutex_unlock(&userl.lock); 02727 } else { 02728 ast_set_flag(user, IAX_TEMPONLY); 02729 } 02730 02731 return user; 02732 }
|
|
Definition at line 5667 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, iax2_peer::name, option_verbose, register_peer_exten(), and VERBOSE_PREFIX_3. Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer(). 05668 { 05669 char data[80]; 05670 struct in_addr in; 05671 char iabuf[INET_ADDRSTRLEN]; 05672 char *c, *d; 05673 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05674 c = strchr(data, ':'); 05675 if (c) { 05676 *c = '\0'; 05677 c++; 05678 if (inet_aton(data, &in)) { 05679 d = strchr(c, ':'); 05680 if (d) { 05681 *d = '\0'; 05682 d++; 05683 if (option_verbose > 2) 05684 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05685 ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); 05686 iax2_poke_peer(p, 0); 05687 p->expiry = atoi(d); 05688 memset(&p->addr, 0, sizeof(p->addr)); 05689 p->addr.sin_family = AF_INET; 05690 p->addr.sin_addr = in; 05691 p->addr.sin_port = htons(atoi(c)); 05692 if (p->expire > -1) 05693 ast_sched_del(sched, p->expire); 05694 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05695 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05696 if (iax2_regfunk) 05697 iax2_regfunk(p->name, 1); 05698 register_peer_exten(p, 1); 05699 } 05700 05701 } 05702 } 05703 } 05704 }
|
|
Definition at line 5620 of file chan_iax2.c. References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_strlen_zero(), channeltype, free, iax2_peer::name, regcontext, iax2_peer::regexten, strdup, and strsep(). Referenced by destroy_peer(), expire_register(), expire_registry(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry(). 05621 { 05622 char multi[256]; 05623 char *stringp, *ext; 05624 if (!ast_strlen_zero(regcontext)) { 05625 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 05626 stringp = multi; 05627 while((ext = strsep(&stringp, "&"))) { 05628 if (onoff) { 05629 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05630 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype); 05631 } else 05632 ast_context_remove_extension(regcontext, ext, 1, NULL); 05633 } 05634 } 05635 }
|
|
Verify inbound registration.
Definition at line 5086 of file chan_iax2.c. References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_device_state_changed(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, authdebug, iax2_peer::authmethods, destroy_peer(), chan_iax2_pvt::expiry, expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxsl, chan_iax2_pvt::inkeys, iax2_peer::inkeys, key(), LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, chan_iax2_pvt::peer, iax_ies::refresh, iax_ies::rsa_result, chan_iax2_pvt::secret, iax2_peer::secret, secret, strsep(), and iax_ies::username. Referenced by handle_request_register(), and socket_read(). 05087 { 05088 char requeststr[256] = ""; 05089 char peer[256] = ""; 05090 char md5secret[256] = ""; 05091 char rsasecret[256] = ""; 05092 char secret[256] = ""; 05093 char iabuf[INET_ADDRSTRLEN]; 05094 struct iax2_peer *p; 05095 struct ast_key *key; 05096 char *keyn; 05097 int x; 05098 int expire = 0; 05099 05100 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05101 iaxs[callno]->peer[0] = '\0'; 05102 if (ies->username) 05103 ast_copy_string(peer, ies->username, sizeof(peer)); 05104 if (ies->password) 05105 ast_copy_string(secret, ies->password, sizeof(secret)); 05106 if (ies->md5_result) 05107 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05108 if (ies->rsa_result) 05109 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05110 if (ies->refresh) 05111 expire = ies->refresh; 05112 05113 if (ast_strlen_zero(peer)) { 05114 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05115 return -1; 05116 } 05117 /* We release the lock for the call to prevent a deadlock, but it's okay because 05118 only the current thread could possibly make it go away or make changes */ 05119 ast_mutex_unlock(&iaxsl[callno]); 05120 /* SLD: first call to lookup peer during registration */ 05121 p = find_peer(peer, 1); 05122 ast_mutex_lock(&iaxsl[callno]); 05123 05124 if (!p) { 05125 if (authdebug) 05126 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05127 return -1; 05128 } 05129 05130 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05131 if (authdebug) 05132 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05133 if (ast_test_flag(p, IAX_TEMPONLY)) 05134 destroy_peer(p); 05135 return -1; 05136 } 05137 05138 if (!ast_apply_ha(p->ha, sin)) { 05139 if (authdebug) 05140 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); 05141 if (ast_test_flag(p, IAX_TEMPONLY)) 05142 destroy_peer(p); 05143 return -1; 05144 } 05145 ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret)); 05146 ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys)); 05147 /* Check secret against what we have on file */ 05148 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05149 if (!ast_strlen_zero(p->inkeys)) { 05150 char tmpkeys[256]; 05151 char *stringp=NULL; 05152 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05153 stringp=tmpkeys; 05154 keyn = strsep(&stringp, ":"); 05155 while(keyn) { 05156 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05157 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05158 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05159 break; 05160 } else if (!key) 05161 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05162 keyn = strsep(&stringp, ":"); 05163 } 05164 if (!keyn) { 05165 if (authdebug) 05166 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05167 if (ast_test_flag(p, IAX_TEMPONLY)) 05168 destroy_peer(p); 05169 return -1; 05170 } 05171 } else { 05172 if (authdebug) 05173 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05174 if (ast_test_flag(p, IAX_TEMPONLY)) 05175 destroy_peer(p); 05176 return -1; 05177 } 05178 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05179 /* They've provided a plain text password and we support that */ 05180 if (strcmp(secret, p->secret)) { 05181 if (authdebug) 05182 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); 05183 if (ast_test_flag(p, IAX_TEMPONLY)) 05184 destroy_peer(p); 05185 return -1; 05186 } else 05187 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05188 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05189 struct MD5Context md5; 05190 unsigned char digest[16]; 05191 char *tmppw, *stringp; 05192 05193 tmppw = ast_strdupa(p->secret); 05194 stringp = tmppw; 05195 while((tmppw = strsep(&stringp, ";"))) { 05196 MD5Init(&md5); 05197 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05198 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05199 MD5Final(digest, &md5); 05200 for (x=0;x<16;x++) 05201 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05202 if (!strcasecmp(requeststr, md5secret)) 05203 break; 05204 } 05205 if (tmppw) { 05206 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05207 } else { 05208 if (authdebug) 05209 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name, requeststr, md5secret); 05210 if (ast_test_flag(p, IAX_TEMPONLY)) 05211 destroy_peer(p); 05212 return -1; 05213 } 05214 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05215 if (authdebug) 05216 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05217 if (ast_test_flag(p, IAX_TEMPONLY)) 05218 destroy_peer(p); 05219 return -1; 05220 } 05221 ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer)); 05222 /* Choose lowest expiry number */ 05223 if (expire && (expire < iaxs[callno]->expiry)) 05224 iaxs[callno]->expiry = expire; 05225 05226 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05227 05228 if (ast_test_flag(p, IAX_TEMPONLY)) 05229 destroy_peer(p); 05230 return 0; 05231 05232 }
|
|
Definition at line 5808 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), 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, LOG_WARNING, and send_command(). Referenced by socket_read(). 05809 { 05810 struct iax_ie_data ied; 05811 struct iax2_peer *p; 05812 /* SLD: third call to find_peer in registration */ 05813 p = find_peer(name, 1); 05814 if (p) { 05815 memset(&ied, 0, sizeof(ied)); 05816 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05817 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 05818 /* Build the challenge */ 05819 snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand()); 05820 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 05821 } 05822 iax_ie_append_str(&ied, IAX_IE_USERNAME, name); 05823 if (ast_test_flag(p, IAX_TEMPONLY)) 05824 destroy_peer(p); 05825 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 05826 } 05827 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05828 return 0; 05829 }
|
|
Definition at line 5831 of file chan_iax2.c. References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username. Referenced by socket_read(). 05832 { 05833 struct iax2_registry *reg; 05834 /* Start pessimistic */ 05835 struct iax_ie_data ied; 05836 char peer[256] = ""; 05837 char iabuf[INET_ADDRSTRLEN]; 05838 char challenge[256] = ""; 05839 int res; 05840 int authmethods = 0; 05841 if (ies->authmethods) 05842 authmethods = ies->authmethods; 05843 if (ies->username) 05844 ast_copy_string(peer, ies->username, sizeof(peer)); 05845 if (ies->challenge) 05846 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 05847 memset(&ied, 0, sizeof(ied)); 05848 reg = iaxs[callno]->reg; 05849 if (reg) { 05850 if (inaddrcmp(®->addr, sin)) { 05851 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05852 return -1; 05853 } 05854 if (ast_strlen_zero(reg->secret)) { 05855 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 05856 reg->regstate = REG_STATE_NOAUTH; 05857 return -1; 05858 } 05859 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 05860 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 05861 if (reg->secret[0] == '[') { 05862 char tmpkey[256]; 05863 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 05864 tmpkey[strlen(tmpkey) - 1] = '\0'; 05865 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 05866 } else 05867 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 05868 if (!res) { 05869 reg->regstate = REG_STATE_AUTHSENT; 05870 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 05871 } else 05872 return -1; 05873 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 05874 } else 05875 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 05876 return -1; 05877 }
|
|
Definition at line 4353 of file chan_iax2.c. References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED. Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry(). 04354 { 04355 switch(regstate) { 04356 case REG_STATE_UNREGISTERED: 04357 return "Unregistered"; 04358 case REG_STATE_REGSENT: 04359 return "Request Sent"; 04360 case REG_STATE_AUTHSENT: 04361 return "Auth. Sent"; 04362 case REG_STATE_REGISTERED: 04363 return "Registered"; 04364 case REG_STATE_REJECTED: 04365 return "Rejected"; 04366 case REG_STATE_TIMEOUT: 04367 return "Timeout"; 04368 case REG_STATE_NOAUTH: 04369 return "No Authentication"; 04370 default: 04371 return "Unknown"; 04372 } 04373 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 8969 of file chan_iax2.c. References reload_config(). 08970 { 08971 return reload_config(); 08972 }
|
|
Definition at line 1998 of file chan_h323.c. References ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, IPTOS_MINCOST, ast_variable::lineno, ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, secret, tos, update_common_options(), user, userbyalias, userl, ast_user_list::users, usingGk, ast_variable::value, and VERBOSE_PREFIX_2. Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), and reload(). 01999 { 02000 int format; 02001 struct ast_config *cfg; 02002 struct ast_variable *v; 02003 struct oh323_peer *peer = NULL; 02004 struct oh323_user *user = NULL; 02005 struct oh323_alias *alias = NULL; 02006 struct ast_hostent ahp; struct hostent *hp; 02007 char *cat; 02008 char *utype; 02009 02010 cfg = ast_config_load(config); 02011 02012 /* We *must* have a config file otherwise stop immediately */ 02013 if (!cfg) { 02014 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02015 return 1; 02016 } 02017 02018 /* fire up the H.323 Endpoint */ 02019 if (!h323_end_point_exist()) { 02020 h323_end_point_create(); 02021 } 02022 h323debug = 0; 02023 memset(&bindaddr, 0, sizeof(bindaddr)); 02024 memset(&global_options, 0, sizeof(global_options)); 02025 global_options.dtmfcodec = 101; 02026 global_options.dtmfmode = H323_DTMF_RFC2833; 02027 global_options.capability = ~0; /* All capabilities */ 02028 global_options.bridge = 1; /* Do native bridging by default */ 02029 v = ast_variable_browse(cfg, "general"); 02030 while(v) { 02031 /* Create the interface list */ 02032 if (!strcasecmp(v->name, "port")) { 02033 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02034 } else if (!strcasecmp(v->name, "bindaddr")) { 02035 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02036 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02037 } else { 02038 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02039 } 02040 } else if (!strcasecmp(v->name, "tos")) { 02041 if (sscanf(v->value, "%d", &format)) { 02042 tos = format & 0xff; 02043 } else if (!strcasecmp(v->value, "lowdelay")) { 02044 tos = IPTOS_LOWDELAY; 02045 } else if (!strcasecmp(v->value, "throughput")) { 02046 tos = IPTOS_THROUGHPUT; 02047 } else if (!strcasecmp(v->value, "reliability")) { 02048 tos = IPTOS_RELIABILITY; 02049 } else if (!strcasecmp(v->value, "mincost")) { 02050 tos = IPTOS_MINCOST; 02051 } else if (!strcasecmp(v->value, "none")) { 02052 tos = 0; 02053 } else { 02054 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02055 } 02056 } else if (!strcasecmp(v->name, "gatekeeper")) { 02057 if (!strcasecmp(v->value, "DISABLE")) { 02058 gatekeeper_disable = 1; 02059 usingGk = 0; 02060 } else if (!strcasecmp(v->value, "DISCOVER")) { 02061 gatekeeper_disable = 0; 02062 gatekeeper_discover = 1; 02063 usingGk = 1; 02064 } else { 02065 gatekeeper_disable = 0; 02066 usingGk = 1; 02067 strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1); 02068 } 02069 } else if (!strcasecmp(v->name, "secret")) { 02070 strncpy(secret, v->value, sizeof(secret) - 1); 02071 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02072 gkroute = ast_true(v->value); 02073 } else if (!strcasecmp(v->name, "context")) { 02074 strncpy(default_context, v->value, sizeof(default_context) - 1); 02075 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02076 } else if (!strcasecmp(v->name, "UserByAlias")) { 02077 userbyalias = ast_true(v->value); 02078 } else if (!update_common_options(v, &global_options)) { 02079 /* dummy */ 02080 } 02081 v = v->next; 02082 } 02083 02084 cat = ast_category_browse(cfg, NULL); 02085 while(cat) { 02086 if (strcasecmp(cat, "general")) { 02087 utype = ast_variable_retrieve(cfg, cat, "type"); 02088 if (utype) { 02089 if (!strcasecmp(utype, "user")) { 02090 user = build_user(cat, ast_variable_browse(cfg, cat)); 02091 if (user) { 02092 ast_mutex_lock(&userl.lock); 02093 user->next = userl.users; 02094 userl.users = user; 02095 ast_mutex_unlock(&userl.lock); 02096 } 02097 } else if (!strcasecmp(utype, "peer")) { 02098 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02099 if (peer) { 02100 ast_mutex_lock(&peerl.lock); 02101 peer->next = peerl.peers; 02102 peerl.peers = peer; 02103 ast_mutex_unlock(&peerl.lock); 02104 } 02105 } else if (!strcasecmp(utype, "friend")) { 02106 user = build_user(cat, ast_variable_browse(cfg, cat)); 02107 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02108 if (user) { 02109 ast_mutex_lock(&userl.lock); 02110 user->next = userl.users; 02111 userl.users = user; 02112 ast_mutex_unlock(&userl.lock); 02113 } 02114 if (peer) { 02115 ast_mutex_lock(&peerl.lock); 02116 peer->next = peerl.peers; 02117 peerl.peers = peer; 02118 ast_mutex_unlock(&peerl.lock); 02119 } 02120 } else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) { 02121 alias = build_alias(cat, ast_variable_browse(cfg, cat)); 02122 if (alias) { 02123 ast_mutex_lock(&aliasl.lock); 02124 alias->next = aliasl.aliases; 02125 aliasl.aliases = alias; 02126 ast_mutex_unlock(&aliasl.lock); 02127 } 02128 } else { 02129 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02130 } 02131 } else { 02132 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02133 } 02134 } 02135 cat = ast_category_browse(cfg, cat); 02136 } 02137 ast_config_destroy(cfg); 02138 02139 /* Register our H.323 aliases if any*/ 02140 while (alias) { 02141 if (h323_set_alias(alias)) { 02142 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02143 return -1; 02144 } 02145 alias = alias->next; 02146 } 02147 02148 return 0; 02149 }
|
|
Definition at line 1362 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(). 01363 { 01364 struct iax_firmware *cur, *curl, *curp; 01365 DIR *fwd; 01366 struct dirent *de; 01367 char dir[256]; 01368 char fn[256]; 01369 /* Mark all as dead */ 01370 ast_mutex_lock(&waresl.lock); 01371 cur = waresl.wares; 01372 while(cur) { 01373 cur->dead = 1; 01374 cur = cur->next; 01375 } 01376 /* Now that we've freed them, load the new ones */ 01377 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01378 fwd = opendir(dir); 01379 if (fwd) { 01380 while((de = readdir(fwd))) { 01381 if (de->d_name[0] != '.') { 01382 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01383 if (!try_firmware(fn)) { 01384 if (option_verbose > 1) 01385 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01386 } 01387 } 01388 } 01389 closedir(fwd); 01390 } else 01391 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01392 01393 /* Clean up leftovers */ 01394 cur = waresl.wares; 01395 curp = NULL; 01396 while(cur) { 01397 curl = cur; 01398 cur = cur->next; 01399 if (curl->dead) { 01400 if (curp) { 01401 curp->next = cur; 01402 } else { 01403 waresl.wares = cur; 01404 } 01405 destroy_firmware(curl); 01406 } else { 01407 curp = cur; 01408 } 01409 } 01410 ast_mutex_unlock(&waresl.lock); 01411 }
|
|
Definition at line 6322 of file chan_iax2.c. References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts. Referenced by socket_read(). 06323 { 06324 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06325 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06326 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06327 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06328 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06329 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06330 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06331 }
|
|
Definition at line 2268 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_add(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, GAMMA, iax2_dropcount, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxdebug, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, jittershrinkrate, chan_iax2_pvt::last, match(), max_jitter_buffer, maxjitterbuffer, MEMORY_SIZE, min_jitter_buffer, iax_frame::retrans, chan_iax2_pvt::rxcore, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, unwrap_timestamp(), and update_jbsched(). Referenced by socket_read(). 02269 { 02270 #ifdef NEWJB 02271 int type, len; 02272 int ret; 02273 int needfree = 0; 02274 #else 02275 int x; 02276 int ms; 02277 int delay; 02278 unsigned int orig_ts; 02279 int drops[MEMORY_SIZE]; 02280 int min, max=0, prevjitterbuffer, maxone=0,y,z, match; 02281 02282 /* Remember current jitterbuffer so we can log any change */ 02283 prevjitterbuffer = iaxs[fr->callno]->jitterbuffer; 02284 /* Similarly for the frame timestamp */ 02285 orig_ts = fr->ts; 02286 #endif 02287 02288 #if 0 02289 if (option_debug && iaxdebug) 02290 ast_log(LOG_DEBUG, "schedule_delivery: ts=%d, last=%d, update=%d\n", 02291 fr->ts, iaxs[fr->callno]->last, updatehistory); 02292 #endif 02293 02294 /* Attempt to recover wrapped timestamps */ 02295 unwrap_timestamp(fr); 02296 02297 if (updatehistory) { 02298 #ifndef NEWJB 02299 02300 /* Attempt to spot a change of timebase on timestamps coming from the other side 02301 We detect by noticing a jump in consecutive timestamps that can't reasonably be explained 02302 by network jitter or reordering. Sometimes, also, the peer stops sending us frames 02303 for a while - in this case this code might also resync us. But that's not a bad thing. 02304 Be careful of non-voice frames which are timestamped differently (especially ACKS!) 02305 [that's why we only do this when updatehistory is true] 02306 */ 02307 x = fr->ts - iaxs[fr->callno]->last; 02308 if (x > TS_GAP_FOR_JB_RESYNC || x < -TS_GAP_FOR_JB_RESYNC) { 02309 if (option_debug && iaxdebug) 02310 ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped. resyncing rxcore (ts=%d, last=%d)\n", 02311 fr->callno, fr->ts, iaxs[fr->callno]->last); 02312 /* zap rxcore - calc_rxstamp will make a new one based on this frame */ 02313 iaxs[fr->callno]->rxcore = ast_tv(0, 0); 02314 /* wipe "last" if stamps have jumped backwards */ 02315 if (x<0) 02316 iaxs[fr->callno]->last = 0; 02317 /* should we also empty history? */ 02318 } 02319 /* ms is a measure of the "lateness" of the frame relative to the "reference" 02320 frame we received. (initially the very first, but also see code just above here). 02321 Understand that "ms" can easily be -ve if lag improves since the reference frame. 02322 Called by IAX thread, with iaxsl lock held. */ 02323 ms = calc_rxstamp(iaxs[fr->callno], fr->ts) - fr->ts; 02324 02325 /* Rotate our history queue of "lateness". Don't worry about those initial 02326 zeros because the first entry will always be zero */ 02327 for (x=0;x<MEMORY_SIZE - 1;x++) 02328 iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1]; 02329 /* Add a history entry for this one */ 02330 iaxs[fr->callno]->history[x] = ms; 02331 #endif 02332 } 02333 #ifndef NEWJB 02334 else 02335 ms = 0; 02336 #endif 02337 02338 02339 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02340 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02341 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02342 else { 02343 #if 0 02344 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02345 #endif 02346 fr->af.delivery = ast_tv(0,0); 02347 } 02348 02349 #ifndef NEWJB 02350 /* Initialize the minimum to reasonable values. It's too much 02351 work to do the same for the maximum, repeatedly */ 02352 min=iaxs[fr->callno]->history[0]; 02353 for (z=0;z < iax2_dropcount + 1;z++) { 02354 /* Start very optimistic ;-) */ 02355 max=-999999999; 02356 for (x=0;x<MEMORY_SIZE;x++) { 02357 if (max < iaxs[fr->callno]->history[x]) { 02358 /* We have a candidate new maximum value. Make 02359 sure it's not in our drop list */ 02360 match = 0; 02361 for (y=0;!match && (y<z);y++) 02362 match |= (drops[y] == x); 02363 if (!match) { 02364 /* It's not in our list, use it as the new maximum */ 02365 max = iaxs[fr->callno]->history[x]; 02366 maxone = x; 02367 } 02368 02369 } 02370 if (!z) { 02371 /* On our first pass, find the minimum too */ 02372 if (min > iaxs[fr->callno]->history[x]) 02373 min = iaxs[fr->callno]->history[x]; 02374 } 02375 } 02376 #if 1 02377 drops[z] = maxone; 02378 #endif 02379 } 02380 #endif 02381 02382 #ifdef NEWJB 02383 type = JB_TYPE_CONTROL; 02384 len = 0; 02385 02386 if(fr->af.frametype == AST_FRAME_VOICE) { 02387 type = JB_TYPE_VOICE; 02388 len = ast_codec_get_samples(&fr->af) / 8; 02389 } else if(fr->af.frametype == AST_FRAME_CNG) { 02390 type = JB_TYPE_SILENCE; 02391 } 02392 02393 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02394 if (tsout) 02395 *tsout = fr->ts; 02396 __do_deliver(fr); 02397 return -1; 02398 } 02399 02400 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02401 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02402 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02403 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02404 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02405 jb_frame frame; 02406 02407 /* deliver any frames in the jb */ 02408 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK) 02409 __do_deliver(frame.data); 02410 02411 jb_reset(iaxs[fr->callno]->jb); 02412 02413 if (iaxs[fr->callno]->jbid > -1) 02414 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02415 02416 iaxs[fr->callno]->jbid = -1; 02417 02418 /* deliver this frame now */ 02419 if (tsout) 02420 *tsout = fr->ts; 02421 __do_deliver(fr); 02422 return -1; 02423 02424 } 02425 02426 02427 /* insert into jitterbuffer */ 02428 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02429 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02430 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02431 if (ret == JB_DROP) { 02432 needfree++; 02433 } else if (ret == JB_SCHED) { 02434 update_jbsched(iaxs[fr->callno]); 02435 } 02436 #else 02437 /* Just for reference, keep the "jitter" value, the difference between the 02438 earliest and the latest. */ 02439 if (max >= min) 02440 iaxs[fr->callno]->jitter = max - min; 02441 02442 /* IIR filter for keeping track of historic jitter, but always increase 02443 historic jitter immediately for increase */ 02444 02445 if (iaxs[fr->callno]->jitter > iaxs[fr->callno]->historicjitter ) 02446 iaxs[fr->callno]->historicjitter = iaxs[fr->callno]->jitter; 02447 else 02448 iaxs[fr->callno]->historicjitter = GAMMA * (double)iaxs[fr->callno]->jitter + (1-GAMMA) * 02449 iaxs[fr->callno]->historicjitter; 02450 02451 /* If our jitter buffer is too big (by a significant margin), then we slowly 02452 shrink it to avoid letting the change be perceived */ 02453 if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer) 02454 iaxs[fr->callno]->jitterbuffer -= jittershrinkrate; 02455 02456 /* If our jitter buffer headroom is too small (by a significant margin), then we slowly enlarge it */ 02457 /* min_jitter_buffer should be SMALLER than max_jitter_buffer - leaving a "no mans land" 02458 in between - otherwise the jitterbuffer size will hunt up and down causing unnecessary 02459 disruption. Set maxexcessbuffer to say 150msec, minexcessbuffer to say 50 */ 02460 if (max > iaxs[fr->callno]->jitterbuffer - min_jitter_buffer) 02461 iaxs[fr->callno]->jitterbuffer += jittershrinkrate; 02462 02463 /* If our jitter buffer is smaller than our maximum delay, grow the jitter 02464 buffer immediately to accomodate it (and a little more). */ 02465 if (max > iaxs[fr->callno]->jitterbuffer) 02466 iaxs[fr->callno]->jitterbuffer = max 02467 /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */; 02468 02469 /* update "min", just for RRs and stats */ 02470 iaxs[fr->callno]->min = min; 02471 02472 /* Subtract the lateness from our jitter buffer to know how long to wait 02473 before sending our packet. */ 02474 delay = iaxs[fr->callno]->jitterbuffer - ms; 02475 02476 /* Whatever happens, no frame waits longer than maxjitterbuffer */ 02477 if (delay > maxjitterbuffer) 02478 delay = maxjitterbuffer; 02479 02480 /* If jitter buffer is disabled then just pretend the frame is "right on time" */ 02481 /* If frame came from trunk, also don't do any delay */ 02482 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) || fromtrunk ) 02483 delay = 0; 02484 02485 if (option_debug && iaxdebug) { 02486 /* Log jitter stats for possible offline analysis */ 02487 ast_log(LOG_DEBUG, "Jitter: call=%d ts=%d orig=%d last=%d %s: min=%d max=%d jb=%d %+d lateness=%d jbdelay=%d jitter=%d historic=%d\n", 02488 fr->callno, fr->ts, orig_ts, iaxs[fr->callno]->last, 02489 (fr->af.frametype == AST_FRAME_VOICE) ? "VOICE" : "CONTROL", 02490 min, max, iaxs[fr->callno]->jitterbuffer, 02491 iaxs[fr->callno]->jitterbuffer - prevjitterbuffer, 02492 ms, delay, 02493 iaxs[fr->callno]->jitter, iaxs[fr->callno]->historicjitter); 02494 } 02495 02496 if (delay < 1) { 02497 /* Don't deliver it more than 4 ms late */ 02498 if ((delay > -4) || (fr->af.frametype != AST_FRAME_VOICE)) { 02499 if (option_debug && iaxdebug) 02500 ast_log(LOG_DEBUG, "schedule_delivery: Delivering immediately (Calculated delay is %d)\n", delay); 02501 if (tsout) 02502 *tsout = fr->ts; 02503 __do_deliver(fr); 02504 return -1; 02505 } else { 02506 if (option_debug && iaxdebug) 02507 ast_log(LOG_DEBUG, "schedule_delivery: Dropping voice packet since %dms delay is too old\n", delay); 02508 iaxs[fr->callno]->frames_dropped++; 02509 needfree++; 02510 } 02511 } else { 02512 if (option_debug && iaxdebug) 02513 ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay); 02514 fr->retrans = ast_sched_add(sched, delay, do_deliver, fr); 02515 } 02516 #endif 02517 if (tsout) 02518 *tsout = fr->ts; 02519 if (needfree) { 02520 /* Free our iax frame */ 02521 iax2_frame_free(fr); 02522 return -1; 02523 } 02524 return 0; 02525 }
|
|
Definition at line 4678 of file chan_iax2.c. References __send_command(). Referenced by attempt_transmit(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), send_command_locked(), send_lagrq(), send_ping(), and socket_read(). 04679 { 04680 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04681 }
|
|
Definition at line 4699 of file chan_iax2.c. References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy_nolock(). Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_hangup(), socket_read(), and update_registry(). 04700 { 04701 /* It is assumed that the callno has already been locked */ 04702 iax2_predestroy_nolock(i->callno); 04703 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04704 }
|
|
Definition at line 4706 of file chan_iax2.c. References __send_command(). Referenced by iax2_vnak(), and socket_read(). 04707 { 04708 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04709 }
|
|
Definition at line 4683 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iaxsl, and send_command(). Referenced by iax2_answer(), iax2_digit(), iax2_indicate(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer(). 04684 { 04685 int res; 04686 ast_mutex_lock(&iaxsl[callno]); 04687 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04688 ast_mutex_unlock(&iaxsl[callno]); 04689 return res; 04690 }
|
|
Definition at line 4711 of file chan_iax2.c. References __send_command(). Referenced by socket_read(), and try_transfer(). 04712 { 04713 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04714 }
|
|
Definition at line 803 of file chan_iax2.c. References AST_FRAME_IAX, IAX_COMMAND_LAGRQ, and send_command(). Referenced by find_callno(), and make_trunk(). 00804 { 00805 int callno = (long)data; 00806 /* Ping only if it's real not if it's bridged */ 00807 if (iaxs[callno]) { 00808 #ifdef BRIDGE_OPTIMIZATION 00809 if (!iaxs[callno]->bridgecallno) 00810 #endif 00811 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 00812 return 1; 00813 } else 00814 return 0; 00815 }
|
|
Definition at line 1491 of file chan_iax2.c. References ast_inet_ntoa(), ast_log(), chan_iax2_pvt::callno, iax_frame::callno, handle_error(), iax_showframe(), iaxdebug, LOG_DEBUG, LOG_WARNING, option_debug, iax_frame::transfer, and iax_frame::ts. Referenced by attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit(). 01492 { 01493 int res; 01494 char iabuf[INET_ADDRSTRLEN]; 01495 /* Called with iaxsl held */ 01496 if (!iaxs[f->callno]) 01497 return -1; 01498 if (option_debug > 2 && iaxdebug) 01499 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port)); 01500 /* Don't send if there was an error, but return error instead */ 01501 if (!f->callno) { 01502 ast_log(LOG_WARNING, "Call number = %d\n", f->callno); 01503 return -1; 01504 } 01505 if (iaxs[f->callno]->error) 01506 return -1; 01507 if (f->transfer) { 01508 if (iaxdebug) 01509 iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01510 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer, 01511 sizeof(iaxs[f->callno]->transfer)); 01512 } else { 01513 if (iaxdebug) 01514 iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01515 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr, 01516 sizeof(iaxs[f->callno]->addr)); 01517 } 01518 if (res < 0) { 01519 if (option_debug && iaxdebug) 01520 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01521 handle_error(); 01522 } else 01523 res = 0; 01524 return res; 01525 }
|
|
Definition at line 777 of file chan_iax2.c. References AST_FRAME_IAX, IAX_COMMAND_PING, and send_command(). Referenced by find_callno(), and make_trunk(). 00778 { 00779 int callno = (long)data; 00780 /* Ping only if it's real, not if it's bridged */ 00781 if (iaxs[callno]) { 00782 #ifdef BRIDGE_OPTIMIZATION 00783 if (!iaxs[callno]->bridgecallno) 00784 #endif 00785 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00786 return 1; 00787 } else 00788 return 0; 00789 }
|
|
Definition at line 6001 of file chan_iax2.c. References iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax_frame::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, trunkfreq, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros. Referenced by timing_read(). 06002 { 06003 int res = 0; 06004 struct iax_frame *fr; 06005 struct ast_iax2_meta_hdr *meta; 06006 struct ast_iax2_meta_trunk_hdr *mth; 06007 int calls = 0; 06008 06009 /* Point to frame */ 06010 fr = (struct iax_frame *)tpeer->trunkdata; 06011 /* Point to meta data */ 06012 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06013 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06014 if (tpeer->trunkdatalen) { 06015 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06016 meta->zeros = 0; 06017 meta->metacmd = IAX_META_TRUNK; 06018 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06019 meta->cmddata = IAX_META_TRUNK_MINI; 06020 else 06021 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06022 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06023 /* And the rest of the ast_iax2 header */ 06024 fr->direction = DIRECTION_OUTGRESS; 06025 fr->retrans = -1; 06026 fr->transfer = 0; 06027 /* Any appropriate call will do */ 06028 fr->data = fr->afdata; 06029 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06030 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06031 calls = tpeer->calls; 06032 #if 0 06033 ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts)); 06034 #endif 06035 /* Reset transmit trunk side data */ 06036 tpeer->trunkdatalen = 0; 06037 tpeer->calls = 0; 06038 } 06039 if (res < 0) 06040 return res; 06041 return calls; 06042 }
|
|
Definition at line 8678 of file chan_iax2.c. References accountcode, amaflags, ast_category_browse(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_bind(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), authdebug, autokill, build_peer(), build_user(), capability, cfg, channeltype, DEFAULT_MAXMS, defaultsockfd, delayreject, format, get_encrypt_methods(), global_rtautoclear, iax2_capability, iax2_dropcount, iax2_encryption, 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_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxcompat, jittershrinkrate, lagrq_time, language, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_jitter_buffer, max_reg_expire, maxauthreq, maxjitterbuffer, maxjitterinterps, min_jitter_buffer, min_reg_expire, ast_variable::name, iax2_peer::next, iax2_user::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, ping_time, portno, reg_source_db(), regcontext, resyncthreshold, set_timing(), socket_read(), tos, trunkfreq, user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2. Referenced by load_module(), and reload(). 08679 { 08680 struct ast_config *cfg; 08681 int capability=iax2_capability; 08682 struct ast_variable *v; 08683 char *cat; 08684 char *utype; 08685 char *tosval; 08686 int format; 08687 int portno = IAX_DEFAULT_PORTNO; 08688 int x; 08689 struct iax2_user *user; 08690 struct iax2_peer *peer; 08691 struct ast_netsock *ns; 08692 #if 0 08693 static unsigned short int last_port=0; 08694 #endif 08695 08696 cfg = ast_config_load(config_file); 08697 08698 if (!cfg) { 08699 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08700 return -1; 08701 } 08702 08703 /* Reset global codec prefs */ 08704 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08705 08706 /* Reset Global Flags */ 08707 memset(&globalflags, 0, sizeof(globalflags)); 08708 ast_set_flag(&globalflags, IAX_RTUPDATE); 08709 08710 #ifdef SO_NO_CHECK 08711 nochecksums = 0; 08712 #endif 08713 08714 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08715 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08716 08717 v = ast_variable_browse(cfg, "general"); 08718 08719 /* Seed initial tos value */ 08720 tosval = ast_variable_retrieve(cfg, "general", "tos"); 08721 if (tosval) { 08722 if (ast_str2tos(tosval, &tos)) 08723 ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n"); 08724 } 08725 while(v) { 08726 if (!strcasecmp(v->name, "bindport")){ 08727 if (reload) 08728 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 08729 else 08730 portno = atoi(v->value); 08731 } else if (!strcasecmp(v->name, "pingtime")) 08732 ping_time = atoi(v->value); 08733 else if (!strcasecmp(v->name, "nochecksums")) { 08734 #ifdef SO_NO_CHECK 08735 if (ast_true(v->value)) 08736 nochecksums = 1; 08737 else 08738 nochecksums = 0; 08739 #else 08740 if (ast_true(v->value)) 08741 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 08742 #endif 08743 } 08744 else if (!strcasecmp(v->name, "maxjitterbuffer")) 08745 maxjitterbuffer = atoi(v->value); 08746 #ifdef NEWJB 08747 else if (!strcasecmp(v->name, "resyncthreshold")) 08748 resyncthreshold = atoi(v->value); 08749 else if (!strcasecmp(v->name, "maxjitterinterps")) 08750 maxjitterinterps = atoi(v->value); 08751 #endif 08752 else if (!strcasecmp(v->name, "jittershrinkrate")) 08753 jittershrinkrate = atoi(v->value); 08754 else if (!strcasecmp(v->name, "maxexcessbuffer")) 08755 max_jitter_buffer = atoi(v->value); 08756 else if (!strcasecmp(v->name, "minexcessbuffer")) 08757 min_jitter_buffer = atoi(v->value); 08758 else if (!strcasecmp(v->name, "lagrqtime")) 08759 lagrq_time = atoi(v->value); 08760 else if (!strcasecmp(v->name, "dropcount")) 08761 iax2_dropcount = atoi(v->value); 08762 else if (!strcasecmp(v->name, "maxregexpire")) 08763 max_reg_expire = atoi(v->value); 08764 else if (!strcasecmp(v->name, "minregexpire")) 08765 min_reg_expire = atoi(v->value); 08766 else if (!strcasecmp(v->name, "bindaddr")) { 08767 if (reload) { 08768 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 08769 } else { 08770 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 08771 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 08772 } else { 08773 if (option_verbose > 1) { 08774 if (strchr(v->value, ':')) 08775 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 08776 else 08777 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 08778 } 08779 if (defaultsockfd < 0) 08780 defaultsockfd = ast_netsock_sockfd(ns); 08781 ast_netsock_unref(ns); 08782 } 08783 } 08784 } else if (!strcasecmp(v->name, "authdebug")) 08785 authdebug = ast_true(v->value); 08786 else if (!strcasecmp(v->name, "encryption")) 08787 iax2_encryption = get_encrypt_methods(v->value); 08788 else if (!strcasecmp(v->name, "notransfer")) 08789 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 08790 else if (!strcasecmp(v->name, "codecpriority")) { 08791 if(!strcasecmp(v->value, "caller")) 08792 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 08793 else if(!strcasecmp(v->value, "disabled")) 08794 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08795 else if(!strcasecmp(v->value, "reqonly")) { 08796 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 08797 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08798 } 08799 } else if (!strcasecmp(v->name, "jitterbuffer")) 08800 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 08801 else if (!strcasecmp(v->name, "forcejitterbuffer")) 08802 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 08803 else if (!strcasecmp(v->name, "delayreject")) 08804 delayreject = ast_true(v->value); 08805 else if (!strcasecmp(v->name, "mailboxdetail")) 08806 ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL); 08807 else if (!strcasecmp(v->name, "rtcachefriends")) 08808 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 08809 else if (!strcasecmp(v->name, "rtignoreregexpire")) 08810 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 08811 else if (!strcasecmp(v->name, "rtupdate")) 08812 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 08813 else if (!strcasecmp(v->name, "trunktimestamps")) 08814 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 08815 else if (!strcasecmp(v->name, "rtautoclear")) { 08816 int i = atoi(v->value); 08817 if(i > 0) 08818 global_rtautoclear = i; 08819 else 08820 i = 0; 08821 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 08822 } else if (!strcasecmp(v->name, "trunkfreq")) { 08823 trunkfreq = atoi(v->value); 08824 if (trunkfreq < 10) 08825 trunkfreq = 10; 08826 } else if (!strcasecmp(v->name, "autokill")) { 08827 if (sscanf(v->value, "%d", &x) == 1) { 08828 if (x >= 0) 08829 autokill = x; 08830 else 08831 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 08832 } else if (ast_true(v->value)) { 08833 autokill = DEFAULT_MAXMS; 08834 } else { 08835 autokill = 0; 08836 } 08837 } else if (!strcasecmp(v->name, "bandwidth")) { 08838 if (!strcasecmp(v->value, "low")) { 08839 capability = IAX_CAPABILITY_LOWBANDWIDTH; 08840 } else if (!strcasecmp(v->value, "medium")) { 08841 capability = IAX_CAPABILITY_MEDBANDWIDTH; 08842 } else if (!strcasecmp(v->value, "high")) { 08843 capability = IAX_CAPABILITY_FULLBANDWIDTH; 08844 } else 08845 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 08846 } else if (!strcasecmp(v->name, "allow")) { 08847 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 08848 } else if (!strcasecmp(v->name, "disallow")) { 08849 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 08850 } else if (!strcasecmp(v->name, "register")) { 08851 iax2_register(v->value, v->lineno); 08852 } else if (!strcasecmp(v->name, "iaxcompat")) { 08853 iaxcompat = ast_true(v->value); 08854 } else if (!strcasecmp(v->name, "regcontext")) { 08855 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 08856 /* Create context if it doesn't exist already */ 08857 if (!ast_context_find(regcontext)) 08858 ast_context_create(NULL, regcontext, channeltype); 08859 } else if (!strcasecmp(v->name, "tos")) { 08860 if (ast_str2tos(v->value, &tos)) 08861 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 08862 } else if (!strcasecmp(v->name, "accountcode")) { 08863 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 08864 } else if (!strcasecmp(v->name, "amaflags")) { 08865 format = ast_cdr_amaflags2int(v->value); 08866 if (format < 0) { 08867 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08868 } else { 08869 amaflags = format; 08870 } 08871 } else if (!strcasecmp(v->name, "language")) { 08872 ast_copy_string(language, v->value, sizeof(language)); 08873 } else if (!strcasecmp(v->name, "maxauthreq")) { 08874 maxauthreq = atoi(v->value); 08875 if (maxauthreq < 0) 08876 maxauthreq = 0; 08877 } /*else if (strcasecmp(v->name,"type")) */ 08878 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08879 v = v->next; 08880 } 08881 08882 if (defaultsockfd < 0) { 08883 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 08884 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 08885 } else { 08886 if (option_verbose > 1) 08887 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 08888 defaultsockfd = ast_netsock_sockfd(ns); 08889 ast_netsock_unref(ns); 08890 } 08891 } 08892 08893 if (min_reg_expire > max_reg_expire) { 08894 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 08895 min_reg_expire, max_reg_expire, max_reg_expire); 08896 min_reg_expire = max_reg_expire; 08897 } 08898 iax2_capability = capability; 08899 cat = ast_category_browse(cfg, NULL); 08900 while(cat) { 08901 if (strcasecmp(cat, "general")) { 08902 utype = ast_variable_retrieve(cfg, cat, "type"); 08903 if (utype) { 08904 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 08905 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 08906 if (user) { 08907 ast_mutex_lock(&userl.lock); 08908 user->next = userl.users; 08909 userl.users = user; 08910 ast_mutex_unlock(&userl.lock); 08911 } 08912 } 08913 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 08914 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 08915 if (peer) { 08916 ast_mutex_lock(&peerl.lock); 08917 peer->next = peerl.peers; 08918 peerl.peers = peer; 08919 ast_mutex_unlock(&peerl.lock); 08920 if (ast_test_flag(peer, IAX_DYNAMIC)) 08921 reg_source_db(peer); 08922 } 08923 } else if (strcasecmp(utype, "user")) { 08924 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 08925 } 08926 } else 08927 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 08928 } 08929 cat = ast_category_browse(cfg, cat); 08930 } 08931 ast_config_destroy(cfg); 08932 set_timing(); 08933 return capability; 08934 }
|
|
Definition at line 8661 of file chan_iax2.c. References ast_log(), LOG_WARNING, timingfd, and trunkfreq. Referenced by set_config(). 08662 { 08663 #ifdef IAX_TRUNKING 08664 int bs = trunkfreq * 8; 08665 if (timingfd > -1) { 08666 if ( 08667 #ifdef ZT_TIMERACK 08668 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08669 #endif 08670 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08671 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08672 } 08673 #endif 08674 }
|
|
Definition at line 6333 of file chan_iax2.c. References 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_CONGESTION, AST_CONTROL_PROGRESS, 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_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authdebug, authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_frame::data, ast_frame::datalen, decrypt_frame(), delayreject, iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_error(), ast_iax2_queue::head, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy_nolock(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_frame(), 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_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_TRUNK, iax_ies::iax_unknown, iaxcompat, iaxdebug, iaxfrdup2(), iaxq, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, iax2_peer::name, NEW_ALLOW, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_verbose, iax_frame::oseqno, iax2_dpcache::peer, chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, stop_stuff(), ast_frame::subclass, test_losspct, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros. Referenced by network_thread(), and set_config(). 06334 { 06335 struct sockaddr_in sin; 06336 int res; 06337 int updatehistory=1; 06338 int new = NEW_PREVENT; 06339 unsigned char buf[4096]; 06340 void *ptr; 06341 socklen_t len = sizeof(sin); 06342 int dcallno = 0; 06343 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf; 06344 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf; 06345 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; 06346 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf; 06347 struct ast_iax2_meta_trunk_hdr *mth; 06348 struct ast_iax2_meta_trunk_entry *mte; 06349 struct ast_iax2_meta_trunk_mini *mtm; 06350 struct iax_frame *fr; 06351 struct iax_frame *cur; 06352 char iabuf[INET_ADDRSTRLEN]; 06353 struct ast_frame f; 06354 struct ast_channel *c; 06355 struct iax2_dpcache *dp; 06356 struct iax2_peer *peer; 06357 struct iax2_trunk_peer *tpeer; 06358 struct timeval rxtrunktime; 06359 struct iax_ies ies; 06360 struct iax_ie_data ied0, ied1; 06361 int format; 06362 int exists; 06363 int minivid = 0; 06364 unsigned int ts; 06365 char empty[32]=""; /* Safety measure */ 06366 struct iax_frame *duped_fr; 06367 char host_pref_buf[128]; 06368 char caller_pref_buf[128]; 06369 struct ast_codec_pref pref; 06370 char *using_prefs = "mine"; 06371 06372 /* allocate an iax_frame with 4096 bytes of data buffer */ 06373 fr = alloca(sizeof(*fr) + 4096); 06374 fr->callno = 0; 06375 06376 res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len); 06377 if (res < 0) { 06378 if (errno != ECONNREFUSED) 06379 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06380 handle_error(); 06381 return 1; 06382 } 06383 if(test_losspct) { /* simulate random loss condition */ 06384 if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct) 06385 return 1; 06386 06387 } 06388 if (res < sizeof(*mh)) { 06389 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06390 return 1; 06391 } 06392 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06393 if (res < sizeof(*vh)) { 06394 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06395 return 1; 06396 } 06397 06398 /* This is a video frame, get call number */ 06399 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06400 minivid = 1; 06401 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06402 unsigned char metatype; 06403 06404 if (res < sizeof(*meta)) { 06405 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06406 return 1; 06407 } 06408 06409 /* This is a meta header */ 06410 switch(meta->metacmd) { 06411 case IAX_META_TRUNK: 06412 if (res < (sizeof(*meta) + sizeof(*mth))) { 06413 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06414 sizeof(*meta) + sizeof(*mth)); 06415 return 1; 06416 } 06417 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06418 ts = ntohl(mth->ts); 06419 metatype = meta->cmddata; 06420 res -= (sizeof(*meta) + sizeof(*mth)); 06421 ptr = mth->data; 06422 tpeer = find_tpeer(&sin, fd); 06423 if (!tpeer) { 06424 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06425 return 1; 06426 } 06427 tpeer->trunkact = ast_tvnow(); 06428 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06429 tpeer->rxtrunktime = tpeer->trunkact; 06430 rxtrunktime = tpeer->rxtrunktime; 06431 ast_mutex_unlock(&tpeer->lock); 06432 while(res >= sizeof(*mte)) { 06433 /* Process channels */ 06434 unsigned short callno, trunked_ts, len; 06435 06436 if (metatype == IAX_META_TRUNK_MINI) { 06437 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06438 ptr += sizeof(*mtm); 06439 res -= sizeof(*mtm); 06440 len = ntohs(mtm->len); 06441 callno = ntohs(mtm->mini.callno); 06442 trunked_ts = ntohs(mtm->mini.ts); 06443 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06444 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06445 ptr += sizeof(*mte); 06446 res -= sizeof(*mte); 06447 len = ntohs(mte->len); 06448 callno = ntohs(mte->callno); 06449 trunked_ts = 0; 06450 } else { 06451 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06452 break; 06453 } 06454 /* Stop if we don't have enough data */ 06455 if (len > res) 06456 break; 06457 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06458 if (fr->callno) { 06459 ast_mutex_lock(&iaxsl[fr->callno]); 06460 /* If it's a valid call, deliver the contents. If not, we 06461 drop it, since we don't have a scallno to use for an INVAL */ 06462 /* Process as a mini frame */ 06463 f.frametype = AST_FRAME_VOICE; 06464 if (iaxs[fr->callno]) { 06465 if (iaxs[fr->callno]->voiceformat > 0) { 06466 f.subclass = iaxs[fr->callno]->voiceformat; 06467 f.datalen = len; 06468 if (f.datalen >= 0) { 06469 if (f.datalen) 06470 f.data = ptr; 06471 else 06472 f.data = NULL; 06473 if(trunked_ts) { 06474 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06475 } else 06476 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06477 /* Don't pass any packets until we're started */ 06478 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06479 /* Common things */ 06480 f.src = "IAX2"; 06481 f.mallocd = 0; 06482 f.offset = 0; 06483 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06484 f.samples = ast_codec_get_samples(&f); 06485 else 06486 f.samples = 0; 06487 fr->outoforder = 0; 06488 iax_frame_wrap(fr, &f); 06489 #ifdef BRIDGE_OPTIMIZATION 06490 if (iaxs[fr->callno]->bridgecallno) { 06491 forward_delivery(fr); 06492 } else { 06493 duped_fr = iaxfrdup2(fr); 06494 if (duped_fr) { 06495 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06496 } 06497 } 06498 #else 06499 duped_fr = iaxfrdup2(fr); 06500 if (duped_fr) { 06501 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06502 } 06503 #endif 06504 if (iaxs[fr->callno]->last < fr->ts) { 06505 iaxs[fr->callno]->last = fr->ts; 06506 #if 1 06507 if (option_debug) 06508 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06509 #endif 06510 } 06511 } 06512 } else { 06513 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06514 } 06515 } else { 06516 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06517 iax2_vnak(fr->callno); 06518 } 06519 } 06520 ast_mutex_unlock(&iaxsl[fr->callno]); 06521 } 06522 ptr += len; 06523 res -= len; 06524 } 06525 06526 } 06527 return 1; 06528 } 06529 06530 #ifdef DEBUG_SUPPORT 06531 if (iaxdebug && (res >= sizeof(*fh))) 06532 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06533 #endif 06534 if ((res >= sizeof(*fh)) && ntohs(mh->callno) & IAX_FLAG_FULL) { 06535 if (res < sizeof(*fh)) { 06536 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06537 return 1; 06538 } 06539 06540 /* Get the destination call number */ 06541 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06542 /* Retrieve the type and subclass */ 06543 f.frametype = fh->type; 06544 if (f.frametype == AST_FRAME_VIDEO) { 06545 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06546 } else { 06547 f.subclass = uncompress_subclass(fh->csub); 06548 } 06549 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06550 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06551 (f.subclass == IAX_COMMAND_REGREL))) 06552 new = NEW_ALLOW; 06553 } else { 06554 /* Don't know anything about it yet */ 06555 f.frametype = AST_FRAME_NULL; 06556 f.subclass = 0; 06557 } 06558 06559 if (!fr->callno) 06560 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06561 06562 if (fr->callno > 0) 06563 ast_mutex_lock(&iaxsl[fr->callno]); 06564 06565 if (!fr->callno || !iaxs[fr->callno]) { 06566 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06567 frame, reply with an inval */ 06568 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06569 /* We can only raw hangup control frames */ 06570 if (((f.subclass != IAX_COMMAND_INVAL) && 06571 (f.subclass != IAX_COMMAND_TXCNT) && 06572 (f.subclass != IAX_COMMAND_TXACC) && 06573 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06574 (f.frametype != AST_FRAME_IAX)) 06575 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06576 fd); 06577 } 06578 if (fr->callno > 0) 06579 ast_mutex_unlock(&iaxsl[fr->callno]); 06580 return 1; 06581 } 06582 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06583 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06584 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06585 ast_mutex_unlock(&iaxsl[fr->callno]); 06586 return 1; 06587 } 06588 #ifdef DEBUG_SUPPORT 06589 else if (iaxdebug) 06590 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 06591 #endif 06592 } 06593 06594 /* count this frame */ 06595 iaxs[fr->callno]->frames_received++; 06596 06597 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 06598 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06599 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06600 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06601 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06602 if (option_debug && iaxdebug) 06603 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06604 /* Check if it's out of order (and not an ACK or INVAL) */ 06605 fr->oseqno = fh->oseqno; 06606 fr->iseqno = fh->iseqno; 06607 fr->ts = ntohl(fh->ts); 06608 #ifdef IAXTESTS 06609 if (test_resync) { 06610 if (option_debug) 06611 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 06612 fr->ts += test_resync; 06613 } 06614 #endif /* IAXTESTS */ 06615 #if 0 06616 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06617 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06618 (f.subclass == IAX_COMMAND_NEW || 06619 f.subclass == IAX_COMMAND_AUTHREQ || 06620 f.subclass == IAX_COMMAND_ACCEPT || 06621 f.subclass == IAX_COMMAND_REJECT)) ) ) 06622 #endif 06623 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06624 updatehistory = 0; 06625 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 06626 (iaxs[fr->callno]->iseqno || 06627 ((f.subclass != IAX_COMMAND_TXCNT) && 06628 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06629 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06630 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06631 (f.subclass != IAX_COMMAND_TXACC)) || 06632 (f.frametype != AST_FRAME_IAX))) { 06633 if ( 06634 ((f.subclass != IAX_COMMAND_ACK) && 06635 (f.subclass != IAX_COMMAND_INVAL) && 06636 (f.subclass != IAX_COMMAND_TXCNT) && 06637 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06638 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06639 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06640 (f.subclass != IAX_COMMAND_TXACC) && 06641 (f.subclass != IAX_COMMAND_VNAK)) || 06642 (f.frametype != AST_FRAME_IAX)) { 06643 /* If it's not an ACK packet, it's out of order. */ 06644 if (option_debug) 06645 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06646 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 06647 if (iaxs[fr->callno]->iseqno > fr->oseqno) { 06648 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06649 if ((f.frametype != AST_FRAME_IAX) || 06650 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06651 if (option_debug) 06652 ast_log(LOG_DEBUG, "Acking anyway\n"); 06653 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06654 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06655 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06656 } 06657 } else { 06658 /* Send a VNAK requesting retransmission */ 06659 iax2_vnak(fr->callno); 06660 } 06661 ast_mutex_unlock(&iaxsl[fr->callno]); 06662 return 1; 06663 } 06664 } else { 06665 /* Increment unless it's an ACK or VNAK */ 06666 if (((f.subclass != IAX_COMMAND_ACK) && 06667 (f.subclass != IAX_COMMAND_INVAL) && 06668 (f.subclass != IAX_COMMAND_TXCNT) && 06669 (f.subclass != IAX_COMMAND_TXACC) && 06670 (f.subclass != IAX_COMMAND_VNAK)) || 06671 (f.frametype != AST_FRAME_IAX)) 06672 iaxs[fr->callno]->iseqno++; 06673 } 06674 /* A full frame */ 06675 if (res < sizeof(*fh)) { 06676 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 06677 ast_mutex_unlock(&iaxsl[fr->callno]); 06678 return 1; 06679 } 06680 f.datalen = res - sizeof(*fh); 06681 06682 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06683 from the real peer, not the transfer peer */ 06684 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06685 ((f.subclass != IAX_COMMAND_INVAL) || 06686 (f.frametype != AST_FRAME_IAX))) { 06687 unsigned char x; 06688 /* XXX This code is not very efficient. Surely there is a better way which still 06689 properly handles boundary conditions? XXX */ 06690 /* First we have to qualify that the ACKed value is within our window */ 06691 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 06692 if (fr->iseqno == x) 06693 break; 06694 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 06695 /* The acknowledgement is within our window. Time to acknowledge everything 06696 that it says to */ 06697 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 06698 /* Ack the packet with the given timestamp */ 06699 if (option_debug && iaxdebug) 06700 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06701 ast_mutex_lock(&iaxq.lock); 06702 for (cur = iaxq.head; cur ; cur = cur->next) { 06703 /* If it's our call, and our timestamp, mark -1 retries */ 06704 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 06705 cur->retries = -1; 06706 /* Destroy call if this is the end */ 06707 if (cur->final) { 06708 if (iaxdebug && option_debug) 06709 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno); 06710 iax2_destroy_nolock(fr->callno); 06711 } 06712 } 06713 } 06714 ast_mutex_unlock(&iaxq.lock); 06715 } 06716 /* Note how much we've received acknowledgement for */ 06717 if (iaxs[fr->callno]) 06718 iaxs[fr->callno]->rseqno = fr->iseqno; 06719 else { 06720 /* Stop processing now */ 06721 ast_mutex_unlock(&iaxsl[fr->callno]); 06722 return 1; 06723 } 06724 } else 06725 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 06726 } 06727 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06728 ((f.frametype != AST_FRAME_IAX) || 06729 ((f.subclass != IAX_COMMAND_TXACC) && 06730 (f.subclass != IAX_COMMAND_TXCNT)))) { 06731 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06732 ast_mutex_unlock(&iaxsl[fr->callno]); 06733 return 1; 06734 } 06735 06736 if (f.datalen) { 06737 if (f.frametype == AST_FRAME_IAX) { 06738 if (iax_parse_ies(&ies, buf + sizeof(*fh), f.datalen)) { 06739 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06740 ast_mutex_unlock(&iaxsl[fr->callno]); 06741 return 1; 06742 } 06743 f.data = NULL; 06744 } else 06745 f.data = buf + sizeof(*fh); 06746 } else { 06747 if (f.frametype == AST_FRAME_IAX) 06748 f.data = NULL; 06749 else 06750 f.data = empty; 06751 memset(&ies, 0, sizeof(ies)); 06752 } 06753 if (f.frametype == AST_FRAME_VOICE) { 06754 if (f.subclass != iaxs[fr->callno]->voiceformat) { 06755 iaxs[fr->callno]->voiceformat = f.subclass; 06756 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06757 if (iaxs[fr->callno]->owner) { 06758 int orignative; 06759 retryowner: 06760 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 06761 ast_mutex_unlock(&iaxsl[fr->callno]); 06762 usleep(1); 06763 ast_mutex_lock(&iaxsl[fr->callno]); 06764 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 06765 } 06766 if (iaxs[fr->callno]) { 06767 if (iaxs[fr->callno]->owner) { 06768 orignative = iaxs[fr->callno]->owner->nativeformats; 06769 iaxs[fr->callno]->owner->nativeformats = f.subclass; 06770 if (iaxs[fr->callno]->owner->readformat) 06771 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 06772 iaxs[fr->callno]->owner->nativeformats = orignative; 06773 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 06774 } 06775 } else { 06776 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06777 ast_mutex_unlock(&iaxsl[fr->callno]); 06778 return 1; 06779 } 06780 } 06781 } 06782 } 06783 if (f.frametype == AST_FRAME_VIDEO) { 06784 if (f.subclass != iaxs[fr->callno]->videoformat) { 06785 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06786 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 06787 } 06788 } 06789 if (f.frametype == AST_FRAME_IAX) { 06790 if (iaxs[fr->callno]->initid > -1) { 06791 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06792 ast_sched_del(sched, iaxs[fr->callno]->initid); 06793 iaxs[fr->callno]->initid = -1; 06794 } 06795 /* Handle the IAX pseudo frame itself */ 06796 if (option_debug && iaxdebug) 06797 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06798 06799 /* Update last ts unless the frame's timestamp originated with us. */ 06800 if (iaxs[fr->callno]->last < fr->ts && 06801 f.subclass != IAX_COMMAND_ACK && 06802 f.subclass != IAX_COMMAND_PONG && 06803 f.subclass != IAX_COMMAND_LAGRP) { 06804 iaxs[fr->callno]->last = fr->ts; 06805 if (option_debug && iaxdebug) 06806 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06807 } 06808 06809 switch(f.subclass) { 06810 case IAX_COMMAND_ACK: 06811 /* Do nothing */ 06812 break; 06813 case IAX_COMMAND_QUELCH: 06814 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06815 /* Generate Manager Hold event, if necessary*/ 06816 if (iaxs[fr->callno]->owner) { 06817 manager_event(EVENT_FLAG_CALL, "Hold", 06818 "Channel: %s\r\n" 06819 "Uniqueid: %s\r\n", 06820 iaxs[fr->callno]->owner->name, 06821 iaxs[fr->callno]->owner->uniqueid); 06822 } 06823 06824 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 06825 if (ies.musiconhold) { 06826 if (iaxs[fr->callno]->owner && 06827 ast_bridged_channel(iaxs[fr->callno]->owner)) 06828 ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL); 06829 } 06830 } 06831 break; 06832 case IAX_COMMAND_UNQUELCH: 06833 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06834 /* Generate Manager Unhold event, if necessary*/ 06835 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 06836 manager_event(EVENT_FLAG_CALL, "Unhold", 06837 "Channel: %s\r\n" 06838 "Uniqueid: %s\r\n", 06839 iaxs[fr->callno]->owner->name, 06840 iaxs[fr->callno]->owner->uniqueid); 06841 } 06842 06843 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 06844 if (iaxs[fr->callno]->owner && 06845 ast_bridged_channel(iaxs[fr->callno]->owner)) 06846 ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner)); 06847 } 06848 break; 06849 case IAX_COMMAND_TXACC: 06850 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 06851 /* Ack the packet with the given timestamp */ 06852 ast_mutex_lock(&iaxq.lock); 06853 for (cur = iaxq.head; cur ; cur = cur->next) { 06854 /* Cancel any outstanding txcnt's */ 06855 if ((fr->callno == cur->callno) && (cur->transfer)) 06856 cur->retries = -1; 06857 } 06858 ast_mutex_unlock(&iaxq.lock); 06859 memset(&ied1, 0, sizeof(ied1)); 06860 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 06861 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06862 iaxs[fr->callno]->transferring = TRANSFER_READY; 06863 } 06864 break; 06865 case IAX_COMMAND_NEW: 06866 /* Ignore if it's already up */ 06867 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06868 break; 06869 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06870 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06871 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06872 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 06873 fr->callno = make_trunk(fr->callno, 1); 06874 } 06875 /* For security, always ack immediately */ 06876 if (delayreject) 06877 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06878 if (check_access(fr->callno, &sin, &ies)) { 06879 /* They're not allowed on */ 06880 auth_fail(fr->callno, IAX_COMMAND_REJECT); 06881 if (authdebug) 06882 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 06883 break; 06884 } 06885 /* This might re-enter the IAX code and need the lock */ 06886 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 06887 ast_mutex_unlock(&iaxsl[fr->callno]); 06888 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 06889 ast_mutex_lock(&iaxsl[fr->callno]); 06890 } else 06891 exists = 0; 06892 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 06893 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 06894 memset(&ied0, 0, sizeof(ied0)); 06895 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06896 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06897 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06898 if (authdebug) 06899 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 06900 } else { 06901 /* Select an appropriate format */ 06902 06903 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06904 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06905 using_prefs = "reqonly"; 06906 } else { 06907 using_prefs = "disabled"; 06908 } 06909 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 06910 memset(&pref, 0, sizeof(pref)); 06911 strcpy(caller_pref_buf, "disabled"); 06912 strcpy(host_pref_buf, "disabled"); 06913 } else { 06914 using_prefs = "mine"; 06915 /* If the information elements are in here... use them */ 06916 if (ies.codec_prefs) 06917 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 06918 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06919 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06920 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06921 pref = iaxs[fr->callno]->rprefs; 06922 using_prefs = "caller"; 06923 } else { 06924 pref = iaxs[fr->callno]->prefs; 06925 } 06926 } else 06927 pref = iaxs[fr->callno]->prefs; 06928 06929 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 06930 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06931 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06932 } 06933 if (!format) { 06934 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06935 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 06936 if (!format) { 06937 memset(&ied0, 0, sizeof(ied0)); 06938 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06939 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06940 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06941 if (authdebug) { 06942 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06943 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 06944 else 06945 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(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 06946 } 06947 } else { 06948 /* Pick one... */ 06949 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06950 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 06951 format = 0; 06952 } else { 06953 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06954 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06955 memset(&pref, 0, sizeof(pref)); 06956 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06957 strcpy(caller_pref_buf,"disabled"); 06958 strcpy(host_pref_buf,"disabled"); 06959 } else { 06960 using_prefs = "mine"; 06961 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06962 /* Do the opposite of what we tried above. */ 06963 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06964 pref = iaxs[fr->callno]->prefs; 06965 } else { 06966 pref = iaxs[fr->callno]->rprefs; 06967 using_prefs = "caller"; 06968 } 06969 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 06970 06971 } else /* if no codec_prefs IE do it the old way */ 06972 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06973 } 06974 } 06975 06976 if (!format) { 06977 memset(&ied0, 0, sizeof(ied0)); 06978 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06979 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06980 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06981 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06982 if (authdebug) 06983 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(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 06984 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 06985 break; 06986 } 06987 } 06988 } 06989 if (format) { 06990 /* No authentication required, let them in */ 06991 memset(&ied1, 0, sizeof(ied1)); 06992 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 06993 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 06994 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 06995 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 06996 if (option_verbose > 2) 06997 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 06998 "%srequested format = %s,\n" 06999 "%srequested prefs = %s,\n" 07000 "%sactual format = %s,\n" 07001 "%shost prefs = %s,\n" 07002 "%spriority = %s\n", 07003 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07004 VERBOSE_PREFIX_4, 07005 ast_getformatname(iaxs[fr->callno]->peerformat), 07006 VERBOSE_PREFIX_4, 07007 caller_pref_buf, 07008 VERBOSE_PREFIX_4, 07009 ast_getformatname(format), 07010 VERBOSE_PREFIX_4, 07011 host_pref_buf, 07012 VERBOSE_PREFIX_4, 07013 using_prefs); 07014 07015 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07016 iax2_destroy_nolock(fr->callno); 07017 } else { 07018 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07019 /* If this is a TBD call, we're ready but now what... */ 07020 if (option_verbose > 2) 07021 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07022 } 07023 } 07024 } 07025 break; 07026 } 07027 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07028 merge_encryption(iaxs[fr->callno],ies.encmethods); 07029 else 07030 iaxs[fr->callno]->encmethods = 0; 07031 if (!authenticate_request(iaxs[fr->callno])) 07032 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07033 break; 07034 case IAX_COMMAND_DPREQ: 07035 /* Request status in the dialplan */ 07036 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07037 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07038 if (iaxcompat) { 07039 /* Spawn a thread for the lookup */ 07040 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07041 } else { 07042 /* Just look it up */ 07043 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07044 } 07045 } 07046 break; 07047 case IAX_COMMAND_HANGUP: 07048 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07049 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07050 /* Set hangup cause according to remote */ 07051 if (ies.causecode && iaxs[fr->callno]->owner) 07052 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07053 /* Send ack immediately, before we destroy */ 07054 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07055 iax2_destroy_nolock(fr->callno); 07056 break; 07057 case IAX_COMMAND_REJECT: 07058 memset(&f, 0, sizeof(f)); 07059 f.frametype = AST_FRAME_CONTROL; 07060 f.subclass = AST_CONTROL_CONGESTION; 07061 07062 /* Set hangup cause according to remote */ 07063 if (ies.causecode && iaxs[fr->callno]->owner) 07064 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07065 07066 iax2_queue_frame(fr->callno, &f); 07067 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07068 /* Send ack immediately, before we destroy */ 07069 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07070 iax2_destroy_nolock(fr->callno); 07071 break; 07072 } 07073 if (iaxs[fr->callno]->owner) { 07074 if (authdebug) 07075 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ies.cause ? ies.cause : "<Unknown>"); 07076 } 07077 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno); 07078 /* Send ack immediately, before we destroy */ 07079 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07080 iaxs[fr->callno]->error = EPERM; 07081 iax2_destroy_nolock(fr->callno); 07082 break; 07083 case IAX_COMMAND_TRANSFER: 07084 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07085 if (!strcmp(ies.called_number, ast_parking_ext())) { 07086 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07087 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07088 } else 07089 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07090 } else { 07091 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07092 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07093 ies.called_number, iaxs[fr->callno]->context); 07094 else 07095 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07096 ies.called_number, iaxs[fr->callno]->context); 07097 } 07098 } else 07099 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07100 break; 07101 case IAX_COMMAND_ACCEPT: 07102 /* Ignore if call is already up or needs authentication or is a TBD */ 07103 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07104 break; 07105 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07106 /* Send ack immediately, before we destroy */ 07107 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07108 iax2_destroy_nolock(fr->callno); 07109 break; 07110 } 07111 if (ies.format) { 07112 iaxs[fr->callno]->peerformat = ies.format; 07113 } else { 07114 if (iaxs[fr->callno]->owner) 07115 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07116 else 07117 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07118 } 07119 if (option_verbose > 2) 07120 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); 07121 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07122 memset(&ied0, 0, sizeof(ied0)); 07123 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07124 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07125 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07126 if (authdebug) 07127 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07128 } else { 07129 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07130 if (iaxs[fr->callno]->owner) { 07131 /* Switch us to use a compatible format */ 07132 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07133 if (option_verbose > 2) 07134 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07135 retryowner2: 07136 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07137 ast_mutex_unlock(&iaxsl[fr->callno]); 07138 usleep(1); 07139 ast_mutex_lock(&iaxsl[fr->callno]); 07140 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07141 } 07142 07143 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07144 /* Setup read/write formats properly. */ 07145 if (iaxs[fr->callno]->owner->writeformat) 07146 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07147 if (iaxs[fr->callno]->owner->readformat) 07148 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07149 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07150 } 07151 } 07152 } 07153 ast_mutex_lock(&dpcache_lock); 07154 dp = iaxs[fr->callno]->dpentries; 07155 while(dp) { 07156 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07157 iax2_dprequest(dp, fr->callno); 07158 } 07159 dp = dp->peer; 07160 } 07161 ast_mutex_unlock(&dpcache_lock); 07162 break; 07163 case IAX_COMMAND_POKE: 07164 /* Send back a pong packet with the original timestamp */ 07165 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07166 break; 07167 case IAX_COMMAND_PING: 07168 #ifdef BRIDGE_OPTIMIZATION 07169 if (iaxs[fr->callno]->bridgecallno) { 07170 /* If we're in a bridged call, just forward this */ 07171 forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1); 07172 } else { 07173 struct iax_ie_data pingied; 07174 construct_rr(iaxs[fr->callno], &pingied); 07175 /* Send back a pong packet with the original timestamp */ 07176 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07177 } 07178 #else 07179 { 07180 struct iax_ie_data pingied; 07181 construct_rr(iaxs[fr->callno], &pingied); 07182 /* Send back a pong packet with the original timestamp */ 07183 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07184 } 07185 #endif 07186 break; 07187 case IAX_COMMAND_PONG: 07188 #ifdef BRIDGE_OPTIMIZATION 07189 if (iaxs[fr->callno]->bridgecallno) { 07190 /* Forward to the other side of the bridge */ 07191 forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07192 } else { 07193 /* Calculate ping time */ 07194 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07195 } 07196 #else 07197 /* Calculate ping time */ 07198 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07199 #endif 07200 /* save RR info */ 07201 save_rr(fr, &ies); 07202 07203 if (iaxs[fr->callno]->peerpoke) { 07204 peer = iaxs[fr->callno]->peerpoke; 07205 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07206 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07207 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07208 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07209 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07210 } 07211 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07212 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07213 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07214 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07215 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07216 } 07217 } 07218 peer->lastms = iaxs[fr->callno]->pingtime; 07219 if (peer->smoothing && (peer->lastms > -1)) 07220 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07221 else if (peer->smoothing && peer->lastms < 0) 07222 peer->historicms = (0 + peer->historicms) / 2; 07223 else 07224 peer->historicms = iaxs[fr->callno]->pingtime; 07225 07226 if (peer->pokeexpire > -1) 07227 ast_sched_del(sched, peer->pokeexpire); 07228 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07229 iax2_destroy_nolock(fr->callno); 07230 peer->callno = 0; 07231 /* Try again eventually */ 07232 ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms); 07233 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07234 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07235 else 07236 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07237 } 07238 break; 07239 case IAX_COMMAND_LAGRQ: 07240 case IAX_COMMAND_LAGRP: 07241 #ifdef BRIDGE_OPTIMIZATION 07242 if (iaxs[fr->callno]->bridgecallno) { 07243 forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1); 07244 } else { 07245 #endif 07246 f.src = "LAGRQ"; 07247 f.mallocd = 0; 07248 f.offset = 0; 07249 f.samples = 0; 07250 iax_frame_wrap(fr, &f); 07251 if(f.subclass == IAX_COMMAND_LAGRQ) { 07252 /* Received a LAGRQ - echo back a LAGRP */ 07253 fr->af.subclass = IAX_COMMAND_LAGRP; 07254 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07255 } else { 07256 /* Received LAGRP in response to our LAGRQ */ 07257 unsigned int ts; 07258 /* This is a reply we've been given, actually measure the difference */ 07259 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07260 iaxs[fr->callno]->lag = ts - fr->ts; 07261 if (option_debug && iaxdebug) 07262 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07263 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07264 } 07265 #ifdef BRIDGE_OPTIMIZATION 07266 } 07267 #endif 07268 break; 07269 case IAX_COMMAND_AUTHREQ: 07270 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07271 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>"); 07272 break; 07273 } 07274 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07275 ast_log(LOG_WARNING, 07276 "I don't know how to authenticate %s to %s\n", 07277 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr)); 07278 } 07279 break; 07280 case IAX_COMMAND_AUTHREP: 07281 /* For security, always ack immediately */ 07282 if (delayreject) 07283 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07284 /* Ignore once we've started */ 07285 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07286 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>"); 07287 break; 07288 } 07289 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07290 if (authdebug) 07291 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); 07292 memset(&ied0, 0, sizeof(ied0)); 07293 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07294 break; 07295 } 07296 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07297 /* This might re-enter the IAX code and need the lock */ 07298 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07299 } else 07300 exists = 0; 07301 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07302 if (authdebug) 07303 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07304 memset(&ied0, 0, sizeof(ied0)); 07305 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07306 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07307 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07308 } else { 07309 /* Select an appropriate format */ 07310 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07311 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07312 using_prefs = "reqonly"; 07313 } else { 07314 using_prefs = "disabled"; 07315 } 07316 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07317 memset(&pref, 0, sizeof(pref)); 07318 strcpy(caller_pref_buf, "disabled"); 07319 strcpy(host_pref_buf, "disabled"); 07320 } else { 07321 using_prefs = "mine"; 07322 if (ies.codec_prefs) 07323 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07324 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07325 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07326 pref = iaxs[fr->callno]->rprefs; 07327 using_prefs = "caller"; 07328 } else { 07329 pref = iaxs[fr->callno]->prefs; 07330 } 07331 } else /* if no codec_prefs IE do it the old way */ 07332 pref = iaxs[fr->callno]->prefs; 07333 07334 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07335 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07336 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07337 } 07338 if (!format) { 07339 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07340 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); 07341 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07342 } 07343 if (!format) { 07344 if (authdebug) { 07345 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07346 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07347 else 07348 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(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07349 } 07350 memset(&ied0, 0, sizeof(ied0)); 07351 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07352 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07353 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07354 } else { 07355 /* Pick one... */ 07356 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07357 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07358 format = 0; 07359 } else { 07360 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07361 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07362 memset(&pref, 0, sizeof(pref)); 07363 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07364 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07365 strcpy(caller_pref_buf,"disabled"); 07366 strcpy(host_pref_buf,"disabled"); 07367 } else { 07368 using_prefs = "mine"; 07369 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07370 /* Do the opposite of what we tried above. */ 07371 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07372 pref = iaxs[fr->callno]->prefs; 07373 } else { 07374 pref = iaxs[fr->callno]->rprefs; 07375 using_prefs = "caller"; 07376 } 07377 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07378 } else /* if no codec_prefs IE do it the old way */ 07379 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07380 } 07381 } 07382 if (!format) { 07383 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07384 if (authdebug) { 07385 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07386 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07387 else 07388 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(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07389 } 07390 memset(&ied0, 0, sizeof(ied0)); 07391 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07392 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07393 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07394 } 07395 } 07396 } 07397 if (format) { 07398 /* Authentication received */ 07399 memset(&ied1, 0, sizeof(ied1)); 07400 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07401 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07402 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07403 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07404 if (option_verbose > 2) 07405 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07406 "%srequested format = %s,\n" 07407 "%srequested prefs = %s,\n" 07408 "%sactual format = %s,\n" 07409 "%shost prefs = %s,\n" 07410 "%spriority = %s\n", 07411 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07412 VERBOSE_PREFIX_4, 07413 ast_getformatname(iaxs[fr->callno]->peerformat), 07414 VERBOSE_PREFIX_4, 07415 caller_pref_buf, 07416 VERBOSE_PREFIX_4, 07417 ast_getformatname(format), 07418 VERBOSE_PREFIX_4, 07419 host_pref_buf, 07420 VERBOSE_PREFIX_4, 07421 using_prefs); 07422 07423 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07424 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07425 iax2_destroy_nolock(fr->callno); 07426 } else { 07427 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07428 /* If this is a TBD call, we're ready but now what... */ 07429 if (option_verbose > 2) 07430 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07431 } 07432 } 07433 } 07434 break; 07435 case IAX_COMMAND_DIAL: 07436 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07437 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07438 ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten)); 07439 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07440 if (authdebug) 07441 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07442 memset(&ied0, 0, sizeof(ied0)); 07443 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07444 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07445 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07446 } else { 07447 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07448 if (option_verbose > 2) 07449 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat); 07450 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07451 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07452 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07453 iax2_destroy_nolock(fr->callno); 07454 } 07455 } 07456 break; 07457 case IAX_COMMAND_INVAL: 07458 iaxs[fr->callno]->error = ENOTCONN; 07459 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07460 iax2_destroy_nolock(fr->callno); 07461 if (option_debug) 07462 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07463 break; 07464 case IAX_COMMAND_VNAK: 07465 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07466 /* Force retransmission */ 07467 vnak_retransmit(fr->callno, fr->iseqno); 07468 break; 07469 case IAX_COMMAND_REGREQ: 07470 case IAX_COMMAND_REGREL: 07471 /* For security, always ack immediately */ 07472 if (delayreject) 07473 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07474 if (register_verify(fr->callno, &sin, &ies)) { 07475 /* Send delayed failure */ 07476 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07477 break; 07478 } 07479 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 07480 if (f.subclass == IAX_COMMAND_REGREL) 07481 memset(&sin, 0, sizeof(sin)); 07482 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07483 ast_log(LOG_WARNING, "Registry error\n"); 07484 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07485 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07486 break; 07487 } 07488 registry_authrequest(iaxs[fr->callno]->peer, fr->callno); 07489 break; 07490 case IAX_COMMAND_REGACK: 07491 if (iax2_ack_registry(&ies, &sin, fr->callno)) 07492 ast_log(LOG_WARNING, "Registration failure\n"); 07493 /* Send ack immediately, before we destroy */ 07494 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07495 iax2_destroy_nolock(fr->callno); 07496 break; 07497 case IAX_COMMAND_REGREJ: 07498 if (iaxs[fr->callno]->reg) { 07499 if (authdebug) { 07500 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(iabuf, sizeof(iabuf), sin.sin_addr)); 07501 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 07502 } 07503 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 07504 } 07505 /* Send ack immediately, before we destroy */ 07506 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07507 iax2_destroy_nolock(fr->callno); 07508 break; 07509 case IAX_COMMAND_REGAUTH: 07510 /* Authentication request */ 07511 if (registry_rerequest(&ies, fr->callno, &sin)) { 07512 memset(&ied0, 0, sizeof(ied0)); 07513 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07514 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07515 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07516 } 07517 break; 07518 case IAX_COMMAND_TXREJ: 07519 iaxs[fr->callno]->transferring = 0; 07520 if (option_verbose > 2) 07521 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07522 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 07523 if (iaxs[fr->callno]->bridgecallno) { 07524 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 07525 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 07526 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07527 } 07528 } 07529 break; 07530 case IAX_COMMAND_TXREADY: 07531 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07532 iaxs[fr->callno]->transferring = TRANSFER_READY; 07533 if (option_verbose > 2) 07534 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07535 if (iaxs[fr->callno]->bridgecallno) { 07536 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) { 07537 if (option_verbose > 2) 07538 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07539 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07540 07541 /* They're both ready, now release them. */ 07542 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07543 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 07544 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 07545 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07546 07547 /* Stop doing lag & ping requests */ 07548 stop_stuff(fr->callno); 07549 stop_stuff(iaxs[fr->callno]->bridgecallno); 07550 07551 memset(&ied0, 0, sizeof(ied0)); 07552 memset(&ied1, 0, sizeof(ied1)); 07553 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07554 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07555 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07556 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07557 07558 } 07559 } 07560 } 07561 break; 07562 case IAX_COMMAND_TXREQ: 07563 try_transfer(iaxs[fr->callno], &ies); 07564 break; 07565 case IAX_COMMAND_TXCNT: 07566 if (iaxs[fr->callno]->transferring) 07567 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07568 break; 07569 case IAX_COMMAND_TXREL: 07570 /* Send ack immediately, rather than waiting until we've changed addresses */ 07571 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07572 complete_transfer(fr->callno, &ies); 07573 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 07574 break; 07575 case IAX_COMMAND_DPREP: 07576 complete_dpreply(iaxs[fr->callno], &ies); 07577 break; 07578 case IAX_COMMAND_UNSUPPORT: 07579 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07580 break; 07581 case IAX_COMMAND_FWDOWNL: 07582 /* Firmware download */ 07583 memset(&ied0, 0, sizeof(ied0)); 07584 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07585 if (res < 0) 07586 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07587 else if (res > 0) 07588 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07589 else 07590 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07591 break; 07592 default: 07593 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 07594 memset(&ied0, 0, sizeof(ied0)); 07595 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07596 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07597 } 07598 /* Don't actually pass these frames along */ 07599 if ((f.subclass != IAX_COMMAND_ACK) && 07600 (f.subclass != IAX_COMMAND_TXCNT) && 07601 (f.subclass != IAX_COMMAND_TXACC) && 07602 (f.subclass != IAX_COMMAND_INVAL) && 07603 (f.subclass != IAX_COMMAND_VNAK)) { 07604 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07605 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07606 } 07607 ast_mutex_unlock(&iaxsl[fr->callno]); 07608 return 1; 07609 } 07610 /* Unless this is an ACK or INVAL frame, ack it */ 07611 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07612 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07613 } else if (minivid) { 07614 f.frametype = AST_FRAME_VIDEO; 07615 if (iaxs[fr->callno]->videoformat > 0) 07616 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07617 else { 07618 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07619 iax2_vnak(fr->callno); 07620 ast_mutex_unlock(&iaxsl[fr->callno]); 07621 return 1; 07622 } 07623 f.datalen = res - sizeof(*vh); 07624 if (f.datalen) 07625 f.data = buf + sizeof(*vh); 07626 else 07627 f.data = NULL; 07628 #ifdef IAXTESTS 07629 if (test_resync) { 07630 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); 07631 } else 07632 #endif /* IAXTESTS */ 07633 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); 07634 } else { 07635 /* A mini frame */ 07636 f.frametype = AST_FRAME_VOICE; 07637 if (iaxs[fr->callno]->voiceformat > 0) 07638 f.subclass = iaxs[fr->callno]->voiceformat; 07639 else { 07640 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07641 iax2_vnak(fr->callno); 07642 ast_mutex_unlock(&iaxsl[fr->callno]); 07643 return 1; 07644 } 07645 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07646 if (f.datalen < 0) { 07647 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07648 ast_mutex_unlock(&iaxsl[fr->callno]); 07649 return 1; 07650 } 07651 if (f.datalen) 07652 f.data = buf + sizeof(*mh); 07653 else 07654 f.data = NULL; 07655 #ifdef IAXTESTS 07656 if (test_resync) { 07657 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07658 } else 07659 #endif /* IAXTESTS */ 07660 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07661 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07662 } 07663 /* Don't pass any packets until we're started */ 07664 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07665 ast_mutex_unlock(&iaxsl[fr->callno]); 07666 return 1; 07667 } 07668 /* Common things */ 07669 f.src = "IAX2"; 07670 f.mallocd = 0; 07671 f.offset = 0; 07672 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07673 f.samples = ast_codec_get_samples(&f); 07674 /* We need to byteswap incoming slinear samples from network byte order */ 07675 if (f.subclass == AST_FORMAT_SLINEAR) 07676 ast_frame_byteswap_be(&f); 07677 } else 07678 f.samples = 0; 07679 iax_frame_wrap(fr, &f); 07680 07681 /* If this is our most recent packet, use it as our basis for timestamping */ 07682 if (iaxs[fr->callno]->last < fr->ts) { 07683 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07684 fr->outoforder = 0; 07685 } else { 07686 if (option_debug && iaxdebug) 07687 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); 07688 fr->outoforder = -1; 07689 } 07690 #ifdef BRIDGE_OPTIMIZATION 07691 if (iaxs[fr->callno]->bridgecallno) { 07692 forward_delivery(fr); 07693 } else { 07694 duped_fr = iaxfrdup2(fr); 07695 if (duped_fr) { 07696 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07697 } 07698 } 07699 #else 07700 duped_fr = iaxfrdup2(fr); 07701 if (duped_fr) { 07702 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07703 } 07704 #endif 07705 07706 if (iaxs[fr->callno]->last < fr->ts) { 07707 iaxs[fr->callno]->last = fr->ts; 07708 #if 1 07709 if (option_debug && iaxdebug) 07710 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07711 #endif 07712 } 07713 07714 /* Always run again */ 07715 ast_mutex_unlock(&iaxsl[fr->callno]); 07716 return 1; 07717 }
|
|
Definition at line 6179 of file chan_iax2.c. References ast_log(), ast_pthread_create, dp_lookup_thread(), LOG_WARNING, malloc, and strdup. Referenced by socket_read(). 06180 { 06181 pthread_t newthread; 06182 struct dpreq_data *dpr; 06183 dpr = malloc(sizeof(struct dpreq_data)); 06184 if (dpr) { 06185 memset(dpr, 0, sizeof(struct dpreq_data)); 06186 dpr->callno = callno; 06187 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06188 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06189 if (callerid) 06190 dpr->callerid = strdup(callerid); 06191 if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) { 06192 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06193 } 06194 } else 06195 ast_log(LOG_WARNING, "Out of memory!\n"); 06196 }
|
|
Definition at line 8083 of file chan_iax2.c. References ast_pthread_create, netthreadid, and network_thread(). Referenced by load_module(). 08084 { 08085 return ast_pthread_create(&netthreadid, NULL, network_thread, NULL); 08086 }
|
|
Definition at line 5879 of file chan_iax2.c. References ast_sched_del(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, and chan_iax2_pvt::pingid. Referenced by socket_read(). 05880 { 05881 if (iaxs[callno]->lagid > -1) 05882 ast_sched_del(sched, iaxs[callno]->lagid); 05883 iaxs[callno]->lagid = -1; 05884 if (iaxs[callno]->pingid > -1) 05885 ast_sched_del(sched, iaxs[callno]->pingid); 05886 iaxs[callno]->pingid = -1; 05887 if (iaxs[callno]->autoid > -1) 05888 ast_sched_del(sched, iaxs[callno]->autoid); 05889 iaxs[callno]->autoid = -1; 05890 if (iaxs[callno]->initid > -1) 05891 ast_sched_del(sched, iaxs[callno]->initid); 05892 iaxs[callno]->initid = -1; 05893 if (iaxs[callno]->authid > -1) 05894 ast_sched_del(sched, iaxs[callno]->authid); 05895 iaxs[callno]->authid = -1; 05896 #ifdef NEWJB 05897 if (iaxs[callno]->jbid > -1) 05898 ast_sched_del(sched, iaxs[callno]->jbid); 05899 iaxs[callno]->jbid = -1; 05900 #endif 05901 return 0; 05902 }
|
|
Definition at line 6052 of file chan_iax2.c. References ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iaxtrunkdebug, iax2_trunk_peer::lock, ast_peer_list::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, peerl, send_trunk(), and tpeers. Referenced by network_thread(). 06053 { 06054 char buf[1024]; 06055 int res; 06056 char iabuf[INET_ADDRSTRLEN]; 06057 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06058 int processed = 0; 06059 int totalcalls = 0; 06060 #ifdef ZT_TIMERACK 06061 int x = 1; 06062 #endif 06063 struct timeval now; 06064 if (iaxtrunkdebug) 06065 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06066 gettimeofday(&now, NULL); 06067 if (events & AST_IO_PRI) { 06068 #ifdef ZT_TIMERACK 06069 /* Great, this is a timing interface, just call the ioctl */ 06070 if (ioctl(fd, ZT_TIMERACK, &x)) 06071 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06072 res = 0; 06073 #endif 06074 } else { 06075 /* Read and ignore from the pseudo channel for timing */ 06076 res = read(fd, buf, sizeof(buf)); 06077 if (res < 1) { 06078 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06079 ast_mutex_unlock(&peerl.lock); 06080 return 1; 06081 } 06082 } 06083 /* For each peer that supports trunking... */ 06084 ast_mutex_lock(&tpeerlock); 06085 tpeer = tpeers; 06086 while(tpeer) { 06087 processed++; 06088 res = 0; 06089 ast_mutex_lock(&tpeer->lock); 06090 /* We can drop a single tpeer per pass. That makes all this logic 06091 substantially easier */ 06092 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06093 /* Take it out of the list, but don't free it yet, because it 06094 could be in use */ 06095 if (prev) 06096 prev->next = tpeer->next; 06097 else 06098 tpeers = tpeer->next; 06099 drop = tpeer; 06100 } else { 06101 res = send_trunk(tpeer, &now); 06102 if (iaxtrunkdebug) 06103 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(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 06104 } 06105 totalcalls += res; 06106 res = 0; 06107 ast_mutex_unlock(&tpeer->lock); 06108 prev = tpeer; 06109 tpeer = tpeer->next; 06110 } 06111 ast_mutex_unlock(&tpeerlock); 06112 if (drop) { 06113 ast_mutex_lock(&drop->lock); 06114 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06115 because by the time they could get tpeerlock, we've already grabbed it */ 06116 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06117 free(drop->trunkdata); 06118 ast_mutex_unlock(&drop->lock); 06119 ast_mutex_destroy(&drop->lock); 06120 free(drop); 06121 06122 } 06123 if (iaxtrunkdebug) 06124 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06125 iaxtrunkdebug =0; 06126 return 1; 06127 }
|
|
Definition at line 1477 of file chan_iax2.c. References ast_log(), iax_frame::data, iax_frame::datalen, handle_error(), LOG_DEBUG, and option_debug. Referenced by send_trunk(). 01478 { 01479 int res; 01480 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01481 sizeof(*sin)); 01482 if (res < 0) { 01483 if (option_debug) 01484 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01485 handle_error(); 01486 } else 01487 res = 0; 01488 return res; 01489 }
|
|
Definition at line 1159 of file chan_iax2.c. References ast_log(), 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, LOG_WARNING, malloc, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl. Referenced by reload_firmware(). 01160 { 01161 struct stat stbuf; 01162 struct iax_firmware *cur; 01163 int ifd; 01164 int fd; 01165 int res; 01166 01167 struct ast_iax2_firmware_header *fwh, fwh2; 01168 struct MD5Context md5; 01169 unsigned char sum[16]; 01170 unsigned char buf[1024]; 01171 int len, chunk; 01172 char *s2; 01173 char *last; 01174 s2 = alloca(strlen(s) + 100); 01175 if (!s2) { 01176 ast_log(LOG_WARNING, "Alloca failed!\n"); 01177 return -1; 01178 } 01179 last = strrchr(s, '/'); 01180 if (last) 01181 last++; 01182 else 01183 last = s; 01184 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand()); 01185 res = stat(s, &stbuf); 01186 if (res < 0) { 01187 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01188 return -1; 01189 } 01190 /* Make sure it's not a directory */ 01191 if (S_ISDIR(stbuf.st_mode)) 01192 return -1; 01193 ifd = open(s, O_RDONLY); 01194 if (ifd < 0) { 01195 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01196 return -1; 01197 } 01198 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01199 if (fd < 0) { 01200 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01201 close(ifd); 01202 return -1; 01203 } 01204 /* Unlink our newly created file */ 01205 unlink(s2); 01206 01207 /* Now copy the firmware into it */ 01208 len = stbuf.st_size; 01209 while(len) { 01210 chunk = len; 01211 if (chunk > sizeof(buf)) 01212 chunk = sizeof(buf); 01213 res = read(ifd, buf, chunk); 01214 if (res != chunk) { 01215 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01216 close(ifd); 01217 close(fd); 01218 return -1; 01219 } 01220 res = write(fd, buf, chunk); 01221 if (res != chunk) { 01222 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01223 close(ifd); 01224 close(fd); 01225 return -1; 01226 } 01227 len -= chunk; 01228 } 01229 close(ifd); 01230 /* Return to the beginning */ 01231 lseek(fd, 0, SEEK_SET); 01232 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01233 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01234 close(fd); 01235 return -1; 01236 } 01237 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01238 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01239 close(fd); 01240 return -1; 01241 } 01242 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01243 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01244 close(fd); 01245 return -1; 01246 } 01247 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01248 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01249 close(fd); 01250 return -1; 01251 } 01252 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01253 if (!fwh) { 01254 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01255 close(fd); 01256 return -1; 01257 } 01258 MD5Init(&md5); 01259 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01260 MD5Final(sum, &md5); 01261 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01262 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01263 munmap(fwh, stbuf.st_size); 01264 close(fd); 01265 return -1; 01266 } 01267 cur = waresl.wares; 01268 while(cur) { 01269 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01270 /* Found a candidate */ 01271 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01272 /* The version we have on loaded is older, load this one instead */ 01273 break; 01274 /* This version is no newer than what we have. Don't worry about it. 01275 We'll consider it a proper load anyhow though */ 01276 munmap(fwh, stbuf.st_size); 01277 close(fd); 01278 return 0; 01279 } 01280 cur = cur->next; 01281 } 01282 if (!cur) { 01283 /* Allocate a new one and link it */ 01284 cur = malloc(sizeof(struct iax_firmware)); 01285 if (cur) { 01286 memset(cur, 0, sizeof(struct iax_firmware)); 01287 cur->fd = -1; 01288 cur->next = waresl.wares; 01289 waresl.wares = cur; 01290 } 01291 } 01292 if (cur) { 01293 if (cur->fwh) { 01294 munmap(cur->fwh, cur->mmaplen); 01295 } 01296 if (cur->fd > -1) 01297 close(cur->fd); 01298 cur->fwh = fwh; 01299 cur->fd = fd; 01300 cur->mmaplen = stbuf.st_size; 01301 cur->dead = 0; 01302 } 01303 return 0; 01304 }
|
|
Definition at line 5358 of file chan_iax2.c. References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring. Referenced by socket_read(). 05359 { 05360 int newcall = 0; 05361 char newip[256]; 05362 struct iax_ie_data ied; 05363 struct sockaddr_in new; 05364 05365 05366 memset(&ied, 0, sizeof(ied)); 05367 if (ies->apparent_addr) 05368 bcopy(ies->apparent_addr, &new, sizeof(new)); 05369 if (ies->callno) 05370 newcall = ies->callno; 05371 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05372 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05373 return -1; 05374 } 05375 pvt->transfercallno = newcall; 05376 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05377 inet_aton(newip, &pvt->transfer.sin_addr); 05378 pvt->transfer.sin_family = AF_INET; 05379 pvt->transferring = TRANSFER_BEGIN; 05380 pvt->transferid = ies->transferid; 05381 if (ies->transferid) 05382 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05383 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05384 return 0; 05385 }
|
|
Definition at line 837 of file chan_iax2.c. References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT. Referenced by decode_frame(), and socket_read(). 00838 { 00839 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 00840 if (csub & IAX_FLAG_SC_LOG) { 00841 /* special case for 'compressed' -1 */ 00842 if (csub == 0xff) 00843 return -1; 00844 else 00845 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 00846 } 00847 else 00848 return csub; 00849 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 9623 of file chan_iax2.c. References __unload_module(), ast_custom_function_unregister(), ast_mutex_destroy(), iaxq, ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, peerl, userl, and waresl. 09624 { 09625 ast_mutex_destroy(&iaxq.lock); 09626 ast_mutex_destroy(&userl.lock); 09627 ast_mutex_destroy(&peerl.lock); 09628 ast_mutex_destroy(&waresl.lock); 09629 ast_custom_function_unregister(&iaxpeer_function); 09630 return __unload_module(); 09631 }
|
|
Definition at line 3185 of file chan_iax2.c. References ast_mutex_unlock(), and iaxsl. Referenced by iax2_bridge(). 03186 { 03187 ast_mutex_unlock(&iaxsl[callno1]); 03188 ast_mutex_unlock(&iaxsl[callno0]); 03189 }
|
|
Definition at line 2151 of file chan_iax2.c. References ast_log(), iax_frame::callno, iaxdebug, chan_iax2_pvt::last, and iax_frame::ts. Referenced by schedule_delivery(). 02152 { 02153 int x; 02154 02155 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02156 x = fr->ts - iaxs[fr->callno]->last; 02157 if (x < -50000) { 02158 /* Sudden big jump backwards in timestamp: 02159 What likely happened here is that miniframe timestamp has circled but we haven't 02160 gotten the update from the main packet. We'll just pretend that we did, and 02161 update the timestamp appropriately. */ 02162 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02163 if (option_debug && iaxdebug) 02164 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02165 } 02166 if (x > 50000) { 02167 /* Sudden apparent big jump forwards in timestamp: 02168 What's likely happened is this is an old miniframe belonging to the previous 02169 top-16-bit timestamp that has turned up out of order. 02170 Adjust the timestamp appropriately. */ 02171 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02172 if (option_debug && iaxdebug) 02173 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02174 } 02175 } 02176 }
|
|
Definition at line 2181 of file chan_iax2.c. References ast_sched_add(), ast_sched_del(), get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore. Referenced by get_from_jb(), and schedule_delivery(). 02181 { 02182 int when; 02183 02184 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02185 02186 when = jb_next(pvt->jb) - when; 02187 02188 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02189 02190 if(when <= 0) { 02191 /* XXX should really just empty until when > 0.. */ 02192 when = 1; 02193 } 02194 02195 pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt); 02196 }
|
|
Definition at line 986 of file chan_iax2.c. References ast_log(), iaxdebug, LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START. Referenced by find_callno(), and make_trunk(). 00987 { 00988 int max = 1; 00989 int x; 00990 /* XXX Prolly don't need locks here XXX */ 00991 for (x=1;x<TRUNK_CALL_START - 1; x++) { 00992 if (iaxs[x]) 00993 max = x + 1; 00994 } 00995 maxnontrunkcall = max; 00996 if (option_debug && iaxdebug) 00997 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 00998 }
|
|
Definition at line 972 of file chan_iax2.c. References ast_log(), IAX_MAX_CALLS, iaxdebug, LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START. Referenced by iax2_destroy(), and make_trunk(). 00973 { 00974 int max = TRUNK_CALL_START; 00975 int x; 00976 /* XXX Prolly don't need locks here XXX */ 00977 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 00978 if (iaxs[x]) 00979 max = x + 1; 00980 } 00981 maxtrunkcall = max; 00982 if (option_debug && iaxdebug) 00983 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 00984 }
|
|
Definition at line 1715 of file chan_iax2.c. References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno. Referenced by attempt_transmit(). 01716 { 01717 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 01718 struct ast_iax2_full_hdr *fh = f->data; 01719 /* Mark this as a retransmission */ 01720 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 01721 /* Update iseqno */ 01722 f->iseqno = iaxs[f->callno]->iseqno; 01723 fh->iseqno = f->iseqno; 01724 return 0; 01725 }
|
|
Definition at line 5706 of file chan_iax2.c. References iax2_peer::addr, ast_app_has_voicemail(), ast_app_messagecount(), 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(), 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_MESSAGEDETAIL, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), max_reg_expire, min_reg_expire, iax2_peer::name, option_verbose, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3. Referenced by socket_read(). 05707 { 05708 /* Called from IAX thread only, with proper iaxsl lock */ 05709 struct iax_ie_data ied; 05710 struct iax2_peer *p; 05711 int msgcount; 05712 char data[80]; 05713 char iabuf[INET_ADDRSTRLEN]; 05714 int version; 05715 05716 memset(&ied, 0, sizeof(ied)); 05717 05718 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05719 if (!(p = find_peer(name, 1))) { 05720 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05721 return -1; 05722 } 05723 05724 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05725 realtime_update_peer(name, sin); 05726 if (inaddrcmp(&p->addr, sin)) { 05727 if (iax2_regfunk) 05728 iax2_regfunk(p->name, 1); 05729 /* Stash the IP address from which they registered */ 05730 memcpy(&p->addr, sin, sizeof(p->addr)); 05731 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05732 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05733 ast_db_put("IAX/Registry", p->name, data); 05734 if (option_verbose > 2) 05735 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05736 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 05737 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05738 register_peer_exten(p, 1); 05739 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05740 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05741 if (option_verbose > 2) 05742 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05743 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05744 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05745 register_peer_exten(p, 0); 05746 ast_db_del("IAX/Registry", p->name); 05747 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05748 } 05749 /* Update the host */ 05750 /* Verify that the host is really there */ 05751 iax2_poke_peer(p, callno); 05752 } 05753 /* Store socket fd */ 05754 p->sockfd = fd; 05755 /* Setup the expiry */ 05756 if (p->expire > -1) 05757 ast_sched_del(sched, p->expire); 05758 /* treat an unspecified refresh interval as the minimum */ 05759 if (!refresh) 05760 refresh = min_reg_expire; 05761 if (refresh > max_reg_expire) { 05762 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05763 p->name, max_reg_expire, refresh); 05764 p->expiry = max_reg_expire; 05765 } else if (refresh < min_reg_expire) { 05766 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05767 p->name, min_reg_expire, refresh); 05768 p->expiry = min_reg_expire; 05769 } else { 05770 p->expiry = refresh; 05771 } 05772 if (p->expiry && sin->sin_addr.s_addr) 05773 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05774 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05775 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05776 if (sin->sin_addr.s_addr) { 05777 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05778 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05779 if (!ast_strlen_zero(p->mailbox)) { 05780 if (ast_test_flag(p, IAX_MESSAGEDETAIL)) { 05781 int new, old; 05782 ast_app_messagecount(p->mailbox, &new, &old); 05783 if (new > 255) 05784 new = 255; 05785 if (old > 255) 05786 old = 255; 05787 msgcount = (old << 8) | new; 05788 } else { 05789 msgcount = ast_app_has_voicemail(p->mailbox, NULL); 05790 if (msgcount) 05791 msgcount = 65535; 05792 } 05793 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05794 } 05795 if (ast_test_flag(p, IAX_HASCALLERID)) { 05796 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05797 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05798 } 05799 } 05800 version = iax_check_version(devtype); 05801 if (version) 05802 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05803 if (ast_test_flag(p, IAX_TEMPONLY)) 05804 destroy_peer(p); 05805 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05806 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 9732 of file chan_iax2.c. References usecnt. 09733 { 09734 return usecnt; 09735 }
|
|
Definition at line 5977 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::oseqno, and send_packet(). Referenced by socket_read(). 05978 { 05979 struct iax_frame *f; 05980 ast_mutex_lock(&iaxq.lock); 05981 f = iaxq.head; 05982 while(f) { 05983 /* Send a copy immediately */ 05984 if ((f->callno == callno) && iaxs[f->callno] && 05985 (f->oseqno >= last)) { 05986 send_packet(f); 05987 } 05988 f = f->next; 05989 } 05990 ast_mutex_unlock(&iaxq.lock); 05991 }
|
|
Definition at line 225 of file chan_iax2.c. Referenced by build_device(), build_gateway(), check_access(), find_callno(), mkintf(), set_config(), setup_zap(), and tds_log(). |
|
Definition at line 226 of file chan_iax2.c. Referenced by build_device(), build_gateway(), find_callno(), mkintf(), set_config(), and setup_zap(). |
|
Definition at line 163 of file chan_iax2.c. Referenced by register_verify(), set_config(), and socket_read(). |
|
Definition at line 164 of file chan_iax2.c. Referenced by iax2_call(), and set_config(). |
|
Definition at line 143 of file chan_iax2.c. |
|
Definition at line 145 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 jb debug\n" " Enables jitterbuffer debugging information\n" Definition at line 9522 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9514 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 debug\n" " Enables dumping of IAX packets for debugging purposes\n" Definition at line 9506 of file chan_iax2.c. |
|
Definition at line 179 of file chan_iax2.c. Referenced by build_peer(), create_addr(), iax2_do_register(), load_module(), peer_set_srcaddr(), and set_config(). |
|
Definition at line 227 of file chan_iax2.c. Referenced by auth_fail(), set_config(), and socket_read(). |
|
Definition at line 141 of file chan_iax2.c. |
|
Referenced by find_cache(), and iax2_show_cache(). |
|
Definition at line 272 of file chan_iax2.c. Referenced by realtime_peer(), reload_config(), set_config(), and sip_show_settings(). |
|
Definition at line 230 of file chan_iax2.c. |
|
Definition at line 209 of file chan_iax2.c. Referenced by build_peer(), build_user(), iax2_request(), and set_config(). |
|
Definition at line 9548 of file chan_iax2.c. |
|
Definition at line 211 of file chan_iax2.c. Referenced by schedule_delivery(), and set_config(). |
|
Definition at line 228 of file chan_iax2.c. Referenced by build_peer(), build_user(), iax2_call(), and set_config(). |
|
|
|
Definition at line 184 of file chan_iax2.c. Referenced by expire_registry(), reg_source_db(), and update_registry(). |
|
Initial value: "Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n" Definition at line 9468 of file chan_iax2.c. |
|
|
|
Definition at line 9442 of file chan_iax2.c. |
|
Definition at line 753 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n" Definition at line 9530 of file chan_iax2.c. |
|
Definition at line 165 of file chan_iax2.c. Referenced by set_config(), and socket_read(). |
|
Definition at line 213 of file chan_iax2.c. Referenced by calc_rxstamp(), calc_timestamp(), decode_frame(), encrypt_frame(), find_callno(), iax2_bridge(), iax2_do_debug(), iax2_do_register(), iax2_indicate(), iax2_no_debug(), iax2_send(), iax_debug_output(), raw_hangup(), schedule_delivery(), send_packet(), socket_read(), unwrap_timestamp(), update_max_nontrunk(), and update_max_trunk(). |
|
Definition at line 167 of file chan_iax2.c. Referenced by complete_dpreply(), dp_lookup(), and find_cache(). |
|
Definition at line 169 of file chan_iax2.c. Referenced by find_cache(). |
|
Definition at line 9380 of file chan_iax2.c. |
|
Referenced by attempt_transmit(), complete_transfer(), iax2_destroy(), iax2_show_stats(), iax2_transmit(), load_module(), network_thread(), socket_read(), unload_module(), and vnak_retransmit(). |
|
Definition at line 717 of file chan_iax2.c. Referenced by iax_showframe(). |
|
|
Definition at line 215 of file chan_iax2.c. Referenced by iax2_do_trunk_debug(), iax2_no_trunk_debug(), and timing_read(). |
|
Definition at line 206 of file chan_iax2.c. |
|
Definition at line 1846 of file chan_iax2.c. |
|
Definition at line 161 of file chan_iax2.c. Referenced by schedule_delivery(), and set_config(). |
|
Definition at line 153 of file chan_iax2.c. Referenced by find_callno(), make_trunk(), and set_config(). |
|
Definition at line 147 of file chan_iax2.c. |
|
Definition at line 719 of file chan_iax2.c. Referenced by find_callno(), iax2_destroy(), and make_trunk(). |
|
Definition at line 430 of file chan_iax2.c. Referenced by iax2_set_jitter(), schedule_delivery(), and set_config(). |
|
Definition at line 174 of file chan_iax2.c. Referenced by set_config(), and update_registry(). |
|
Definition at line 151 of file chan_iax2.c. Referenced by attempt_transmit(). |
|
Definition at line 150 of file chan_iax2.c. Referenced by build_user(), and set_config(). |
|
Definition at line 156 of file chan_iax2.c. Referenced by new_iax(), schedule_delivery(), and set_config(). |
|
Definition at line 159 of file chan_iax2.c. Referenced by new_iax(), and set_config(). |
|
Definition at line 155 of file chan_iax2.c. Referenced by find_callno(), and update_max_nontrunk(). |
|
Definition at line 154 of file chan_iax2.c. Referenced by find_callno(), and update_max_trunk(). |
|
Definition at line 432 of file chan_iax2.c. Referenced by schedule_delivery(), and set_config(). |
|
Definition at line 173 of file chan_iax2.c. Referenced by build_peer(), expire_registry(), find_callno(), set_config(), and update_registry(). |
|
Definition at line 178 of file chan_iax2.c. |
|
Definition at line 232 of file chan_iax2.c. Referenced by __unload_module(), iax2_transmit(), and start_network_thread(). |
|
Initial value: "Usage: iax2 no jb debug\n" " Disables jitterbuffer debugging information\n" Definition at line 9526 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9518 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no debug\n" " Disables dumping of IAX packets for debugging purposes\n" Definition at line 9510 of file chan_iax2.c. |
|
Definition at line 7806 of file chan_iax2.c. |
|
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 7808 of file chan_iax2.c. |
|
|
|
Definition at line 152 of file chan_iax2.c. Referenced by find_callno(), make_trunk(), and set_config(). |
|
Definition at line 139 of file chan_iax2.c. Referenced by ast_best_codec(). |
|
Initial value: "Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n" Definition at line 9464 of file chan_iax2.c. |
|
Definition at line 7807 of file chan_iax2.c. |
|
Definition at line 148 of file chan_iax2.c. Referenced by register_peer_exten(), reload_config(), set_config(), and sip_show_settings(). |
|
Definition at line 412 of file chan_iax2.c. |
|
Definition at line 158 of file chan_iax2.c. Referenced by new_iax(), and set_config(). |
|
Definition at line 207 of file chan_iax2.c. |
|
Initial value: "Usage: iax show cache\n" " Display currently cached IAX Dialplan results.\n" Definition at line 9456 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show channels\n" " Lists all currently active IAX channels.\n" Definition at line 9484 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show firmware\n" " Lists all known IAX firmware images.\n" Definition at line 9498 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show netstats\n" " Lists network status for all currently active IAX channels.\n" Definition at line 9488 of file chan_iax2.c. |
|
Initial value: "Usage: iax show peer <name>\n" " Display details on specific IAX peer\n" Definition at line 9460 of file chan_iax2.c. |
|
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 9492 of file chan_iax2.c. |
|
Definition at line 9472 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show registry\n" " Lists all registration requests and status.\n" Definition at line 9502 of file chan_iax2.c. |
|
Initial value: "Usage: iax show stats\n" " Display statistics on IAX channel driver.\n" Definition at line 9452 of file chan_iax2.c. |
|
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 9479 of file chan_iax2.c. |
|
Definition at line 142 of file chan_iax2.c. |
|
Definition at line 217 of file chan_iax2.c. Referenced by iax2_test_losspct(), and socket_read(). |
|
Definition at line 176 of file chan_iax2.c. Referenced by build_peer(), build_user(), load_module(), network_thread(), and set_timing(). |
|
Definition at line 171 of file chan_iax2.c. |
|
Referenced by find_tpeer(), and timing_read(). |
|
Definition at line 162 of file chan_iax2.c. Referenced by send_trunk(), set_config(), and set_timing(). |
|
Definition at line 181 of file chan_iax2.c. |
|
|
|
Referenced by iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), try_firmware(), and unload_module(). |