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