#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 8010 of file chan_iax2.c. References iax2_context::context, malloc, and iax2_context::next. Referenced by build_user(). 08011 { 08012 struct iax2_context *con = malloc(sizeof(struct iax2_context)); 08013 if (con) { 08014 ast_copy_string(con->context, context, sizeof(con->context)); 08015 con->next = NULL; 08016 } 08017 return con; 08018 }
|
|
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 8120 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. 08121 { 08122 struct iax2_peer *peer; 08123 struct iax2_peer *prev; 08124 struct ast_ha *oldha = NULL; 08125 int maskfound=0; 08126 int found=0; 08127 prev = NULL; 08128 ast_mutex_lock(&peerl.lock); 08129 if (!temponly) { 08130 peer = peerl.peers; 08131 while(peer) { 08132 if (!strcmp(peer->name, name)) { 08133 break; 08134 } 08135 prev = peer; 08136 peer = peer->next; 08137 } 08138 } else 08139 peer = NULL; 08140 if (peer) { 08141 found++; 08142 oldha = peer->ha; 08143 peer->ha = NULL; 08144 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08145 if (prev) { 08146 prev->next = peer->next; 08147 } else { 08148 peerl.peers = peer->next; 08149 } 08150 ast_mutex_unlock(&peerl.lock); 08151 } else { 08152 ast_mutex_unlock(&peerl.lock); 08153 peer = malloc(sizeof(struct iax2_peer)); 08154 if (peer) { 08155 memset(peer, 0, sizeof(struct iax2_peer)); 08156 peer->expire = -1; 08157 peer->pokeexpire = -1; 08158 peer->sockfd = defaultsockfd; 08159 } 08160 } 08161 if (peer) { 08162 ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08163 peer->encmethods = iax2_encryption; 08164 peer->secret[0] = '\0'; 08165 if (!found) { 08166 ast_copy_string(peer->name, name, sizeof(peer->name)); 08167 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08168 peer->expiry = min_reg_expire; 08169 } 08170 peer->prefs = prefs; 08171 peer->capability = iax2_capability; 08172 peer->smoothing = 0; 08173 peer->pokefreqok = DEFAULT_FREQ_OK; 08174 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08175 peer->context[0] = '\0'; 08176 peer->peercontext[0] = '\0'; 08177 while(v) { 08178 if (!strcasecmp(v->name, "secret")) { 08179 if (!ast_strlen_zero(peer->secret)) { 08180 strncpy(peer->secret + strlen(peer->secret), ";", sizeof(peer->secret)-strlen(peer->secret) - 1); 08181 strncpy(peer->secret + strlen(peer->secret), v->value, sizeof(peer->secret)-strlen(peer->secret) - 1); 08182 } else 08183 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 08184 } else if (!strcasecmp(v->name, "mailbox")) { 08185 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 08186 } else if (!strcasecmp(v->name, "dbsecret")) { 08187 ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret)); 08188 } else if (!strcasecmp(v->name, "mailboxdetail")) { 08189 ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 08190 } else if (!strcasecmp(v->name, "trunk")) { 08191 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08192 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08193 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08194 ast_clear_flag(peer, IAX_TRUNK); 08195 } 08196 } else if (!strcasecmp(v->name, "auth")) { 08197 peer->authmethods = get_auth_methods(v->value); 08198 } else if (!strcasecmp(v->name, "encryption")) { 08199 peer->encmethods = get_encrypt_methods(v->value); 08200 } else if (!strcasecmp(v->name, "notransfer")) { 08201 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08202 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08203 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08204 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08205 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08206 } else if (!strcasecmp(v->name, "host")) { 08207 if (!strcasecmp(v->value, "dynamic")) { 08208 /* They'll register with us */ 08209 ast_set_flag(peer, IAX_DYNAMIC); 08210 if (!found) { 08211 /* Initialize stuff iff we're not found, otherwise 08212 we keep going with what we had */ 08213 memset(&peer->addr.sin_addr, 0, 4); 08214 if (peer->addr.sin_port) { 08215 /* If we've already got a port, make it the default rather than absolute */ 08216 peer->defaddr.sin_port = peer->addr.sin_port; 08217 peer->addr.sin_port = 0; 08218 } 08219 } 08220 } else { 08221 /* Non-dynamic. Make sure we become that way if we're not */ 08222 if (peer->expire > -1) 08223 ast_sched_del(sched, peer->expire); 08224 peer->expire = -1; 08225 ast_clear_flag(peer, IAX_DYNAMIC); 08226 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08227 free(peer); 08228 return NULL; 08229 } 08230 if (!peer->addr.sin_port) 08231 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08232 } 08233 if (!maskfound) 08234 inet_aton("255.255.255.255", &peer->mask); 08235 } else if (!strcasecmp(v->name, "defaultip")) { 08236 if (ast_get_ip(&peer->defaddr, v->value)) { 08237 free(peer); 08238 return NULL; 08239 } 08240 } else if (!strcasecmp(v->name, "sourceaddress")) { 08241 peer_set_srcaddr(peer, v->value); 08242 } else if (!strcasecmp(v->name, "permit") || 08243 !strcasecmp(v->name, "deny")) { 08244 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08245 } else if (!strcasecmp(v->name, "mask")) { 08246 maskfound++; 08247 inet_aton(v->value, &peer->mask); 08248 } else if (!strcasecmp(v->name, "context")) { 08249 if (ast_strlen_zero(peer->context)) 08250 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 08251 } else if (!strcasecmp(v->name, "regexten")) { 08252 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 08253 } else if (!strcasecmp(v->name, "peercontext")) { 08254 if (ast_strlen_zero(peer->peercontext)) 08255 ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext)); 08256 } else if (!strcasecmp(v->name, "port")) { 08257 if (ast_test_flag(peer, IAX_DYNAMIC)) 08258 peer->defaddr.sin_port = htons(atoi(v->value)); 08259 else 08260 peer->addr.sin_port = htons(atoi(v->value)); 08261 } else if (!strcasecmp(v->name, "username")) { 08262 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 08263 } else if (!strcasecmp(v->name, "allow")) { 08264 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08265 } else if (!strcasecmp(v->name, "disallow")) { 08266 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08267 } else if (!strcasecmp(v->name, "callerid")) { 08268 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), 08269 peer->cid_num, sizeof(peer->cid_num)); 08270 ast_set_flag(peer, IAX_HASCALLERID); 08271 } else if (!strcasecmp(v->name, "sendani")) { 08272 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08273 } else if (!strcasecmp(v->name, "inkeys")) { 08274 ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys)); 08275 } else if (!strcasecmp(v->name, "outkey")) { 08276 ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey)); 08277 } else if (!strcasecmp(v->name, "qualify")) { 08278 if (!strcasecmp(v->value, "no")) { 08279 peer->maxms = 0; 08280 } else if (!strcasecmp(v->value, "yes")) { 08281 peer->maxms = DEFAULT_MAXMS; 08282 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08283 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); 08284 peer->maxms = 0; 08285 } 08286 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08287 peer->smoothing = ast_true(v->value); 08288 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08289 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08290 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); 08291 } 08292 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08293 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08294 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); 08295 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08296 } else if (!strcasecmp(v->name, "timezone")) { 08297 ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag)); 08298 }/* else if (strcasecmp(v->name,"type")) */ 08299 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08300 v=v->next; 08301 } 08302 if (!peer->authmethods) 08303 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08304 ast_clear_flag(peer, IAX_DELME); 08305 /* Make sure these are IPv4 addresses */ 08306 peer->addr.sin_family = AF_INET; 08307 } 08308 if (oldha) 08309 ast_free_ha(oldha); 08310 return peer; 08311 }
|
|
Definition at line 8314 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. 08315 { 08316 struct iax2_user *prev, *user; 08317 struct iax2_context *con, *conl = NULL; 08318 struct ast_ha *oldha = NULL; 08319 struct iax2_context *oldcon = NULL; 08320 int format; 08321 char *varname = NULL, *varval = NULL; 08322 struct ast_variable *tmpvar = NULL; 08323 08324 prev = NULL; 08325 ast_mutex_lock(&userl.lock); 08326 if (!temponly) { 08327 user = userl.users; 08328 while(user) { 08329 if (!strcmp(user->name, name)) { 08330 break; 08331 } 08332 prev = user; 08333 user = user->next; 08334 } 08335 } else 08336 user = NULL; 08337 08338 if (user) { 08339 oldha = user->ha; 08340 oldcon = user->contexts; 08341 user->ha = NULL; 08342 user->contexts = NULL; 08343 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08344 if (prev) { 08345 prev->next = user->next; 08346 } else { 08347 userl.users = user->next; 08348 } 08349 ast_mutex_unlock(&userl.lock); 08350 } else { 08351 ast_mutex_unlock(&userl.lock); 08352 user = malloc(sizeof(struct iax2_user)); 08353 if (user) 08354 memset(user, 0, sizeof(struct iax2_user)); 08355 } 08356 08357 if (user) { 08358 memset(user, 0, sizeof(struct iax2_user)); 08359 user->prefs = prefs; 08360 user->capability = iax2_capability; 08361 user->encmethods = iax2_encryption; 08362 ast_copy_string(user->name, name, sizeof(user->name)); 08363 ast_copy_string(user->language, language, sizeof(user->language)); 08364 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08365 while(v) { 08366 if (!strcasecmp(v->name, "context")) { 08367 con = build_context(v->value); 08368 if (con) { 08369 if (conl) 08370 conl->next = con; 08371 else 08372 user->contexts = con; 08373 conl = con; 08374 } 08375 } else if (!strcasecmp(v->name, "permit") || 08376 !strcasecmp(v->name, "deny")) { 08377 user->ha = ast_append_ha(v->name, v->value, user->ha); 08378 } else if (!strcasecmp(v->name, "setvar")) { 08379 varname = ast_strdupa(v->value); 08380 if (varname && (varval = strchr(varname,'='))) { 08381 *varval = '\0'; 08382 varval++; 08383 if((tmpvar = ast_variable_new(varname, varval))) { 08384 tmpvar->next = user->vars; 08385 user->vars = tmpvar; 08386 } 08387 } 08388 } else if (!strcasecmp(v->name, "allow")) { 08389 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08390 } else if (!strcasecmp(v->name, "disallow")) { 08391 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08392 } else if (!strcasecmp(v->name, "trunk")) { 08393 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08394 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08395 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08396 ast_clear_flag(user, IAX_TRUNK); 08397 } 08398 } else if (!strcasecmp(v->name, "auth")) { 08399 user->authmethods = get_auth_methods(v->value); 08400 } else if (!strcasecmp(v->name, "encryption")) { 08401 user->encmethods = get_encrypt_methods(v->value); 08402 } else if (!strcasecmp(v->name, "notransfer")) { 08403 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08404 } else if (!strcasecmp(v->name, "codecpriority")) { 08405 if(!strcasecmp(v->value, "caller")) 08406 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08407 else if(!strcasecmp(v->value, "disabled")) 08408 ast_set_flag(user, IAX_CODEC_NOPREFS); 08409 else if(!strcasecmp(v->value, "reqonly")) { 08410 ast_set_flag(user, IAX_CODEC_NOCAP); 08411 ast_set_flag(user, IAX_CODEC_NOPREFS); 08412 } 08413 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08414 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08415 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08416 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08417 } else if (!strcasecmp(v->name, "dbsecret")) { 08418 ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret)); 08419 } else if (!strcasecmp(v->name, "secret")) { 08420 if (!ast_strlen_zero(user->secret)) { 08421 strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1); 08422 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); 08423 } else 08424 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 08425 } else if (!strcasecmp(v->name, "callerid")) { 08426 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 08427 ast_set_flag(user, IAX_HASCALLERID); 08428 } else if (!strcasecmp(v->name, "accountcode")) { 08429 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 08430 } else if (!strcasecmp(v->name, "language")) { 08431 ast_copy_string(user->language, v->value, sizeof(user->language)); 08432 } else if (!strcasecmp(v->name, "amaflags")) { 08433 format = ast_cdr_amaflags2int(v->value); 08434 if (format < 0) { 08435 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08436 } else { 08437 user->amaflags = format; 08438 } 08439 } else if (!strcasecmp(v->name, "inkeys")) { 08440 ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys)); 08441 }/* else if (strcasecmp(v->name,"type")) */ 08442 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08443 v = v->next; 08444 } 08445 if (!user->authmethods) { 08446 if (!ast_strlen_zero(user->secret)) { 08447 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08448 if (!ast_strlen_zero(user->inkeys)) 08449 user->authmethods |= IAX_AUTH_RSA; 08450 } else if (!ast_strlen_zero(user->inkeys)) { 08451 user->authmethods = IAX_AUTH_RSA; 08452 } else { 08453 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08454 } 08455 } 08456 ast_clear_flag(user, IAX_DELME); 08457 } 08458 if (oldha) 08459 ast_free_ha(oldha); 08460 if (oldcon) 08461 free_context(oldcon); 08462 return user; 08463 }
|
|
Definition at line 8887 of file chan_iax2.c. References ast_mutex_trylock(), ast_mutex_unlock(), IAX_MAX_CALLS, and iaxsl. Referenced by find_cache(). 08888 { 08889 struct sockaddr_in sin; 08890 int x; 08891 int callno; 08892 struct iax_ie_data ied; 08893 struct create_addr_info cai; 08894 struct parsed_dial_string pds; 08895 char *tmpstr; 08896 08897 for (x=0; x<IAX_MAX_CALLS; x++) { 08898 /* Look for an *exact match* call. Once a call is negotiated, it can only 08899 look up entries for a single context */ 08900 if (!ast_mutex_trylock(&iaxsl[x])) { 08901 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 08902 return x; 08903 ast_mutex_unlock(&iaxsl[x]); 08904 } 08905 } 08906 08907 /* No match found, we need to create a new one */ 08908 08909 memset(&cai, 0, sizeof(cai)); 08910 memset(&ied, 0, sizeof(ied)); 08911 memset(&pds, 0, sizeof(pds)); 08912 08913 tmpstr = ast_strdupa(data); 08914 parse_dial_string(tmpstr, &pds); 08915 08916 /* Populate our address from the given */ 08917 if (create_addr(pds.peer, &sin, &cai)) 08918 return -1; 08919 08920 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 08921 pds.peer, pds.username, pds.password, pds.context); 08922 08923 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 08924 if (callno < 1) { 08925 ast_log(LOG_WARNING, "Unable to create call\n"); 08926 return -1; 08927 } 08928 08929 ast_mutex_lock(&iaxsl[callno]); 08930 ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot)); 08931 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 08932 08933 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 08934 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 08935 /* the string format is slightly different from a standard dial string, 08936 because the context appears in the 'exten' position 08937 */ 08938 if (pds.exten) 08939 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 08940 if (pds.username) 08941 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 08942 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 08943 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 08944 /* Keep password handy */ 08945 if (pds.password) 08946 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 08947 if (pds.key) 08948 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 08949 /* Start the call going */ 08950 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 08951 08952 return callno; 08953 }
|
|
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 8039 of file chan_iax2.c. References ast_log(), and LOG_ERROR. Referenced by peer_set_srcaddr(). 08040 { 08041 int sd; 08042 int res; 08043 08044 sd = socket(AF_INET, SOCK_DGRAM, 0); 08045 if (sd < 0) { 08046 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08047 return -1; 08048 } 08049 08050 res = bind(sd, sa, salen); 08051 if (res < 0) { 08052 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08053 close(sd); 08054 return 1; 08055 } 08056 08057 close(sd); 08058 return 0; 08059 }
|
|
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 8465 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. 08466 { 08467 struct iax2_user *user; 08468 struct iax2_peer *peer; 08469 struct iax2_registry *reg, *regl; 08470 08471 ast_mutex_lock(&userl.lock); 08472 for (user=userl.users;user;) { 08473 ast_set_flag(user, IAX_DELME); 08474 user = user->next; 08475 } 08476 ast_mutex_unlock(&userl.lock); 08477 for (reg = registrations;reg;) { 08478 regl = reg; 08479 reg = reg->next; 08480 if (regl->expire > -1) { 08481 ast_sched_del(sched, regl->expire); 08482 } 08483 if (regl->callno) { 08484 /* XXX Is this a potential lock? I don't think so, but you never know */ 08485 ast_mutex_lock(&iaxsl[regl->callno]); 08486 if (iaxs[regl->callno]) { 08487 iaxs[regl->callno]->reg = NULL; 08488 iax2_destroy_nolock(regl->callno); 08489 } 08490 ast_mutex_unlock(&iaxsl[regl->callno]); 08491 } 08492 free(regl); 08493 } 08494 registrations = NULL; 08495 ast_mutex_lock(&peerl.lock); 08496 for (peer=peerl.peers;peer;) { 08497 /* Assume all will be deleted, and we'll find out for sure later */ 08498 ast_set_flag(peer, IAX_DELME); 08499 peer = peer->next; 08500 } 08501 ast_mutex_unlock(&peerl.lock); 08502 }
|
|
Provides a description of the module.
Definition at line 9651 of file chan_iax2.c. References desc. 09652 { 09653 return (char *) desc; 09654 }
|
|
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 8534 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(). 08535 { 08536 int x; 08537 ast_free_ha(peer->ha); 08538 for (x=0;x<IAX_MAX_CALLS;x++) { 08539 ast_mutex_lock(&iaxsl[x]); 08540 if (iaxs[x] && (iaxs[x]->peerpoke == peer)) { 08541 iax2_destroy(x); 08542 } 08543 ast_mutex_unlock(&iaxsl[x]); 08544 } 08545 /* Delete it, it needs to disappear */ 08546 if (peer->expire > -1) 08547 ast_sched_del(sched, peer->expire); 08548 if (peer->pokeexpire > -1) 08549 ast_sched_del(sched, peer->pokeexpire); 08550 if (peer->callno > 0) 08551 iax2_destroy(peer->callno); 08552 register_peer_exten(peer, 0); 08553 if (peer->dnsmgr) 08554 ast_dnsmgr_release(peer->dnsmgr); 08555 free(peer); 08556 }
|
|
Definition at line 8504 of file chan_iax2.c. References ast_free_ha(), ast_variables_destroy(), free, free_context(), and user. Referenced by check_access(), and prune_users(). 08505 { 08506 ast_free_ha(user->ha); 08507 free_context(user->contexts); 08508 if(user->vars) { 08509 ast_variables_destroy(user->vars); 08510 user->vars = NULL; 08511 } 08512 free(user); 08513 }
|
|
|
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 8955 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(). 08956 { 08957 struct iax2_dpcache *dp, *prev = NULL, *next; 08958 struct timeval tv; 08959 int x; 08960 int com[2]; 08961 int timeout; 08962 int old=0; 08963 int outfd; 08964 int abort; 08965 int callno; 08966 struct ast_channel *c; 08967 struct ast_frame *f; 08968 gettimeofday(&tv, NULL); 08969 dp = dpcache; 08970 while(dp) { 08971 next = dp->next; 08972 /* Expire old caches */ 08973 if (ast_tvcmp(tv, dp->expiry) > 0) { 08974 /* It's expired, let it disappear */ 08975 if (prev) 08976 prev->next = dp->next; 08977 else 08978 dpcache = dp->next; 08979 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 08980 /* Free memory and go again */ 08981 free(dp); 08982 } else { 08983 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); 08984 } 08985 dp = next; 08986 continue; 08987 } 08988 /* We found an entry that matches us! */ 08989 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 08990 break; 08991 prev = dp; 08992 dp = next; 08993 } 08994 if (!dp) { 08995 /* No matching entry. Create a new one. */ 08996 /* First, can we make a callno? */ 08997 callno = cache_get_callno_locked(data); 08998 if (callno < 0) { 08999 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09000 return NULL; 09001 } 09002 dp = malloc(sizeof(struct iax2_dpcache)); 09003 if (!dp) { 09004 ast_mutex_unlock(&iaxsl[callno]); 09005 return NULL; 09006 } 09007 memset(dp, 0, sizeof(struct iax2_dpcache)); 09008 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09009 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09010 gettimeofday(&dp->expiry, NULL); 09011 dp->orig = dp->expiry; 09012 /* Expires in 30 mins by default */ 09013 dp->expiry.tv_sec += iaxdefaultdpcache; 09014 dp->next = dpcache; 09015 dp->flags = CACHE_FLAG_PENDING; 09016 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09017 dp->waiters[x] = -1; 09018 dpcache = dp; 09019 dp->peer = iaxs[callno]->dpentries; 09020 iaxs[callno]->dpentries = dp; 09021 /* Send the request if we're already up */ 09022 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 09023 iax2_dprequest(dp, callno); 09024 ast_mutex_unlock(&iaxsl[callno]); 09025 } 09026 /* By here we must have a dp */ 09027 if (dp->flags & CACHE_FLAG_PENDING) { 09028 /* Okay, here it starts to get nasty. We need a pipe now to wait 09029 for a reply to come back so long as it's pending */ 09030 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09031 /* Find an empty slot */ 09032 if (dp->waiters[x] < 0) 09033 break; 09034 } 09035 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09036 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09037 return NULL; 09038 } 09039 if (pipe(com)) { 09040 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09041 return NULL; 09042 } 09043 dp->waiters[x] = com[1]; 09044 /* Okay, now we wait */ 09045 timeout = iaxdefaulttimeout * 1000; 09046 /* Temporarily unlock */ 09047 ast_mutex_unlock(&dpcache_lock); 09048 /* Defer any dtmf */ 09049 if (chan) 09050 old = ast_channel_defer_dtmf(chan); 09051 abort = 0; 09052 while(timeout) { 09053 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09054 if (outfd > -1) { 09055 break; 09056 } 09057 if (c) { 09058 f = ast_read(c); 09059 if (f) 09060 ast_frfree(f); 09061 else { 09062 /* Got hung up on, abort! */ 09063 break; 09064 abort = 1; 09065 } 09066 } 09067 } 09068 if (!timeout) { 09069 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09070 } 09071 ast_mutex_lock(&dpcache_lock); 09072 dp->waiters[x] = -1; 09073 close(com[1]); 09074 close(com[0]); 09075 if (abort) { 09076 /* Don't interpret anything, just abort. Not sure what th epoint 09077 of undeferring dtmf on a hung up channel is but hey whatever */ 09078 if (!old && chan) 09079 ast_channel_undefer_dtmf(chan); 09080 return NULL; 09081 } 09082 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09083 /* Now to do non-independent analysis the results of our wait */ 09084 if (dp->flags & CACHE_FLAG_PENDING) { 09085 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09086 pending. Don't let it take as long to timeout. */ 09087 dp->flags &= ~CACHE_FLAG_PENDING; 09088 dp->flags |= CACHE_FLAG_TIMEOUT; 09089 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09090 systems without leaving it unavailable once the server comes back online */ 09091 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09092 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09093 if (dp->waiters[x] > -1) 09094 write(dp->waiters[x], "asdf", 4); 09095 } 09096 } 09097 /* Our caller will obtain the rest */ 09098 if (!old && chan) 09099 ast_channel_undefer_dtmf(chan); 09100 } 09101 return dp; 09102 }
|
|
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 7850 of file chan_iax2.c. References free, and iax2_context::next. Referenced by build_user(), and destroy_user(). 07851 { 07852 struct iax2_context *conl; 07853 while(con) { 07854 conl = con; 07855 con = con->next; 07856 free(conl); 07857 } 07858 }
|
|
Definition at line 9227 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. 09228 { 09229 char *ret = NULL; 09230 struct iax2_peer *peer; 09231 char *peername, *colname; 09232 char iabuf[INET_ADDRSTRLEN]; 09233 09234 if (!(peername = ast_strdupa(data))) { 09235 ast_log(LOG_ERROR, "Memory Error!\n"); 09236 return ret; 09237 } 09238 09239 /* if our channel, return the IP address of the endpoint of current channel */ 09240 if (!strcmp(peername,"CURRENTCHANNEL")) { 09241 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt); 09242 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len); 09243 return buf; 09244 } 09245 09246 if ((colname = strchr(peername, ':'))) { 09247 *colname = '\0'; 09248 colname++; 09249 } else { 09250 colname = "ip"; 09251 } 09252 if (!(peer = find_peer(peername, 1))) 09253 return ret; 09254 09255 if (!strcasecmp(colname, "ip")) { 09256 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09257 } else if (!strcasecmp(colname, "status")) { 09258 peer_status(peer, buf, len); 09259 } else if (!strcasecmp(colname, "mailbox")) { 09260 ast_copy_string(buf, peer->mailbox, len); 09261 } else if (!strcasecmp(colname, "context")) { 09262 ast_copy_string(buf, peer->context, len); 09263 } else if (!strcasecmp(colname, "expire")) { 09264 snprintf(buf, len, "%d", peer->expire); 09265 } else if (!strcasecmp(colname, "dynamic")) { 09266 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09267 } else if (!strcasecmp(colname, "callerid_name")) { 09268 ast_copy_string(buf, peer->cid_name, len); 09269 } else if (!strcasecmp(colname, "callerid_num")) { 09270 ast_copy_string(buf, peer->cid_num, len); 09271 } else if (!strcasecmp(colname, "codecs")) { 09272 ast_getformatname_multiple(buf, len -1, peer->capability); 09273 } else if (!strncasecmp(colname, "codec[", 6)) { 09274 char *codecnum, *ptr; 09275 int index = 0, codec = 0; 09276 09277 codecnum = strchr(colname, '['); 09278 *codecnum = '\0'; 09279 codecnum++; 09280 if ((ptr = strchr(codecnum, ']'))) { 09281 *ptr = '\0'; 09282 } 09283 index = atoi(codecnum); 09284 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09285 ast_copy_string(buf, ast_getformatname(codec), len); 09286 } 09287 } 09288 ret = buf; 09289 09290 return ret; 09291 }
|
|
Definition at line 8020 of file chan_iax2.c. References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA. Referenced by build_peer(), and build_user(). 08021 { 08022 int methods = 0; 08023 if (strstr(value, "rsa")) 08024 methods |= IAX_AUTH_RSA; 08025 if (strstr(value, "md5")) 08026 methods |= IAX_AUTH_MD5; 08027 if (strstr(value, "plaintext")) 08028 methods |= IAX_AUTH_PLAINTEXT; 08029 return methods; 08030 }
|
|
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 9128 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. 09129 { 09130 int res = 0; 09131 struct iax2_dpcache *dp; 09132 #if 0 09133 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09134 #endif 09135 if ((priority != 1) && (priority != 2)) 09136 return 0; 09137 ast_mutex_lock(&dpcache_lock); 09138 dp = find_cache(chan, data, context, exten, priority); 09139 if (dp) { 09140 if (dp->flags & CACHE_FLAG_CANEXIST) 09141 res= 1; 09142 } 09143 ast_mutex_unlock(&dpcache_lock); 09144 if (!dp) { 09145 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09146 } 09147 return res; 09148 }
|
|
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 9316 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. 09317 { 09318 char *dest = (char *) data; 09319 struct iax2_peer *p; 09320 int found = 0; 09321 char *ext, *host; 09322 char tmp[256]; 09323 int res = AST_DEVICE_INVALID; 09324 09325 ast_copy_string(tmp, dest, sizeof(tmp)); 09326 host = strchr(tmp, '@'); 09327 if (host) { 09328 *host = '\0'; 09329 host++; 09330 ext = tmp; 09331 } else { 09332 host = tmp; 09333 ext = NULL; 09334 } 09335 09336 if (option_debug > 2) 09337 ast_log(LOG_DEBUG, "Checking device state for device %s\n", dest); 09338 09339 /* SLD: FIXME: second call to find_peer during registration */ 09340 p = find_peer(host, 1); 09341 if (p) { 09342 found++; 09343 res = AST_DEVICE_UNAVAILABLE; 09344 if (option_debug > 2) 09345 ast_log(LOG_DEBUG, "iax2_devicestate(%s): Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09346 host, dest, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09347 09348 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09349 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09350 /* Peer is registered, or have default IP address 09351 and a valid registration */ 09352 if (p->historicms == 0 || p->historicms <= p->maxms) 09353 /* let the core figure out whether it is in use or not */ 09354 res = AST_DEVICE_UNKNOWN; 09355 } 09356 } else { 09357 if (option_debug > 2) 09358 ast_log(LOG_DEBUG, "Devicestate: Can't find peer %s.\n", host); 09359 } 09360 09361 if (p && ast_test_flag(p, IAX_TEMPONLY)) 09362 destroy_peer(p); 09363 return res; 09364 }
|
|
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 7641 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(). 07642 { 07643 struct iax_ie_data ied; 07644 if (option_debug && iaxdebug) 07645 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07646 if (!reg->callno) { 07647 if (option_debug) 07648 ast_log(LOG_DEBUG, "Allocate call number\n"); 07649 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07650 if (reg->callno < 1) { 07651 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07652 return -1; 07653 } else if (option_debug) 07654 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07655 iaxs[reg->callno]->reg = reg; 07656 } 07657 /* Schedule the next registration attempt */ 07658 if (reg->expire > -1) 07659 ast_sched_del(sched, reg->expire); 07660 /* Setup the next registration a little early */ 07661 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07662 /* Send the request */ 07663 memset(&ied, 0, sizeof(ied)); 07664 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07665 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07666 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07667 reg->regstate = REG_STATE_REGSENT; 07668 return 0; 07669 }
|
|
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 9174 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. 09175 { 09176 char odata[256]; 09177 char req[256]; 09178 char *ncontext; 09179 char *dialstatus; 09180 struct iax2_dpcache *dp; 09181 struct ast_app *dial; 09182 #if 0 09183 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); 09184 #endif 09185 if (priority == 2) { 09186 /* Indicate status, can be overridden in dialplan */ 09187 dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09188 if (dialstatus) { 09189 dial = pbx_findapp(dialstatus); 09190 if (dial) 09191 pbx_exec(chan, dial, "", newstack); 09192 } 09193 return -1; 09194 } else if (priority != 1) 09195 return -1; 09196 ast_mutex_lock(&dpcache_lock); 09197 dp = find_cache(chan, data, context, exten, priority); 09198 if (dp) { 09199 if (dp->flags & CACHE_FLAG_EXISTS) { 09200 ast_copy_string(odata, data, sizeof(odata)); 09201 ncontext = strchr(odata, '/'); 09202 if (ncontext) { 09203 *ncontext = '\0'; 09204 ncontext++; 09205 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09206 } else { 09207 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09208 } 09209 if (option_verbose > 2) 09210 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09211 } else { 09212 ast_mutex_unlock(&dpcache_lock); 09213 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09214 return -1; 09215 } 09216 } 09217 ast_mutex_unlock(&dpcache_lock); 09218 dial = pbx_findapp("Dial"); 09219 if (dial) { 09220 return pbx_exec(chan, dial, req, newstack); 09221 } else { 09222 ast_log(LOG_WARNING, "No dial application registered\n"); 09223 } 09224 return -1; 09225 }
|
|
Definition at line 9105 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. 09106 { 09107 struct iax2_dpcache *dp; 09108 int res = 0; 09109 #if 0 09110 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09111 #endif 09112 if ((priority != 1) && (priority != 2)) 09113 return 0; 09114 ast_mutex_lock(&dpcache_lock); 09115 dp = find_cache(chan, data, context, exten, priority); 09116 if (dp) { 09117 if (dp->flags & CACHE_FLAG_EXISTS) 09118 res= 1; 09119 } 09120 ast_mutex_unlock(&dpcache_lock); 09121 if (!dp) { 09122 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09123 } 09124 return res; 09125 }
|
|
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 9151 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. 09152 { 09153 int res = 0; 09154 struct iax2_dpcache *dp; 09155 #if 0 09156 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09157 #endif 09158 if ((priority != 1) && (priority != 2)) 09159 return 0; 09160 ast_mutex_lock(&dpcache_lock); 09161 dp = find_cache(chan, data, context, exten, priority); 09162 if (dp) { 09163 if (dp->flags & CACHE_FLAG_MATCHMORE) 09164 res= 1; 09165 } 09166 ast_mutex_unlock(&dpcache_lock); 09167 if (!dp) { 09168 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09169 } 09170 return res; 09171 }
|
|
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 7792 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(). 07793 { 07794 struct iax2_peer *peer = data; 07795 peer->pokeexpire = -1; 07796 if (peer->lastms > -1) { 07797 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07798 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07799 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07800 } 07801 if (peer->callno > 0) 07802 iax2_destroy(peer->callno); 07803 peer->callno = 0; 07804 peer->lastms = -1; 07805 /* Try again quickly */ 07806 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07807 return 0; 07808 }
|
|
Definition at line 7810 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(). 07811 { 07812 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07813 /* IF we have no IP, or this isn't to be monitored, return 07814 imeediately after clearing things out */ 07815 peer->lastms = 0; 07816 peer->historicms = 0; 07817 peer->pokeexpire = -1; 07818 peer->callno = 0; 07819 return 0; 07820 } 07821 if (peer->callno > 0) { 07822 ast_log(LOG_NOTICE, "Still have a callno...\n"); 07823 iax2_destroy(peer->callno); 07824 } 07825 if (heldcall) 07826 ast_mutex_unlock(&iaxsl[heldcall]); 07827 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 07828 if (heldcall) 07829 ast_mutex_lock(&iaxsl[heldcall]); 07830 if (peer->callno < 1) { 07831 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 07832 return -1; 07833 } 07834 if (peer->pokeexpire > -1) 07835 ast_sched_del(sched, peer->pokeexpire); 07836 /* Speed up retransmission times */ 07837 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 07838 iaxs[peer->callno]->peerpoke = peer; 07839 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 07840 07841 /* If the host is already unreachable then use the unreachable interval instead */ 07842 if (peer->lastms < 0) { 07843 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 07844 } else 07845 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 07846 07847 return 0; 07848 }
|
|
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 7770 of file chan_iax2.c. References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 07771 { 07772 int force = 0; 07773 int res; 07774 if (argc < 4) 07775 return RESULT_SHOWUSAGE; 07776 if ((argc > 4)) { 07777 if (!strcasecmp(argv[4], "forced")) 07778 force = 1; 07779 else 07780 return RESULT_SHOWUSAGE; 07781 } 07782 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07783 if (res < 0) 07784 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07785 else if (res < 1) 07786 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07787 else 07788 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07789 return RESULT_SUCCESS; 07790 }
|
|
Definition at line 7671 of file chan_iax2.c. References iax_prov_complete_template(). 07672 { 07673 if (pos != 3) 07674 return NULL; 07675 return iax_prov_complete_template(line, word, pos, state); 07676 }
|
|
Definition at line 7678 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(). 07679 { 07680 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07681 is found for template */ 07682 struct iax_ie_data provdata; 07683 struct iax_ie_data ied; 07684 unsigned int sig; 07685 struct sockaddr_in sin; 07686 int callno; 07687 struct create_addr_info cai; 07688 07689 memset(&cai, 0, sizeof(cai)); 07690 07691 if (option_debug) 07692 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07693 07694 if (iax_provision_build(&provdata, &sig, template, force)) { 07695 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07696 return 0; 07697 } 07698 07699 if (end) { 07700 memcpy(&sin, end, sizeof(sin)); 07701 cai.sockfd = sockfd; 07702 } else if (create_addr(dest, &sin, &cai)) 07703 return -1; 07704 07705 /* Build the rest of the message */ 07706 memset(&ied, 0, sizeof(ied)); 07707 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07708 07709 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07710 if (!callno) 07711 return -1; 07712 07713 ast_mutex_lock(&iaxsl[callno]); 07714 if (iaxs[callno]) { 07715 /* Schedule autodestruct in case they don't ever give us anything back */ 07716 if (iaxs[callno]->autoid > -1) 07717 ast_sched_del(sched, iaxs[callno]->autoid); 07718 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07719 ast_set_flag(iaxs[callno], IAX_PROVISION); 07720 /* Got a call number now, so go ahead and send the provisioning information */ 07721 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07722 } 07723 ast_mutex_unlock(&iaxsl[callno]); 07724 07725 return 1; 07726 }
|
|
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 8877 of file chan_iax2.c. References reload_config(). 08878 { 08879 return reload_config(); 08880 }
|
|
Definition at line 7860 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. 07861 { 07862 int callno; 07863 int res; 07864 int fmt, native; 07865 struct sockaddr_in sin; 07866 struct ast_channel *c; 07867 struct parsed_dial_string pds; 07868 struct create_addr_info cai; 07869 char *tmpstr; 07870 07871 memset(&pds, 0, sizeof(pds)); 07872 tmpstr = ast_strdupa(data); 07873 parse_dial_string(tmpstr, &pds); 07874 07875 memset(&cai, 0, sizeof(cai)); 07876 cai.capability = iax2_capability; 07877 07878 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07879 07880 if (!pds.peer) { 07881 ast_log(LOG_WARNING, "No peer given\n"); 07882 return NULL; 07883 } 07884 07885 07886 /* Populate our address from the given */ 07887 if (create_addr(pds.peer, &sin, &cai)) { 07888 *cause = AST_CAUSE_UNREGISTERED; 07889 return NULL; 07890 } 07891 07892 if (pds.port) 07893 sin.sin_port = htons(atoi(pds.port)); 07894 07895 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07896 if (callno < 1) { 07897 ast_log(LOG_WARNING, "Unable to create call\n"); 07898 *cause = AST_CAUSE_CONGESTION; 07899 return NULL; 07900 } 07901 07902 ast_mutex_lock(&iaxsl[callno]); 07903 07904 /* If this is a trunk, update it now */ 07905 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07906 if (ast_test_flag(&cai, IAX_TRUNK)) 07907 callno = make_trunk(callno, 1); 07908 iaxs[callno]->maxtime = cai.maxtime; 07909 if (cai.found) 07910 ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host)); 07911 07912 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 07913 07914 ast_mutex_unlock(&iaxsl[callno]); 07915 07916 if (c) { 07917 /* Choose a format we can live with */ 07918 if (c->nativeformats & format) 07919 c->nativeformats &= format; 07920 else { 07921 native = c->nativeformats; 07922 fmt = format; 07923 res = ast_translator_best_choice(&fmt, &native); 07924 if (res < 0) { 07925 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 07926 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 07927 ast_hangup(c); 07928 return NULL; 07929 } 07930 c->nativeformats = native; 07931 } 07932 c->readformat = ast_best_codec(c->nativeformats); 07933 c->writeformat = c->readformat; 07934 } 07935 07936 return c; 07937 }
|
|
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 9661 of file chan_iax2.c. References ASTERISK_GPL_KEY. 09662 { 09663 return ASTERISK_GPL_KEY; 09664 }
|
|
|
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 7939 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(). 07940 { 07941 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 07942 from the network, and queue them for delivery to the channels */ 07943 int res, count; 07944 struct iax_frame *f, *freeme; 07945 if (timingfd > -1) 07946 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 07947 for(;;) { 07948 /* Go through the queue, sending messages which have not yet been 07949 sent, and scheduling retransmissions if appropriate */ 07950 ast_mutex_lock(&iaxq.lock); 07951 f = iaxq.head; 07952 count = 0; 07953 while(f) { 07954 freeme = NULL; 07955 if (!f->sentyet) { 07956 f->sentyet++; 07957 /* Send a copy immediately -- errors here are ok, so don't bother locking */ 07958 if (iaxs[f->callno]) { 07959 send_packet(f); 07960 count++; 07961 } 07962 if (f->retries < 0) { 07963 /* This is not supposed to be retransmitted */ 07964 if (f->prev) 07965 f->prev->next = f->next; 07966 else 07967 iaxq.head = f->next; 07968 if (f->next) 07969 f->next->prev = f->prev; 07970 else 07971 iaxq.tail = f->prev; 07972 iaxq.count--; 07973 /* Free the iax frame */ 07974 freeme = f; 07975 } else { 07976 /* We need reliable delivery. Schedule a retransmission */ 07977 f->retries++; 07978 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 07979 } 07980 } 07981 f = f->next; 07982 if (freeme) 07983 iax_frame_free(freeme); 07984 } 07985 ast_mutex_unlock(&iaxq.lock); 07986 if (count >= 20) 07987 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 07988 07989 /* Now do the IO, and run scheduled tasks */ 07990 res = ast_sched_wait(sched); 07991 if ((res > 1000) || (res < 0)) 07992 res = 1000; 07993 res = ast_io_wait(io, res); 07994 if (res >= 0) { 07995 if (res >= 20) 07996 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 07997 count = ast_sched_runq(sched); 07998 if (count >= 20) 07999 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08000 } 08001 } 08002 return NULL; 08003 }
|
|
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 8064 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(). 08065 { 08066 struct sockaddr_in sin; 08067 int nonlocal = 1; 08068 int port = IAX_DEFAULT_PORTNO; 08069 int sockfd = defaultsockfd; 08070 char *tmp; 08071 char *addr; 08072 char *portstr; 08073 08074 tmp = ast_strdupa(srcaddr); 08075 if (!tmp) { 08076 ast_log(LOG_WARNING, "Out of memory!\n"); 08077 return -1; 08078 } 08079 08080 addr = strsep(&tmp, ":"); 08081 portstr = tmp; 08082 08083 if (portstr) { 08084 port = atoi(portstr); 08085 if (port < 1) 08086 port = IAX_DEFAULT_PORTNO; 08087 } 08088 08089 if (!ast_get_ip(&sin, addr)) { 08090 struct ast_netsock *sock; 08091 int res; 08092 08093 sin.sin_port = 0; 08094 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08095 if (res == 0) { 08096 /* ip address valid. */ 08097 sin.sin_port = htons(port); 08098 sock = ast_netsock_find(netsock, &sin); 08099 if (sock) { 08100 sockfd = ast_netsock_sockfd(sock); 08101 nonlocal = 0; 08102 } 08103 } 08104 } 08105 08106 peer->sockfd = sockfd; 08107 08108 if (nonlocal) { 08109 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08110 srcaddr, peer->name); 08111 return -1; 08112 } else { 08113 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08114 return 0; 08115 } 08116 }
|
|
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 8515 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. 08516 { 08517 struct iax2_user *user, *usernext, *userlast = NULL; 08518 ast_mutex_lock(&userl.lock); 08519 for (user=userl.users;user;) { 08520 usernext = user->next; 08521 if (ast_test_flag(user, IAX_DELME)) { 08522 destroy_user(user); 08523 if (userlast) 08524 userlast->next = usernext; 08525 else 08526 userl.users = usernext; 08527 } else 08528 userlast = user; 08529 user = usernext; 08530 } 08531 ast_mutex_unlock(&userl.lock); 08532 }
|
|
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 8882 of file chan_iax2.c. References reload_config(). 08883 { 08884 return reload_config(); 08885 }
|
|
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 8595 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(). 08596 { 08597 struct ast_config *cfg; 08598 int capability=iax2_capability; 08599 struct ast_variable *v; 08600 char *cat; 08601 char *utype; 08602 char *tosval; 08603 int format; 08604 int portno = IAX_DEFAULT_PORTNO; 08605 int x; 08606 struct iax2_user *user; 08607 struct iax2_peer *peer; 08608 struct ast_netsock *ns; 08609 #if 0 08610 static unsigned short int last_port=0; 08611 #endif 08612 08613 cfg = ast_config_load(config_file); 08614 08615 if (!cfg) { 08616 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08617 return -1; 08618 } 08619 08620 /* Reset global codec prefs */ 08621 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08622 08623 /* Reset Global Flags */ 08624 memset(&globalflags, 0, sizeof(globalflags)); 08625 ast_set_flag(&globalflags, IAX_RTUPDATE); 08626 08627 #ifdef SO_NO_CHECK 08628 nochecksums = 0; 08629 #endif 08630 08631 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08632 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08633 08634 v = ast_variable_browse(cfg, "general"); 08635 08636 /* Seed initial tos value */ 08637 tosval = ast_variable_retrieve(cfg, "general", "tos"); 08638 if (tosval) { 08639 if (ast_str2tos(tosval, &tos)) 08640 ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n"); 08641 } 08642 while(v) { 08643 if (!strcasecmp(v->name, "bindport")){ 08644 if (reload) 08645 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 08646 else 08647 portno = atoi(v->value); 08648 } else if (!strcasecmp(v->name, "pingtime")) 08649 ping_time = atoi(v->value); 08650 else if (!strcasecmp(v->name, "nochecksums")) { 08651 #ifdef SO_NO_CHECK 08652 if (ast_true(v->value)) 08653 nochecksums = 1; 08654 else 08655 nochecksums = 0; 08656 #else 08657 if (ast_true(v->value)) 08658 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 08659 #endif 08660 } 08661 else if (!strcasecmp(v->name, "maxjitterbuffer")) 08662 maxjitterbuffer = atoi(v->value); 08663 #ifdef NEWJB 08664 else if (!strcasecmp(v->name, "resyncthreshold")) 08665 resyncthreshold = atoi(v->value); 08666 else if (!strcasecmp(v->name, "maxjitterinterps")) 08667 maxjitterinterps = atoi(v->value); 08668 #endif 08669 else if (!strcasecmp(v->name, "jittershrinkrate")) 08670 jittershrinkrate = atoi(v->value); 08671 else if (!strcasecmp(v->name, "maxexcessbuffer")) 08672 max_jitter_buffer = atoi(v->value); 08673 else if (!strcasecmp(v->name, "minexcessbuffer")) 08674 min_jitter_buffer = atoi(v->value); 08675 else if (!strcasecmp(v->name, "lagrqtime")) 08676 lagrq_time = atoi(v->value); 08677 else if (!strcasecmp(v->name, "dropcount")) 08678 iax2_dropcount = atoi(v->value); 08679 else if (!strcasecmp(v->name, "maxregexpire")) 08680 max_reg_expire = atoi(v->value); 08681 else if (!strcasecmp(v->name, "minregexpire")) 08682 min_reg_expire = atoi(v->value); 08683 else if (!strcasecmp(v->name, "bindaddr")) { 08684 if (reload) { 08685 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 08686 } else { 08687 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 08688 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 08689 } else { 08690 if (option_verbose > 1) { 08691 if (strchr(v->value, ':')) 08692 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 08693 else 08694 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 08695 } 08696 if (defaultsockfd < 0) 08697 defaultsockfd = ast_netsock_sockfd(ns); 08698 ast_netsock_unref(ns); 08699 } 08700 } 08701 } else if (!strcasecmp(v->name, "authdebug")) 08702 authdebug = ast_true(v->value); 08703 else if (!strcasecmp(v->name, "encryption")) 08704 iax2_encryption = get_encrypt_methods(v->value); 08705 else if (!strcasecmp(v->name, "notransfer")) 08706 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 08707 else if (!strcasecmp(v->name, "codecpriority")) { 08708 if(!strcasecmp(v->value, "caller")) 08709 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 08710 else if(!strcasecmp(v->value, "disabled")) 08711 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08712 else if(!strcasecmp(v->value, "reqonly")) { 08713 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 08714 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08715 } 08716 } else if (!strcasecmp(v->name, "jitterbuffer")) 08717 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 08718 else if (!strcasecmp(v->name, "forcejitterbuffer")) 08719 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 08720 else if (!strcasecmp(v->name, "delayreject")) 08721 delayreject = ast_true(v->value); 08722 else if (!strcasecmp(v->name, "mailboxdetail")) 08723 ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL); 08724 else if (!strcasecmp(v->name, "rtcachefriends")) 08725 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 08726 else if (!strcasecmp(v->name, "rtignoreregexpire")) 08727 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 08728 else if (!strcasecmp(v->name, "rtupdate")) 08729 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 08730 else if (!strcasecmp(v->name, "trunktimestamps")) 08731 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 08732 else if (!strcasecmp(v->name, "rtautoclear")) { 08733 int i = atoi(v->value); 08734 if(i > 0) 08735 global_rtautoclear = i; 08736 else 08737 i = 0; 08738 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 08739 } else if (!strcasecmp(v->name, "trunkfreq")) { 08740 trunkfreq = atoi(v->value); 08741 if (trunkfreq < 10) 08742 trunkfreq = 10; 08743 } else if (!strcasecmp(v->name, "autokill")) { 08744 if (sscanf(v->value, "%d", &x) == 1) { 08745 if (x >= 0) 08746 autokill = x; 08747 else 08748 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 08749 } else if (ast_true(v->value)) { 08750 autokill = DEFAULT_MAXMS; 08751 } else { 08752 autokill = 0; 08753 } 08754 } else if (!strcasecmp(v->name, "bandwidth")) { 08755 if (!strcasecmp(v->value, "low")) { 08756 capability = IAX_CAPABILITY_LOWBANDWIDTH; 08757 } else if (!strcasecmp(v->value, "medium")) { 08758 capability = IAX_CAPABILITY_MEDBANDWIDTH; 08759 } else if (!strcasecmp(v->value, "high")) { 08760 capability = IAX_CAPABILITY_FULLBANDWIDTH; 08761 } else 08762 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 08763 } else if (!strcasecmp(v->name, "allow")) { 08764 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 08765 } else if (!strcasecmp(v->name, "disallow")) { 08766 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 08767 } else if (!strcasecmp(v->name, "register")) { 08768 iax2_register(v->value, v->lineno); 08769 } else if (!strcasecmp(v->name, "iaxcompat")) { 08770 iaxcompat = ast_true(v->value); 08771 } else if (!strcasecmp(v->name, "regcontext")) { 08772 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 08773 /* Create context if it doesn't exist already */ 08774 if (!ast_context_find(regcontext)) 08775 ast_context_create(NULL, regcontext, channeltype); 08776 } else if (!strcasecmp(v->name, "tos")) { 08777 if (ast_str2tos(v->value, &tos)) 08778 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 08779 } else if (!strcasecmp(v->name, "accountcode")) { 08780 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 08781 } else if (!strcasecmp(v->name, "amaflags")) { 08782 format = ast_cdr_amaflags2int(v->value); 08783 if (format < 0) { 08784 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08785 } else { 08786 amaflags = format; 08787 } 08788 } else if (!strcasecmp(v->name, "language")) { 08789 ast_copy_string(language, v->value, sizeof(language)); 08790 } /*else if (strcasecmp(v->name,"type")) */ 08791 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08792 v = v->next; 08793 } 08794 08795 if (defaultsockfd < 0) { 08796 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 08797 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 08798 } else { 08799 if (option_verbose > 1) 08800 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 08801 defaultsockfd = ast_netsock_sockfd(ns); 08802 ast_netsock_unref(ns); 08803 } 08804 } 08805 08806 if (min_reg_expire > max_reg_expire) { 08807 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 08808 min_reg_expire, max_reg_expire, max_reg_expire); 08809 min_reg_expire = max_reg_expire; 08810 } 08811 iax2_capability = capability; 08812 cat = ast_category_browse(cfg, NULL); 08813 while(cat) { 08814 if (strcasecmp(cat, "general")) { 08815 utype = ast_variable_retrieve(cfg, cat, "type"); 08816 if (utype) { 08817 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 08818 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 08819 if (user) { 08820 ast_mutex_lock(&userl.lock); 08821 user->next = userl.users; 08822 userl.users = user; 08823 ast_mutex_unlock(&userl.lock); 08824 } 08825 } 08826 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 08827 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 08828 if (peer) { 08829 ast_mutex_lock(&peerl.lock); 08830 peer->next = peerl.peers; 08831 peerl.peers = peer; 08832 ast_mutex_unlock(&peerl.lock); 08833 if (ast_test_flag(peer, IAX_DYNAMIC)) 08834 reg_source_db(peer); 08835 } 08836 } else if (strcasecmp(utype, "user")) { 08837 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 08838 } 08839 } else 08840 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 08841 } 08842 cat = ast_category_browse(cfg, cat); 08843 } 08844 ast_config_destroy(cfg); 08845 set_timing(); 08846 return capability; 08847 }
|
|
Definition at line 8578 of file chan_iax2.c. References ast_log(), LOG_WARNING, timingfd, and trunkfreq. Referenced by set_config(). 08579 { 08580 #ifdef IAX_TRUNKING 08581 int bs = trunkfreq * 8; 08582 if (timingfd > -1) { 08583 if ( 08584 #ifdef ZT_TIMERACK 08585 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08586 #endif 08587 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08588 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08589 } 08590 #endif 08591 }
|
|
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(), complete_dpreply(), complete_transfer(), construct_rr(), ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_frame::datalen, 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(), 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, 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, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, 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 if (res < sizeof(*vh)) { 06326 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a mini video frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06327 return 1; 06328 06329 } 06330 /* This is a video frame, get call number */ 06331 fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06332 minivid = 1; 06333 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06334 if (res < sizeof(*meta)) { 06335 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06336 return 1; 06337 06338 } 06339 unsigned char metatype; 06340 /* This is a meta header */ 06341 switch(meta->metacmd) { 06342 case IAX_META_TRUNK: 06343 if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) { 06344 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr)); 06345 return 1; 06346 } 06347 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06348 ts = ntohl(mth->ts); 06349 metatype = meta->cmddata; 06350 res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)); 06351 ptr = mth->data; 06352 tpeer = find_tpeer(&sin, fd); 06353 if (!tpeer) { 06354 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)); 06355 return 1; 06356 } 06357 tpeer->trunkact = ast_tvnow(); 06358 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06359 tpeer->rxtrunktime = tpeer->trunkact; 06360 rxtrunktime = tpeer->rxtrunktime; 06361 ast_mutex_unlock(&tpeer->lock); 06362 while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) { 06363 /* Process channels */ 06364 unsigned short callno, trunked_ts, len; 06365 06366 if(metatype == IAX_META_TRUNK_MINI) { 06367 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06368 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06369 res -= sizeof(struct ast_iax2_meta_trunk_mini); 06370 len = ntohs(mtm->len); 06371 callno = ntohs(mtm->mini.callno); 06372 trunked_ts = ntohs(mtm->mini.ts); 06373 } else if ( metatype == IAX_META_TRUNK_SUPERMINI ) { 06374 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06375 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06376 res -= sizeof(struct ast_iax2_meta_trunk_entry); 06377 len = ntohs(mte->len); 06378 callno = ntohs(mte->callno); 06379 trunked_ts = 0; 06380 } else { 06381 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)); 06382 break; 06383 } 06384 /* Stop if we don't have enough data */ 06385 if (len > res) 06386 break; 06387 fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06388 if (fr.callno) { 06389 ast_mutex_lock(&iaxsl[fr.callno]); 06390 /* If it's a valid call, deliver the contents. If not, we 06391 drop it, since we don't have a scallno to use for an INVAL */ 06392 /* Process as a mini frame */ 06393 f.frametype = AST_FRAME_VOICE; 06394 if (iaxs[fr.callno]) { 06395 if (iaxs[fr.callno]->voiceformat > 0) { 06396 f.subclass = iaxs[fr.callno]->voiceformat; 06397 f.datalen = len; 06398 if (f.datalen >= 0) { 06399 if (f.datalen) 06400 f.data = ptr; 06401 else 06402 f.data = NULL; 06403 if(trunked_ts) { 06404 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06405 } else 06406 fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts); 06407 /* Don't pass any packets until we're started */ 06408 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06409 /* Common things */ 06410 f.src = "IAX2"; 06411 f.mallocd = 0; 06412 f.offset = 0; 06413 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06414 f.samples = ast_codec_get_samples(&f); 06415 else 06416 f.samples = 0; 06417 fr.outoforder = 0; 06418 iax_frame_wrap(&fr, &f); 06419 #ifdef BRIDGE_OPTIMIZATION 06420 if (iaxs[fr.callno]->bridgecallno) { 06421 forward_delivery(&fr); 06422 } else { 06423 duped_fr = iaxfrdup2(&fr); 06424 if (duped_fr) { 06425 schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); 06426 } 06427 } 06428 #else 06429 duped_fr = iaxfrdup2(&fr); 06430 if (duped_fr) { 06431 schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); 06432 } 06433 #endif 06434 if (iaxs[fr.callno]->last < fr.ts) { 06435 iaxs[fr.callno]->last = fr.ts; 06436 #if 1 06437 if (option_debug) 06438 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 06439 #endif 06440 } 06441 } 06442 } else { 06443 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06444 } 06445 } else { 06446 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06447 iax2_vnak(fr.callno); 06448 } 06449 } 06450 ast_mutex_unlock(&iaxsl[fr.callno]); 06451 } 06452 ptr += len; 06453 res -= len; 06454 } 06455 06456 } 06457 return 1; 06458 } 06459 #ifdef DEBUG_SUPPORT 06460 if (iaxdebug) 06461 iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr)); 06462 #endif 06463 if ((res >= sizeof(*fh)) && ntohs(mh->callno) & IAX_FLAG_FULL) { 06464 /* Get the destination call number */ 06465 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06466 /* Retrieve the type and subclass */ 06467 f.frametype = fh->type; 06468 if (f.frametype == AST_FRAME_VIDEO) { 06469 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06470 } else { 06471 f.subclass = uncompress_subclass(fh->csub); 06472 } 06473 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06474 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06475 (f.subclass == IAX_COMMAND_REGREL))) 06476 new = NEW_ALLOW; 06477 } else { 06478 /* Don't know anything about it yet */ 06479 f.frametype = AST_FRAME_NULL; 06480 f.subclass = 0; 06481 } 06482 06483 if (!fr.callno) 06484 fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06485 06486 if (fr.callno > 0) 06487 ast_mutex_lock(&iaxsl[fr.callno]); 06488 06489 if (!fr.callno || !iaxs[fr.callno]) { 06490 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06491 frame, reply with an inval */ 06492 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06493 /* We can only raw hangup control frames */ 06494 if (((f.subclass != IAX_COMMAND_INVAL) && 06495 (f.subclass != IAX_COMMAND_TXCNT) && 06496 (f.subclass != IAX_COMMAND_TXACC) && 06497 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06498 (f.frametype != AST_FRAME_IAX)) 06499 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06500 fd); 06501 } 06502 if (fr.callno > 0) 06503 ast_mutex_unlock(&iaxsl[fr.callno]); 06504 return 1; 06505 } 06506 if (ast_test_flag(iaxs[fr.callno], IAX_ENCRYPTED)) { 06507 if (decrypt_frame(fr.callno, fh, &f, &res)) { 06508 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06509 ast_mutex_unlock(&iaxsl[fr.callno]); 06510 return 1; 06511 } 06512 #ifdef DEBUG_SUPPORT 06513 else if (iaxdebug) 06514 iax_showframe(NULL, fh, 3, &sin, res - sizeof(struct ast_iax2_full_hdr)); 06515 #endif 06516 } 06517 06518 /* count this frame */ 06519 iaxs[fr.callno]->frames_received++; 06520 06521 if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid && 06522 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06523 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06524 iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06525 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06526 if (option_debug && iaxdebug) 06527 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06528 /* Check if it's out of order (and not an ACK or INVAL) */ 06529 fr.oseqno = fh->oseqno; 06530 fr.iseqno = fh->iseqno; 06531 fr.ts = ntohl(fh->ts); 06532 #ifdef IAXTESTS 06533 if (test_resync) { 06534 if (option_debug) 06535 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr.ts, fr.ts + test_resync); 06536 fr.ts += test_resync; 06537 } 06538 #endif /* IAXTESTS */ 06539 #if 0 06540 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06541 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06542 (f.subclass == IAX_COMMAND_NEW || 06543 f.subclass == IAX_COMMAND_AUTHREQ || 06544 f.subclass == IAX_COMMAND_ACCEPT || 06545 f.subclass == IAX_COMMAND_REJECT)) ) ) 06546 #endif 06547 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06548 updatehistory = 0; 06549 if ((iaxs[fr.callno]->iseqno != fr.oseqno) && 06550 (iaxs[fr.callno]->iseqno || 06551 ((f.subclass != IAX_COMMAND_TXCNT) && 06552 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06553 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06554 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06555 (f.subclass != IAX_COMMAND_TXACC)) || 06556 (f.frametype != AST_FRAME_IAX))) { 06557 if ( 06558 ((f.subclass != IAX_COMMAND_ACK) && 06559 (f.subclass != IAX_COMMAND_INVAL) && 06560 (f.subclass != IAX_COMMAND_TXCNT) && 06561 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06562 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06563 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06564 (f.subclass != IAX_COMMAND_TXACC) && 06565 (f.subclass != IAX_COMMAND_VNAK)) || 06566 (f.frametype != AST_FRAME_IAX)) { 06567 /* If it's not an ACK packet, it's out of order. */ 06568 if (option_debug) 06569 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06570 iaxs[fr.callno]->iseqno, fr.oseqno, f.frametype, f.subclass); 06571 if (iaxs[fr.callno]->iseqno > fr.oseqno) { 06572 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06573 if ((f.frametype != AST_FRAME_IAX) || 06574 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06575 if (option_debug) 06576 ast_log(LOG_DEBUG, "Acking anyway\n"); 06577 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06578 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06579 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06580 } 06581 } else { 06582 /* Send a VNAK requesting retransmission */ 06583 iax2_vnak(fr.callno); 06584 } 06585 ast_mutex_unlock(&iaxsl[fr.callno]); 06586 return 1; 06587 } 06588 } else { 06589 /* Increment unless it's an ACK or VNAK */ 06590 if (((f.subclass != IAX_COMMAND_ACK) && 06591 (f.subclass != IAX_COMMAND_INVAL) && 06592 (f.subclass != IAX_COMMAND_TXCNT) && 06593 (f.subclass != IAX_COMMAND_TXACC) && 06594 (f.subclass != IAX_COMMAND_VNAK)) || 06595 (f.frametype != AST_FRAME_IAX)) 06596 iaxs[fr.callno]->iseqno++; 06597 } 06598 /* A full frame */ 06599 if (res < sizeof(struct ast_iax2_full_hdr)) { 06600 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_full_hdr)); 06601 ast_mutex_unlock(&iaxsl[fr.callno]); 06602 return 1; 06603 } 06604 f.datalen = res - sizeof(struct ast_iax2_full_hdr); 06605 06606 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06607 from the real peer, not the transfer peer */ 06608 if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 06609 ((f.subclass != IAX_COMMAND_INVAL) || 06610 (f.frametype != AST_FRAME_IAX))) { 06611 unsigned char x; 06612 /* XXX This code is not very efficient. Surely there is a better way which still 06613 properly handles boundary conditions? XXX */ 06614 /* First we have to qualify that the ACKed value is within our window */ 06615 for (x=iaxs[fr.callno]->rseqno; x != iaxs[fr.callno]->oseqno; x++) 06616 if (fr.iseqno == x) 06617 break; 06618 if ((x != iaxs[fr.callno]->oseqno) || (iaxs[fr.callno]->oseqno == fr.iseqno)) { 06619 /* The acknowledgement is within our window. Time to acknowledge everything 06620 that it says to */ 06621 for (x=iaxs[fr.callno]->rseqno; x != fr.iseqno; x++) { 06622 /* Ack the packet with the given timestamp */ 06623 if (option_debug && iaxdebug) 06624 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06625 ast_mutex_lock(&iaxq.lock); 06626 for (cur = iaxq.head; cur ; cur = cur->next) { 06627 /* If it's our call, and our timestamp, mark -1 retries */ 06628 if ((fr.callno == cur->callno) && (x == cur->oseqno)) { 06629 cur->retries = -1; 06630 /* Destroy call if this is the end */ 06631 if (cur->final) { 06632 if (iaxdebug && option_debug) 06633 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr.callno); 06634 iax2_destroy_nolock(fr.callno); 06635 } 06636 } 06637 } 06638 ast_mutex_unlock(&iaxq.lock); 06639 } 06640 /* Note how much we've received acknowledgement for */ 06641 if (iaxs[fr.callno]) 06642 iaxs[fr.callno]->rseqno = fr.iseqno; 06643 else { 06644 /* Stop processing now */ 06645 ast_mutex_unlock(&iaxsl[fr.callno]); 06646 return 1; 06647 } 06648 } else 06649 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno); 06650 } 06651 if (inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 06652 ((f.frametype != AST_FRAME_IAX) || 06653 ((f.subclass != IAX_COMMAND_TXACC) && 06654 (f.subclass != IAX_COMMAND_TXCNT)))) { 06655 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06656 ast_mutex_unlock(&iaxsl[fr.callno]); 06657 return 1; 06658 } 06659 06660 if (f.datalen) { 06661 if (f.frametype == AST_FRAME_IAX) { 06662 if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 06663 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06664 ast_mutex_unlock(&iaxsl[fr.callno]); 06665 return 1; 06666 } 06667 f.data = NULL; 06668 } else 06669 f.data = buf + sizeof(struct ast_iax2_full_hdr); 06670 } else { 06671 if (f.frametype == AST_FRAME_IAX) 06672 f.data = NULL; 06673 else 06674 f.data = empty; 06675 memset(&ies, 0, sizeof(ies)); 06676 } 06677 if (f.frametype == AST_FRAME_VOICE) { 06678 if (f.subclass != iaxs[fr.callno]->voiceformat) { 06679 iaxs[fr.callno]->voiceformat = f.subclass; 06680 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06681 if (iaxs[fr.callno]->owner) { 06682 int orignative; 06683 retryowner: 06684 if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { 06685 ast_mutex_unlock(&iaxsl[fr.callno]); 06686 usleep(1); 06687 ast_mutex_lock(&iaxsl[fr.callno]); 06688 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner; 06689 } 06690 if (iaxs[fr.callno]) { 06691 if (iaxs[fr.callno]->owner) { 06692 orignative = iaxs[fr.callno]->owner->nativeformats; 06693 iaxs[fr.callno]->owner->nativeformats = f.subclass; 06694 if (iaxs[fr.callno]->owner->readformat) 06695 ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); 06696 iaxs[fr.callno]->owner->nativeformats = orignative; 06697 ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); 06698 } 06699 } else { 06700 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06701 ast_mutex_unlock(&iaxsl[fr.callno]); 06702 return 1; 06703 } 06704 } 06705 } 06706 } 06707 if (f.frametype == AST_FRAME_VIDEO) { 06708 if (f.subclass != iaxs[fr.callno]->videoformat) { 06709 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06710 iaxs[fr.callno]->videoformat = f.subclass & ~0x1; 06711 } 06712 } 06713 if (f.frametype == AST_FRAME_IAX) { 06714 if (iaxs[fr.callno]->initid > -1) { 06715 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06716 ast_sched_del(sched, iaxs[fr.callno]->initid); 06717 iaxs[fr.callno]->initid = -1; 06718 } 06719 /* Handle the IAX pseudo frame itself */ 06720 if (option_debug && iaxdebug) 06721 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06722 06723 /* Update last ts unless the frame's timestamp originated with us. */ 06724 if (iaxs[fr.callno]->last < fr.ts && 06725 f.subclass != IAX_COMMAND_ACK && 06726 f.subclass != IAX_COMMAND_PONG && 06727 f.subclass != IAX_COMMAND_LAGRP) { 06728 iaxs[fr.callno]->last = fr.ts; 06729 if (option_debug && iaxdebug) 06730 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 06731 } 06732 06733 switch(f.subclass) { 06734 case IAX_COMMAND_ACK: 06735 /* Do nothing */ 06736 break; 06737 case IAX_COMMAND_QUELCH: 06738 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06739 /* Generate Manager Hold event, if necessary*/ 06740 if (iaxs[fr.callno]->owner) { 06741 manager_event(EVENT_FLAG_CALL, "Hold", 06742 "Channel: %s\r\n" 06743 "Uniqueid: %s\r\n", 06744 iaxs[fr.callno]->owner->name, 06745 iaxs[fr.callno]->owner->uniqueid); 06746 } 06747 06748 ast_set_flag(iaxs[fr.callno], IAX_QUELCH); 06749 if (ies.musiconhold) { 06750 if (iaxs[fr.callno]->owner && 06751 ast_bridged_channel(iaxs[fr.callno]->owner)) 06752 ast_moh_start(ast_bridged_channel(iaxs[fr.callno]->owner), NULL); 06753 } 06754 } 06755 break; 06756 case IAX_COMMAND_UNQUELCH: 06757 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06758 /* Generate Manager Unhold event, if necessary*/ 06759 if (iaxs[fr.callno]->owner && ast_test_flag(iaxs[fr.callno], IAX_QUELCH)) { 06760 manager_event(EVENT_FLAG_CALL, "Unhold", 06761 "Channel: %s\r\n" 06762 "Uniqueid: %s\r\n", 06763 iaxs[fr.callno]->owner->name, 06764 iaxs[fr.callno]->owner->uniqueid); 06765 } 06766 06767 ast_clear_flag(iaxs[fr.callno], IAX_QUELCH); 06768 if (iaxs[fr.callno]->owner && 06769 ast_bridged_channel(iaxs[fr.callno]->owner)) 06770 ast_moh_stop(ast_bridged_channel(iaxs[fr.callno]->owner)); 06771 } 06772 break; 06773 case IAX_COMMAND_TXACC: 06774 if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { 06775 /* Ack the packet with the given timestamp */ 06776 ast_mutex_lock(&iaxq.lock); 06777 for (cur = iaxq.head; cur ; cur = cur->next) { 06778 /* Cancel any outstanding txcnt's */ 06779 if ((fr.callno == cur->callno) && (cur->transfer)) 06780 cur->retries = -1; 06781 } 06782 ast_mutex_unlock(&iaxq.lock); 06783 memset(&ied1, 0, sizeof(ied1)); 06784 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->callno); 06785 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06786 iaxs[fr.callno]->transferring = TRANSFER_READY; 06787 } 06788 break; 06789 case IAX_COMMAND_NEW: 06790 /* Ignore if it's already up */ 06791 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06792 break; 06793 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06794 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06795 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06796 if (ast_test_flag(iaxs[fr.callno], IAX_TRUNK)) { 06797 fr.callno = make_trunk(fr.callno, 1); 06798 } 06799 /* For security, always ack immediately */ 06800 if (delayreject) 06801 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06802 if (check_access(fr.callno, &sin, &ies)) { 06803 /* They're not allowed on */ 06804 auth_fail(fr.callno, IAX_COMMAND_REJECT); 06805 if (authdebug) 06806 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); 06807 break; 06808 } 06809 /* This might re-enter the IAX code and need the lock */ 06810 if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { 06811 ast_mutex_unlock(&iaxsl[fr.callno]); 06812 exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); 06813 ast_mutex_lock(&iaxsl[fr.callno]); 06814 } else 06815 exists = 0; 06816 if (ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) { 06817 if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { 06818 memset(&ied0, 0, sizeof(ied0)); 06819 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06820 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06821 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06822 if (authdebug) 06823 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); 06824 } else { 06825 /* Select an appropriate format */ 06826 06827 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 06828 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 06829 using_prefs = "reqonly"; 06830 } else { 06831 using_prefs = "disabled"; 06832 } 06833 format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; 06834 memset(&pref, 0, sizeof(pref)); 06835 strcpy(caller_pref_buf, "disabled"); 06836 strcpy(host_pref_buf, "disabled"); 06837 } else { 06838 using_prefs = "mine"; 06839 if(ies.codec_prefs) { 06840 ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); 06841 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06842 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 06843 pref = rpref; 06844 using_prefs = "caller"; 06845 } else { 06846 pref = iaxs[fr.callno]->prefs; 06847 } 06848 } else 06849 pref = iaxs[fr.callno]->prefs; 06850 06851 format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); 06852 ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06853 ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06854 } 06855 if (!format) { 06856 if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 06857 format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; 06858 if (!format) { 06859 memset(&ied0, 0, sizeof(ied0)); 06860 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06861 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06862 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06863 if (authdebug) { 06864 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 06865 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); 06866 else 06867 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); 06868 } 06869 } else { 06870 /* Pick one... */ 06871 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 06872 if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) 06873 format = 0; 06874 } else { 06875 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 06876 using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06877 memset(&pref, 0, sizeof(pref)); 06878 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06879 strcpy(caller_pref_buf,"disabled"); 06880 strcpy(host_pref_buf,"disabled"); 06881 } else { 06882 using_prefs = "mine"; 06883 if(ies.codec_prefs) { 06884 /* Do the opposite of what we tried above. */ 06885 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 06886 pref = iaxs[fr.callno]->prefs; 06887 } else { 06888 pref = rpref; 06889 using_prefs = "caller"; 06890 } 06891 format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); 06892 06893 } else /* if no codec_prefs IE do it the old way */ 06894 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06895 } 06896 } 06897 06898 if (!format) { 06899 memset(&ied0, 0, sizeof(ied0)); 06900 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06901 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06902 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06903 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06904 if (authdebug) 06905 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); 06906 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 06907 break; 06908 } 06909 } 06910 } 06911 if (format) { 06912 /* No authentication required, let them in */ 06913 memset(&ied1, 0, sizeof(ied1)); 06914 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 06915 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 06916 if (strcmp(iaxs[fr.callno]->exten, "TBD")) { 06917 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 06918 if (option_verbose > 2) 06919 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 06920 "%srequested format = %s,\n" 06921 "%srequested prefs = %s,\n" 06922 "%sactual format = %s,\n" 06923 "%shost prefs = %s,\n" 06924 "%spriority = %s\n", 06925 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 06926 VERBOSE_PREFIX_4, 06927 ast_getformatname(iaxs[fr.callno]->peerformat), 06928 VERBOSE_PREFIX_4, 06929 caller_pref_buf, 06930 VERBOSE_PREFIX_4, 06931 ast_getformatname(format), 06932 VERBOSE_PREFIX_4, 06933 host_pref_buf, 06934 VERBOSE_PREFIX_4, 06935 using_prefs); 06936 06937 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) 06938 iax2_destroy_nolock(fr.callno); 06939 } else { 06940 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 06941 /* If this is a TBD call, we're ready but now what... */ 06942 if (option_verbose > 2) 06943 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06944 } 06945 } 06946 } 06947 break; 06948 } 06949 if (iaxs[fr.callno]->authmethods & IAX_AUTH_MD5) 06950 merge_encryption(iaxs[fr.callno],ies.encmethods); 06951 else 06952 iaxs[fr.callno]->encmethods = 0; 06953 authenticate_request(iaxs[fr.callno]); 06954 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED); 06955 break; 06956 case IAX_COMMAND_DPREQ: 06957 /* Request status in the dialplan */ 06958 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD) && 06959 !ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED) && ies.called_number) { 06960 if (iaxcompat) { 06961 /* Spawn a thread for the lookup */ 06962 spawn_dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num); 06963 } else { 06964 /* Just look it up */ 06965 dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num, 1); 06966 } 06967 } 06968 break; 06969 case IAX_COMMAND_HANGUP: 06970 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 06971 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno); 06972 /* Set hangup cause according to remote */ 06973 if (ies.causecode && iaxs[fr.callno]->owner) 06974 iaxs[fr.callno]->owner->hangupcause = ies.causecode; 06975 /* Send ack immediately, before we destroy */ 06976 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06977 iax2_destroy_nolock(fr.callno); 06978 break; 06979 case IAX_COMMAND_REJECT: 06980 memset(&f, 0, sizeof(f)); 06981 f.frametype = AST_FRAME_CONTROL; 06982 f.subclass = AST_CONTROL_CONGESTION; 06983 06984 /* Set hangup cause according to remote */ 06985 if (ies.causecode && iaxs[fr.callno]->owner) 06986 iaxs[fr.callno]->owner->hangupcause = ies.causecode; 06987 06988 iax2_queue_frame(fr.callno, &f); 06989 if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { 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 iax2_destroy_nolock(fr.callno); 06993 break; 06994 } 06995 if (iaxs[fr.callno]->owner) { 06996 if (authdebug) 06997 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>"); 06998 } 06999 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno); 07000 /* Send ack immediately, before we destroy */ 07001 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07002 iaxs[fr.callno]->error = EPERM; 07003 iax2_destroy_nolock(fr.callno); 07004 break; 07005 case IAX_COMMAND_TRANSFER: 07006 if (iaxs[fr.callno]->owner && ast_bridged_channel(iaxs[fr.callno]->owner) && ies.called_number) { 07007 if (!strcmp(ies.called_number, ast_parking_ext())) { 07008 if (iax_park(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->owner)) { 07009 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); 07010 } else 07011 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); 07012 } else { 07013 if (ast_async_goto(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->context, ies.called_number, 1)) 07014 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 07015 ies.called_number, iaxs[fr.callno]->context); 07016 else 07017 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 07018 ies.called_number, iaxs[fr.callno]->context); 07019 } 07020 } else 07021 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr.callno); 07022 break; 07023 case IAX_COMMAND_ACCEPT: 07024 /* Ignore if call is already up or needs authentication or is a TBD */ 07025 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07026 break; 07027 if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { 07028 /* Send ack immediately, before we destroy */ 07029 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07030 iax2_destroy_nolock(fr.callno); 07031 break; 07032 } 07033 if (ies.format) { 07034 iaxs[fr.callno]->peerformat = ies.format; 07035 } else { 07036 if (iaxs[fr.callno]->owner) 07037 iaxs[fr.callno]->peerformat = iaxs[fr.callno]->owner->nativeformats; 07038 else 07039 iaxs[fr.callno]->peerformat = iaxs[fr.callno]->capability; 07040 } 07041 if (option_verbose > 2) 07042 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)); 07043 if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) { 07044 memset(&ied0, 0, sizeof(ied0)); 07045 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07046 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07047 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07048 if (authdebug) 07049 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); 07050 } else { 07051 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07052 if (iaxs[fr.callno]->owner) { 07053 /* Switch us to use a compatible format */ 07054 iaxs[fr.callno]->owner->nativeformats = iaxs[fr.callno]->peerformat; 07055 if (option_verbose > 2) 07056 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr.callno]->owner->nativeformats)); 07057 retryowner2: 07058 if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { 07059 ast_mutex_unlock(&iaxsl[fr.callno]); 07060 usleep(1); 07061 ast_mutex_lock(&iaxsl[fr.callno]); 07062 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner2; 07063 } 07064 07065 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) { 07066 /* Setup read/write formats properly. */ 07067 if (iaxs[fr.callno]->owner->writeformat) 07068 ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat); 07069 if (iaxs[fr.callno]->owner->readformat) 07070 ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); 07071 ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); 07072 } 07073 } 07074 } 07075 ast_mutex_lock(&dpcache_lock); 07076 dp = iaxs[fr.callno]->dpentries; 07077 while(dp) { 07078 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07079 iax2_dprequest(dp, fr.callno); 07080 } 07081 dp = dp->peer; 07082 } 07083 ast_mutex_unlock(&dpcache_lock); 07084 break; 07085 case IAX_COMMAND_POKE: 07086 /* Send back a pong packet with the original timestamp */ 07087 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); 07088 break; 07089 case IAX_COMMAND_PING: 07090 #ifdef BRIDGE_OPTIMIZATION 07091 if (iaxs[fr.callno]->bridgecallno) { 07092 /* If we're in a bridged call, just forward this */ 07093 forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr.ts, NULL, 0, -1); 07094 } else { 07095 struct iax_ie_data pingied; 07096 construct_rr(iaxs[fr.callno], &pingied); 07097 /* Send back a pong packet with the original timestamp */ 07098 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); 07099 } 07100 #else 07101 { 07102 struct iax_ie_data pingied; 07103 construct_rr(iaxs[fr.callno], &pingied); 07104 /* Send back a pong packet with the original timestamp */ 07105 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); 07106 } 07107 #endif 07108 break; 07109 case IAX_COMMAND_PONG: 07110 #ifdef BRIDGE_OPTIMIZATION 07111 if (iaxs[fr.callno]->bridgecallno) { 07112 /* Forward to the other side of the bridge */ 07113 forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); 07114 } else { 07115 /* Calculate ping time */ 07116 iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; 07117 } 07118 #else 07119 /* Calculate ping time */ 07120 iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; 07121 #endif 07122 /* save RR info */ 07123 save_rr(&fr, &ies); 07124 07125 if (iaxs[fr.callno]->peerpoke) { 07126 peer = iaxs[fr.callno]->peerpoke; 07127 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07128 if (iaxs[fr.callno]->pingtime <= peer->maxms) { 07129 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr.callno]->pingtime); 07130 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 07131 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07132 } 07133 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07134 if (iaxs[fr.callno]->pingtime > peer->maxms) { 07135 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr.callno]->pingtime); 07136 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 07137 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07138 } 07139 } 07140 peer->lastms = iaxs[fr.callno]->pingtime; 07141 if (peer->smoothing && (peer->lastms > -1)) 07142 peer->historicms = (iaxs[fr.callno]->pingtime + peer->historicms) / 2; 07143 else if (peer->smoothing && peer->lastms < 0) 07144 peer->historicms = (0 + peer->historicms) / 2; 07145 else 07146 peer->historicms = iaxs[fr.callno]->pingtime; 07147 07148 if (peer->pokeexpire > -1) 07149 ast_sched_del(sched, peer->pokeexpire); 07150 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07151 iax2_destroy_nolock(fr.callno); 07152 peer->callno = 0; 07153 /* Try again eventually */ 07154 ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms); 07155 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07156 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07157 else 07158 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07159 } 07160 break; 07161 case IAX_COMMAND_LAGRQ: 07162 case IAX_COMMAND_LAGRP: 07163 #ifdef BRIDGE_OPTIMIZATION 07164 if (iaxs[fr.callno]->bridgecallno) { 07165 forward_command(iaxs[fr.callno], AST_FRAME_IAX, f.subclass, fr.ts, NULL, 0, -1); 07166 } else { 07167 #endif 07168 f.src = "LAGRQ"; 07169 f.mallocd = 0; 07170 f.offset = 0; 07171 f.samples = 0; 07172 iax_frame_wrap(&fr, &f); 07173 if(f.subclass == IAX_COMMAND_LAGRQ) { 07174 /* Received a LAGRQ - echo back a LAGRP */ 07175 fr.af.subclass = IAX_COMMAND_LAGRP; 07176 iax2_send(iaxs[fr.callno], &fr.af, fr.ts, -1, 0, 0, 0); 07177 } else { 07178 /* Received LAGRP in response to our LAGRQ */ 07179 unsigned int ts; 07180 /* This is a reply we've been given, actually measure the difference */ 07181 ts = calc_timestamp(iaxs[fr.callno], 0, &fr.af); 07182 iaxs[fr.callno]->lag = ts - fr.ts; 07183 if (option_debug && iaxdebug) 07184 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07185 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->lag); 07186 } 07187 #ifdef BRIDGE_OPTIMIZATION 07188 } 07189 #endif 07190 break; 07191 case IAX_COMMAND_AUTHREQ: 07192 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07193 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>"); 07194 break; 07195 } 07196 if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) { 07197 ast_log(LOG_WARNING, 07198 "I don't know how to authenticate %s to %s\n", 07199 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr)); 07200 } 07201 break; 07202 case IAX_COMMAND_AUTHREP: 07203 /* For security, always ack immediately */ 07204 if (delayreject) 07205 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07206 /* Ignore once we've started */ 07207 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07208 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>"); 07209 break; 07210 } 07211 if (authenticate_verify(iaxs[fr.callno], &ies)) { 07212 if (authdebug) 07213 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); 07214 memset(&ied0, 0, sizeof(ied0)); 07215 auth_fail(fr.callno, IAX_COMMAND_REJECT); 07216 break; 07217 } 07218 if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { 07219 /* This might re-enter the IAX code and need the lock */ 07220 exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); 07221 } else 07222 exists = 0; 07223 if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { 07224 if (authdebug) 07225 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); 07226 memset(&ied0, 0, sizeof(ied0)); 07227 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07228 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07229 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07230 } else { 07231 /* Select an appropriate format */ 07232 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 07233 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07234 using_prefs = "reqonly"; 07235 } else { 07236 using_prefs = "disabled"; 07237 } 07238 format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; 07239 memset(&pref, 0, sizeof(pref)); 07240 strcpy(caller_pref_buf, "disabled"); 07241 strcpy(host_pref_buf, "disabled"); 07242 } else { 07243 using_prefs = "mine"; 07244 if(ies.codec_prefs) { 07245 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07246 ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); 07247 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 07248 ast_codec_pref_convert(&pref, ies.codec_prefs, 32, 0); 07249 using_prefs = "caller"; 07250 } else { 07251 pref = iaxs[fr.callno]->prefs; 07252 } 07253 } else /* if no codec_prefs IE do it the old way */ 07254 pref = iaxs[fr.callno]->prefs; 07255 07256 format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); 07257 ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07258 ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07259 } 07260 if (!format) { 07261 if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07262 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); 07263 format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; 07264 } 07265 if (!format) { 07266 if (authdebug) { 07267 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 07268 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); 07269 else 07270 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); 07271 } 07272 memset(&ied0, 0, sizeof(ied0)); 07273 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07274 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07275 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07276 } else { 07277 /* Pick one... */ 07278 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07279 if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) 07280 format = 0; 07281 } else { 07282 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 07283 using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07284 memset(&pref, 0, sizeof(pref)); 07285 format = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? 07286 iaxs[fr.callno]->peerformat : ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07287 strcpy(caller_pref_buf,"disabled"); 07288 strcpy(host_pref_buf,"disabled"); 07289 } else { 07290 using_prefs = "mine"; 07291 if(ies.codec_prefs) { 07292 /* Do the opposite of what we tried above. */ 07293 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 07294 pref = iaxs[fr.callno]->prefs; 07295 } else { 07296 pref = rpref; 07297 using_prefs = "caller"; 07298 } 07299 format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); 07300 } else /* if no codec_prefs IE do it the old way */ 07301 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07302 } 07303 } 07304 if (!format) { 07305 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07306 if (authdebug) { 07307 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 07308 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); 07309 else 07310 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); 07311 } 07312 memset(&ied0, 0, sizeof(ied0)); 07313 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07314 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07315 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07316 } 07317 } 07318 } 07319 if (format) { 07320 /* Authentication received */ 07321 memset(&ied1, 0, sizeof(ied1)); 07322 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07323 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07324 if (strcmp(iaxs[fr.callno]->exten, "TBD")) { 07325 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07326 if (option_verbose > 2) 07327 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07328 "%srequested format = %s,\n" 07329 "%srequested prefs = %s,\n" 07330 "%sactual format = %s,\n" 07331 "%shost prefs = %s,\n" 07332 "%spriority = %s\n", 07333 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07334 VERBOSE_PREFIX_4, 07335 ast_getformatname(iaxs[fr.callno]->peerformat), 07336 VERBOSE_PREFIX_4, 07337 caller_pref_buf, 07338 VERBOSE_PREFIX_4, 07339 ast_getformatname(format), 07340 VERBOSE_PREFIX_4, 07341 host_pref_buf, 07342 VERBOSE_PREFIX_4, 07343 using_prefs); 07344 07345 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07346 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) 07347 iax2_destroy_nolock(fr.callno); 07348 } else { 07349 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 07350 /* If this is a TBD call, we're ready but now what... */ 07351 if (option_verbose > 2) 07352 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07353 } 07354 } 07355 } 07356 break; 07357 case IAX_COMMAND_DIAL: 07358 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD)) { 07359 ast_clear_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 07360 ast_copy_string(iaxs[fr.callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr.callno]->exten)); 07361 if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num)) { 07362 if (authdebug) 07363 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); 07364 memset(&ied0, 0, sizeof(ied0)); 07365 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07366 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07367 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07368 } else { 07369 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07370 if (option_verbose > 2) 07371 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); 07372 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07373 send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07374 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat))) 07375 iax2_destroy_nolock(fr.callno); 07376 } 07377 } 07378 break; 07379 case IAX_COMMAND_INVAL: 07380 iaxs[fr.callno]->error = ENOTCONN; 07381 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno); 07382 iax2_destroy_nolock(fr.callno); 07383 if (option_debug) 07384 ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno); 07385 break; 07386 case IAX_COMMAND_VNAK: 07387 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07388 /* Force retransmission */ 07389 vnak_retransmit(fr.callno, fr.iseqno); 07390 break; 07391 case IAX_COMMAND_REGREQ: 07392 case IAX_COMMAND_REGREL: 07393 /* For security, always ack immediately */ 07394 if (delayreject) 07395 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07396 if (register_verify(fr.callno, &sin, &ies)) { 07397 /* Send delayed failure */ 07398 auth_fail(fr.callno, IAX_COMMAND_REGREJ); 07399 break; 07400 } 07401 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)) { 07402 if (f.subclass == IAX_COMMAND_REGREL) 07403 memset(&sin, 0, sizeof(sin)); 07404 if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd, ies.refresh)) 07405 ast_log(LOG_WARNING, "Registry error\n"); 07406 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07407 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07408 break; 07409 } 07410 registry_authrequest(iaxs[fr.callno]->peer, fr.callno); 07411 break; 07412 case IAX_COMMAND_REGACK: 07413 if (iax2_ack_registry(&ies, &sin, fr.callno)) 07414 ast_log(LOG_WARNING, "Registration failure\n"); 07415 /* Send ack immediately, before we destroy */ 07416 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07417 iax2_destroy_nolock(fr.callno); 07418 break; 07419 case IAX_COMMAND_REGREJ: 07420 if (iaxs[fr.callno]->reg) { 07421 if (authdebug) { 07422 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)); 07423 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>"); 07424 } 07425 iaxs[fr.callno]->reg->regstate = REG_STATE_REJECTED; 07426 } 07427 /* Send ack immediately, before we destroy */ 07428 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07429 iax2_destroy_nolock(fr.callno); 07430 break; 07431 case IAX_COMMAND_REGAUTH: 07432 /* Authentication request */ 07433 if (registry_rerequest(&ies, fr.callno, &sin)) { 07434 memset(&ied0, 0, sizeof(ied0)); 07435 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07436 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07437 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07438 } 07439 break; 07440 case IAX_COMMAND_TXREJ: 07441 iaxs[fr.callno]->transferring = 0; 07442 if (option_verbose > 2) 07443 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>"); 07444 memset(&iaxs[fr.callno]->transfer, 0, sizeof(iaxs[fr.callno]->transfer)); 07445 if (iaxs[fr.callno]->bridgecallno) { 07446 if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring) { 07447 iaxs[iaxs[fr.callno]->bridgecallno]->transferring = 0; 07448 send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07449 } 07450 } 07451 break; 07452 case IAX_COMMAND_TXREADY: 07453 if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { 07454 iaxs[fr.callno]->transferring = TRANSFER_READY; 07455 if (option_verbose > 2) 07456 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>"); 07457 if (iaxs[fr.callno]->bridgecallno) { 07458 if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring == TRANSFER_READY) { 07459 if (option_verbose > 2) 07460 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>", 07461 iaxs[iaxs[fr.callno]->bridgecallno]->owner ? iaxs[iaxs[fr.callno]->bridgecallno]->owner->name : "<Unknown>"); 07462 07463 /* They're both ready, now release them. */ 07464 iaxs[iaxs[fr.callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07465 iaxs[fr.callno]->transferring = TRANSFER_RELEASED; 07466 ast_set_flag(iaxs[iaxs[fr.callno]->bridgecallno], IAX_ALREADYGONE); 07467 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 07468 07469 /* Stop doing lag & ping requests */ 07470 stop_stuff(fr.callno); 07471 stop_stuff(iaxs[fr.callno]->bridgecallno); 07472 07473 memset(&ied0, 0, sizeof(ied0)); 07474 memset(&ied1, 0, sizeof(ied1)); 07475 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr.callno]->bridgecallno]->peercallno); 07476 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->peercallno); 07477 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07478 send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07479 07480 } 07481 } 07482 } 07483 break; 07484 case IAX_COMMAND_TXREQ: 07485 try_transfer(iaxs[fr.callno], &ies); 07486 break; 07487 case IAX_COMMAND_TXCNT: 07488 if (iaxs[fr.callno]->transferring) 07489 send_command_transfer(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07490 break; 07491 case IAX_COMMAND_TXREL: 07492 /* Send ack immediately, rather than waiting until we've changed addresses */ 07493 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07494 complete_transfer(fr.callno, &ies); 07495 stop_stuff(fr.callno); /* for attended transfer to work with libiax */ 07496 break; 07497 case IAX_COMMAND_DPREP: 07498 complete_dpreply(iaxs[fr.callno], &ies); 07499 break; 07500 case IAX_COMMAND_UNSUPPORT: 07501 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07502 break; 07503 case IAX_COMMAND_FWDOWNL: 07504 /* Firmware download */ 07505 memset(&ied0, 0, sizeof(ied0)); 07506 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07507 if (res < 0) 07508 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07509 else if (res > 0) 07510 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07511 else 07512 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07513 break; 07514 default: 07515 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno); 07516 memset(&ied0, 0, sizeof(ied0)); 07517 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07518 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07519 } 07520 /* Don't actually pass these frames along */ 07521 if ((f.subclass != IAX_COMMAND_ACK) && 07522 (f.subclass != IAX_COMMAND_TXCNT) && 07523 (f.subclass != IAX_COMMAND_TXACC) && 07524 (f.subclass != IAX_COMMAND_INVAL) && 07525 (f.subclass != IAX_COMMAND_VNAK)) { 07526 if (iaxs[fr.callno] && iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) 07527 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07528 } 07529 ast_mutex_unlock(&iaxsl[fr.callno]); 07530 return 1; 07531 } 07532 /* Unless this is an ACK or INVAL frame, ack it */ 07533 if (iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) 07534 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07535 } else if (minivid) { 07536 f.frametype = AST_FRAME_VIDEO; 07537 if (iaxs[fr.callno]->videoformat > 0) 07538 f.subclass = iaxs[fr.callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07539 else { 07540 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07541 iax2_vnak(fr.callno); 07542 ast_mutex_unlock(&iaxsl[fr.callno]); 07543 return 1; 07544 } 07545 f.datalen = res - sizeof(struct ast_iax2_video_hdr); 07546 if (f.datalen) 07547 f.data = buf + sizeof(struct ast_iax2_video_hdr); 07548 else 07549 f.data = NULL; 07550 #ifdef IAXTESTS 07551 if (test_resync) { 07552 fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); 07553 } else 07554 #endif /* IAXTESTS */ 07555 fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); 07556 } else { 07557 /* A mini frame */ 07558 f.frametype = AST_FRAME_VOICE; 07559 if (iaxs[fr.callno]->voiceformat > 0) 07560 f.subclass = iaxs[fr.callno]->voiceformat; 07561 else { 07562 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07563 iax2_vnak(fr.callno); 07564 ast_mutex_unlock(&iaxsl[fr.callno]); 07565 return 1; 07566 } 07567 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07568 if (f.datalen < 0) { 07569 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07570 ast_mutex_unlock(&iaxsl[fr.callno]); 07571 return 1; 07572 } 07573 if (f.datalen) 07574 f.data = buf + sizeof(struct ast_iax2_mini_hdr); 07575 else 07576 f.data = NULL; 07577 #ifdef IAXTESTS 07578 if (test_resync) { 07579 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07580 } else 07581 #endif /* IAXTESTS */ 07582 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07583 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07584 } 07585 /* Don't pass any packets until we're started */ 07586 if (!ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 07587 ast_mutex_unlock(&iaxsl[fr.callno]); 07588 return 1; 07589 } 07590 /* Common things */ 07591 f.src = "IAX2"; 07592 f.mallocd = 0; 07593 f.offset = 0; 07594 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07595 f.samples = ast_codec_get_samples(&f); 07596 /* We need to byteswap incoming slinear samples from network byte order */ 07597 if (f.subclass == AST_FORMAT_SLINEAR) 07598 ast_frame_byteswap_be(&f); 07599 } else 07600 f.samples = 0; 07601 iax_frame_wrap(&fr, &f); 07602 07603 /* If this is our most recent packet, use it as our basis for timestamping */ 07604 if (iaxs[fr.callno]->last < fr.ts) { 07605 /*iaxs[fr.callno]->last = fr.ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07606 fr.outoforder = 0; 07607 } else { 07608 if (option_debug && iaxdebug) 07609 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); 07610 fr.outoforder = -1; 07611 } 07612 #ifdef BRIDGE_OPTIMIZATION 07613 if (iaxs[fr.callno]->bridgecallno) { 07614 forward_delivery(&fr); 07615 } else { 07616 duped_fr = iaxfrdup2(&fr); 07617 if (duped_fr) { 07618 schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); 07619 } 07620 } 07621 #else 07622 duped_fr = iaxfrdup2(&fr); 07623 if (duped_fr) { 07624 schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); 07625 } 07626 #endif 07627 07628 if (iaxs[fr.callno]->last < fr.ts) { 07629 iaxs[fr.callno]->last = fr.ts; 07630 #if 1 07631 if (option_debug && iaxdebug) 07632 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 07633 #endif 07634 } 07635 07636 /* Always run again */ 07637 ast_mutex_unlock(&iaxsl[fr.callno]); 07638 return 1; 07639 }
|
|
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 8005 of file chan_iax2.c. References ast_pthread_create, netthreadid, and network_thread(). Referenced by load_module(). 08006 { 08007 return ast_pthread_create(&netthreadid, NULL, network_thread, NULL); 08008 }
|
|
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 9547 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. 09548 { 09549 ast_mutex_destroy(&iaxq.lock); 09550 ast_mutex_destroy(&userl.lock); 09551 ast_mutex_destroy(&peerl.lock); 09552 ast_mutex_destroy(&waresl.lock); 09553 ast_custom_function_unregister(&iaxpeer_function); 09554 return __unload_module(); 09555 }
|
|
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 9656 of file chan_iax2.c. References usecnt. 09657 { 09658 return usecnt; 09659 }
|
|
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 9446 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9438 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 debug\n" " Enables dumping of IAX packets for debugging purposes\n" Definition at line 9430 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 9472 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 9392 of file chan_iax2.c. |
|
|
|
Definition at line 9366 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 9454 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 9293 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 9450 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9442 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no debug\n" " Disables dumping of IAX packets for debugging purposes\n" Definition at line 9434 of file chan_iax2.c. |
|
Definition at line 7728 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 7730 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 9388 of file chan_iax2.c. |
|
Definition at line 7729 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 9380 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show channels\n" " Lists all currently active IAX channels.\n" Definition at line 9408 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show firmware\n" " Lists all known IAX firmware images.\n" Definition at line 9422 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 9412 of file chan_iax2.c. |
|
Initial value: "Usage: iax show peer <name>\n" " Display details on specific IAX peer\n" Definition at line 9384 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 9416 of file chan_iax2.c. |
|
Definition at line 9396 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show registry\n" " Lists all registration requests and status.\n" Definition at line 9426 of file chan_iax2.c. |
|
Initial value: "Usage: iax show stats\n" " Display statistics on IAX channel driver.\n" Definition at line 9376 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 9403 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(). |