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