#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 <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 | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | NEWJB |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | TRUNK_CALL_START 0x4000 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_MESSAGEDETAIL = (1 << 8), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH } |
Functions | |
int | __do_deliver (void *data) |
int | __iax2_show_peers (int manager, int fd, int argc, char *argv[]) |
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) |
int | __unload_module (void) |
int | apply_context (struct iax2_context *con, char *context) |
int | ast_cli_netstats (int fd, int limit_fmt) |
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) | |
int | attempt_transmit (void *data) |
int | auth_fail (int callno, int failcode) |
int | auth_reject (void *nothing) |
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) |
int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey) |
int | authenticate_request (struct chan_iax2_pvt *p) |
int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
int | auto_congest (void *nothing) |
int | auto_hangup (void *nothing) |
iax2_context * | build_context (char *context) |
void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
iax2_peer * | build_peer (const char *name, struct ast_variable *v, int temponly) |
iax2_user * | build_user (const char *name, struct ast_variable *v, int temponly) |
int | cache_get_callno_locked (const char *data) |
unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
char * | complete_iax2_show_peer (char *line, char *word, int pos, int state) |
int | complete_transfer (int callno, struct iax_ies *ies) |
unsigned char | compress_subclass (int subclass) |
void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai) |
int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
void | delete_users (void) |
char * | description () |
Provides a description of the module. | |
void | destroy_firmware (struct iax_firmware *cur) |
void | destroy_peer (struct iax2_peer *peer) |
void | destroy_user (struct iax2_user *user) |
void | dp_lookup (int callno, char *context, char *callednum, char *callerid, int skiplock) |
void * | dp_lookup_thread (void *data) |
int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
int | expire_registry (void *data) |
iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd) |
iax2_peer * | find_peer (const char *name, int realtime) |
iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
void | free_context (struct iax2_context *con) |
char * | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
int | get_auth_methods (char *value) |
int | get_encrypt_methods (const char *s) |
int | get_from_jb (void *p) |
int | handle_error (void) |
int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
int | iax2_answer (struct ast_channel *c) |
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) |
int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
unsigned int | iax2_datetime (char *tz) |
void | iax2_destroy (int callno) |
void | iax2_destroy_nolock (int callno) |
int | iax2_devicestate (void *data) |
int | iax2_digit (struct ast_channel *c, char digit) |
int | iax2_do_debug (int fd, int argc, char *argv[]) |
int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
int | iax2_do_register (struct iax2_registry *reg) |
int | iax2_do_register_s (void *data) |
int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data) |
int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
void | iax2_frame_free (struct iax_frame *fr) |
int | iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer) |
int | iax2_getpeertrunk (struct sockaddr_in sin) |
int | iax2_hangup (struct ast_channel *c) |
int | iax2_indicate (struct ast_channel *c, int condition) |
int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
int | iax2_no_debug (int fd, int argc, char *argv[]) |
int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
int | iax2_poke_noanswer (void *data) |
int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
int | iax2_poke_peer_s (void *data) |
int | iax2_predestroy (int callno) |
int | iax2_predestroy_nolock (int callno) |
int | iax2_prov_app (struct ast_channel *chan, void *data) |
int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
char * | iax2_prov_complete_template_3rd (char *line, char *word, int pos, int state) |
int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
int | iax2_queue_frame (int callno, struct ast_frame *f) |
ast_frame * | iax2_read (struct ast_channel *c) |
int | iax2_register (char *value, int lineno) |
int | iax2_reload (int fd, int argc, char *argv[]) |
ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
int | iax2_sendtext (struct ast_channel *c, const char *text) |
int | iax2_set_jitter (int fd, int argc, char *argv[]) |
int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
int | iax2_show_cache (int fd, int argc, char *argv[]) |
int | iax2_show_channels (int fd, int argc, char *argv[]) |
int | iax2_show_firmware (int fd, int argc, char *argv[]) |
int | iax2_show_netstats (int fd, int argc, char *argv[]) |
int | iax2_show_peer (int fd, int argc, char *argv[]) |
int | iax2_show_peers (int fd, int argc, char *argv[]) |
int | iax2_show_registry (int fd, int argc, char *argv[]) |
int | iax2_show_stats (int fd, int argc, char *argv[]) |
int | iax2_show_users (int fd, int argc, char *argv[]) |
int | iax2_start_transfer (unsigned short callno0, unsigned short callno1) |
int | iax2_test_losspct (int fd, int argc, char *argv[]) |
int | iax2_transfer (struct ast_channel *c, const char *dest) |
int | iax2_transmit (struct iax_frame *fr) |
int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
int | iax2_vnak (int callno) |
int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
int | iax_check_version (char *dev) |
void | iax_debug_output (const char *data) |
void | iax_error_output (const char *data) |
int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
void * | iax_park_thread (void *stuff) |
iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
void | jb_debug_output (const char *fmt,...) |
void | jb_error_output (const char *fmt,...) |
void | jb_warning_output (const char *fmt,...) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
void | lock_both (unsigned short callno0, unsigned short callno1) |
int | make_trunk (unsigned short callno, int locked) |
int | manager_iax2_show_netstats (struct mansession *s, struct message *m) |
int | manager_iax2_show_peers (struct mansession *s, struct message *m) |
int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur) |
void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
void * | network_thread (void *ignore) |
chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, int lockpeer, const char *host) |
void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
void | prune_peers (void) |
void | prune_users (void) |
int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
void | realtime_update_peer (const char *peername, struct sockaddr_in *sin) |
iax2_user * | realtime_user (const char *username) |
void | reg_source_db (struct iax2_peer *p) |
void | register_peer_exten (struct iax2_peer *peer, int onoff) |
int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
int | registry_authrequest (char *name, int callno) |
int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
int | reload_config (void) |
void | reload_firmware (void) |
void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
int | send_lagrq (void *data) |
int | send_packet (struct iax_frame *f) |
int | send_ping (void *data) |
int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
int | set_config (char *config_file, int reload) |
void | set_timing (void) |
int | socket_read (int *id, int fd, short events, void *cbdata) |
void | spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid) |
int | start_network_thread (void) |
int | stop_stuff (int callno) |
int | timing_read (int *id, int fd, short events, void *cbdata) |
int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
int | try_firmware (char *s) |
int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
int | uncompress_subclass (unsigned char csub) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
void | unlock_both (unsigned short callno0, unsigned short callno1) |
void | unwrap_timestamp (struct iax_frame *fr) |
void | update_jbsched (struct chan_iax2_pvt *pvt) |
void | update_max_nontrunk (void) |
void | update_max_trunk (void) |
int | update_packet (struct iax_frame *f) |
int | update_registry (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
int | usecount () |
Provides a usecount. | |
void | vnak_retransmit (int callno, int last) |
Variables | |
char | accountcode [AST_MAX_ACCOUNT_CODE] |
int | amaflags = 0 |
int | authdebug = 1 |
int | autokill = 0 |
const char | channeltype [] = "IAX2" |
char | context [80] = "default" |
char | debug_jb_usage [] |
char | debug_trunk_usage [] |
char | debug_usage [] |
int | defaultsockfd = -1 |
int | delayreject = 0 |
const char | desc [] = "Inter Asterisk eXchange (Ver 2)" |
iax2_dpcache * | dpcache |
int | global_rtautoclear = 120 |
ast_flags | globalflags = { 0 } |
int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
ast_cli_entry | iax2_cli [] |
int | iax2_dropcount = DEFAULT_DROP |
int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(* | iax2_regfunk )(char *username, int onoff) = NULL |
char | iax2_reload_usage [] |
enum { ... } | iax2_state |
ast_switch | iax2_switch |
const struct ast_channel_tech | iax2_tech |
char | iax2_test_losspct_usage [] |
int | iaxcompat = 0 |
int | iaxdebug = 0 |
int | iaxdefaultdpcache = 10 * 60 |
int | iaxdefaulttimeout = 5 |
ast_custom_function | iaxpeer_function |
ast_iax2_queue | iaxq |
chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
int | iaxtrunkdebug = 0 |
io_context * | io |
char | jitter_usage [] |
int | jittershrinkrate = 2 |
int | lagrq_time = 10 |
char | language [MAX_LANGUAGE] = "" |
timeval | lastused [IAX_MAX_CALLS] |
int | max_jitter_buffer = MAX_JITTER_BUFFER |
int | max_reg_expire |
int | max_retries = 4 |
int | maxjitterbuffer = 1000 |
int | maxjitterinterps = 10 |
int | maxnontrunkcall = 1 |
int | maxtrunkcall = TRUNK_CALL_START |
int | min_jitter_buffer = MIN_JITTER_BUFFER |
int | min_reg_expire |
ast_netsock_list * | netsock |
pthread_t | netthreadid = AST_PTHREADT_NULL |
char | no_debug_jb_usage [] |
char | no_debug_trunk_usage [] |
char | no_debug_usage [] |
char * | papp = "IAX2Provision" |
char * | pdescrip |
ast_peer_list | peerl |
int | ping_time = 20 |
ast_codec_pref | prefs |
char | prune_realtime_usage [] |
char * | psyn = "Provision a calling IAXy with a given template" |
char | regcontext [AST_MAX_CONTEXT] = "" |
iax2_registry * | registrations |
int | resyncthreshold = 1000 |
sched_context * | sched |
char | show_cache_usage [] |
char | show_channels_usage [] |
char | show_firmware_usage [] |
char | show_netstats_usage [] |
char | show_peer_usage [] |
char | show_peers_usage [] |
char | show_prov_usage [] |
char | show_reg_usage [] |
char | show_stats_usage [] |
char | show_users_usage [] |
const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
int | test_losspct = 0 |
int | timingfd = -1 |
int | tos = 0 |
iax2_trunk_peer * | tpeers |
int | trunkfreq = 20 |
int | usecnt |
ast_user_list | userl |
ast_firmware_list | waresl |
Definition in file chan_iax2.c.
|
Extension can exist Definition at line 626 of file chan_iax2.c. |
|
Extension exists Definition at line 622 of file chan_iax2.c. |
|
Matchmore Definition at line 636 of file chan_iax2.c. |
|
Extension is nonexistent Definition at line 624 of file chan_iax2.c. |
|
Waiting to hear back response Definition at line 628 of file chan_iax2.c. |
|
Timed out Definition at line 630 of file chan_iax2.c. |
|
Request transmitted Definition at line 632 of file chan_iax2.c. |
|
Timeout Definition at line 634 of file chan_iax2.c. |
|
Definition at line 122 of file chan_iax2.c. Referenced by ast_iax2_new(), and iax2_call(). |
|
Definition at line 131 of file chan_iax2.c. |
|
Definition at line 126 of file chan_iax2.c. |
|
Definition at line 202 of file chan_iax2.c. Referenced by handle_response_peerpoke(), and sip_poke_noanswer(). |
|
Definition at line 201 of file chan_iax2.c. Referenced by handle_response_peerpoke(). |
|
Definition at line 200 of file chan_iax2.c. |
|
Definition at line 124 of file chan_iax2.c. |
|
40ms, uncompressed linear * 10 channels Definition at line 416 of file chan_iax2.c. Referenced by iax2_trunk_queue(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Referenced by iax2_show_channels(). |
|
Definition at line 136 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 344 of file chan_iax2.c. Referenced by iax2_trunk_queue(). |
|
Definition at line 185 of file chan_iax2.c. Referenced by cache_get_callno_locked(). |
|
Value: (IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_ADPCM) Definition at line 192 of file chan_iax2.c. |
|
Value: (IAX_CAPABILITY_LOWBANDWIDTH & \ ~AST_FORMAT_G723_1) Definition at line 196 of file chan_iax2.c. |
|
Value: (IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW) Definition at line 187 of file chan_iax2.c. |
|
Definition at line 105 of file chan_iax2.c. |
|
Definition at line 413 of file chan_iax2.c. |
|
Definition at line 411 of file chan_iax2.c. |
|
maximum difference between actual and predicted ts for sending Definition at line 419 of file chan_iax2.c. |
|
40ms, uncompressed linear * 200 channels Definition at line 417 of file chan_iax2.c. Referenced by timing_read(). |
|
Definition at line 125 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 414 of file chan_iax2.c. |
|
Definition at line 410 of file chan_iax2.c. |
|
Definition at line 133 of file chan_iax2.c. |
|
Definition at line 941 of file chan_iax2.c. |
|
Definition at line 942 of file chan_iax2.c. Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request(). |
|
Definition at line 940 of file chan_iax2.c. Referenced by socket_read(). |
|
Definition at line 98 of file chan_iax2.c. |
|
Definition at line 121 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 129 of file chan_iax2.c. Referenced by update_max_nontrunk(). |
|
Definition at line 422 of file chan_iax2.c. Referenced by schedule_delivery(). |
|
Definition at line 232 of file chan_iax2.c. 00232 { 00233 IAX_STATE_STARTED = (1 << 0), 00234 IAX_STATE_AUTHENTICATED = (1 << 1), 00235 IAX_STATE_TBD = (1 << 2) 00236 } iax2_state;
|
|
Definition at line 243 of file chan_iax2.c. 00243 { 00244 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00245 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00246 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00247 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00248 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00249 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00250 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00251 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00252 IAX_MESSAGEDETAIL = (1 << 8), /*!< Show exact numbers */ 00253 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00254 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00255 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00256 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00257 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00258 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00259 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00260 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00261 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00262 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00263 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00264 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00265 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00266 IAX_TRUNKTIMESTAMPS = (1 << 22) /*!< Send trunk timestamps */ 00267 } iax2_flags;
|
|
Definition at line 375 of file chan_iax2.c. 00375 { 00376 REG_STATE_UNREGISTERED = 0, 00377 REG_STATE_REGSENT, 00378 REG_STATE_AUTHSENT, 00379 REG_STATE_REGISTERED, 00380 REG_STATE_REJECTED, 00381 REG_STATE_TIMEOUT, 00382 REG_STATE_NOAUTH 00383 };
|
|
Definition at line 385 of file chan_iax2.c. 00385 { 00386 TRANSFER_NONE = 0, 00387 TRANSFER_BEGIN, 00388 TRANSFER_READY, 00389 TRANSFER_RELEASED, 00390 TRANSFER_PASSTHROUGH 00391 };
|
|
Definition at line 1407 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(), and schedule_delivery(). 01408 { 01409 /* Just deliver the packet by using queueing. This is called by 01410 the IAX thread with the iaxsl lock held. */ 01411 struct iax_frame *fr = data; 01412 fr->retrans = -1; 01413 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01414 iax2_queue_frame(fr->callno, &fr->af); 01415 /* Free our iax frame */ 01416 iax2_frame_free(fr); 01417 /* And don't run again */ 01418 return 0; 01419 }
|
|
Definition at line 4179 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, and iax2_peer::username. Referenced by iax2_show_peers(), and manager_iax2_show_peers(). 04180 { 04181 regex_t regexbuf; 04182 int havepattern = 0; 04183 int total_peers = 0; 04184 int online_peers = 0; 04185 int offline_peers = 0; 04186 int unmonitored_peers = 0; 04187 04188 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04189 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04190 04191 struct iax2_peer *peer; 04192 char name[256]; 04193 char iabuf[INET_ADDRSTRLEN]; 04194 int registeredonly=0; 04195 char *term = manager ? "\r\n" : "\n"; 04196 04197 switch (argc) { 04198 case 6: 04199 if (!strcasecmp(argv[3], "registered")) 04200 registeredonly = 1; 04201 else 04202 return RESULT_SHOWUSAGE; 04203 if (!strcasecmp(argv[4], "like")) { 04204 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04205 return RESULT_SHOWUSAGE; 04206 havepattern = 1; 04207 } else 04208 return RESULT_SHOWUSAGE; 04209 break; 04210 case 5: 04211 if (!strcasecmp(argv[3], "like")) { 04212 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04213 return RESULT_SHOWUSAGE; 04214 havepattern = 1; 04215 } else 04216 return RESULT_SHOWUSAGE; 04217 break; 04218 case 4: 04219 if (!strcasecmp(argv[3], "registered")) 04220 registeredonly = 1; 04221 else 04222 return RESULT_SHOWUSAGE; 04223 break; 04224 case 3: 04225 break; 04226 default: 04227 return RESULT_SHOWUSAGE; 04228 } 04229 04230 ast_mutex_lock(&peerl.lock); 04231 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04232 for (peer = peerl.peers;peer;peer = peer->next) { 04233 char nm[20]; 04234 char status[20]; 04235 char srch[2000]; 04236 int retstatus; 04237 04238 if (registeredonly && !peer->addr.sin_addr.s_addr) 04239 continue; 04240 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04241 continue; 04242 04243 if (!ast_strlen_zero(peer->username)) 04244 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04245 else 04246 ast_copy_string(name, peer->name, sizeof(name)); 04247 04248 retstatus = peer_status(peer, status, sizeof(status)); 04249 if (retstatus > 0) 04250 online_peers++; 04251 else if (!retstatus) 04252 offline_peers++; 04253 else 04254 unmonitored_peers++; 04255 04256 ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)); 04257 04258 snprintf(srch, sizeof(srch), FORMAT, name, 04259 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04260 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04261 nm, 04262 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04263 peer->encmethods ? "(E)" : " ", status, term); 04264 04265 ast_cli(fd, FORMAT, name, 04266 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04267 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04268 nm, 04269 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04270 peer->encmethods ? "(E)" : " ", status, term); 04271 total_peers++; 04272 } 04273 ast_mutex_unlock(&peerl.lock); 04274 04275 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04276 04277 if (havepattern) 04278 regfree(®exbuf); 04279 04280 return RESULT_SUCCESS; 04281 #undef FORMAT 04282 #undef FORMAT2 04283 }
|
|
Definition at line 4645 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(). 04647 { 04648 struct ast_frame f; 04649 f.frametype = type; 04650 f.subclass = command; 04651 f.datalen = datalen; 04652 f.samples = 0; 04653 f.mallocd = 0; 04654 f.offset = 0; 04655 f.src = (char *)__FUNCTION__; 04656 f.data = (char *)data; 04657 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04658 }
|
|
Definition at line 9499 of file chan_iax2.c. References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_netsock_release(), ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_cli, iax2_destroy(), iax2_switch, iax2_tech, iax_provision_unload(), iaxs, netsock, netthreadid, papp, sched, and sched_context_destroy(). Referenced by load_module(), and unload_module(). 09500 { 09501 int x; 09502 /* Cancel the network thread, close the net socket */ 09503 if (netthreadid != AST_PTHREADT_NULL) { 09504 pthread_cancel(netthreadid); 09505 pthread_join(netthreadid, NULL); 09506 } 09507 ast_netsock_release(netsock); 09508 for (x=0;x<IAX_MAX_CALLS;x++) 09509 if (iaxs[x]) 09510 iax2_destroy(x); 09511 ast_manager_unregister( "IAXpeers" ); 09512 ast_manager_unregister( "IAXnetstats" ); 09513 ast_unregister_application(papp); 09514 ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0])); 09515 ast_unregister_switch(&iax2_switch); 09516 ast_channel_unregister(&iax2_tech); 09517 delete_users(); 09518 iax_provision_unload(); 09519 sched_context_destroy(sched); 09520 return 0; 09521 }
|
|
Definition at line 4698 of file chan_iax2.c. References context, iax2_context::context, and iax2_context::next. Referenced by check_access(). 04699 { 04700 while(con) { 04701 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04702 return -1; 04703 con = con->next; 04704 } 04705 return 0; 04706 }
|
|
Definition at line 4465 of file chan_iax2.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::bridgecallno, jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, chan_iax2_pvt::frames_dropped, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr. Referenced by iax2_show_netstats(), and manager_iax2_show_netstats(). 04466 { 04467 int x; 04468 int numchans = 0; 04469 for (x=0;x<IAX_MAX_CALLS;x++) { 04470 ast_mutex_lock(&iaxsl[x]); 04471 if (iaxs[x]) { 04472 #ifdef BRIDGE_OPTIMIZATION 04473 if (iaxs[x]->bridgecallno) { 04474 if (limit_fmt) 04475 ast_cli(fd, "%-25.25s <NATIVE BRIDGED>", 04476 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04477 else 04478 ast_cli(fd, "%s <NATIVE BRIDGED>", 04479 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04480 } else 04481 #endif 04482 { 04483 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04484 char *fmt; 04485 #ifdef NEWJB 04486 jb_info jbinfo; 04487 04488 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04489 jb_getinfo(iaxs[x]->jb, &jbinfo); 04490 localjitter = jbinfo.jitter; 04491 localdelay = jbinfo.current - jbinfo.min; 04492 locallost = jbinfo.frames_lost; 04493 locallosspct = jbinfo.losspct/1000; 04494 localdropped = jbinfo.frames_dropped; 04495 localooo = jbinfo.frames_ooo; 04496 } else { 04497 localjitter = -1; 04498 localdelay = 0; 04499 locallost = -1; 04500 locallosspct = -1; 04501 localdropped = 0; 04502 localooo = -1; 04503 } 04504 #else 04505 localjitter = iaxs[x]->jitter; 04506 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) 04507 { 04508 localdelay = jitterbufsize(iaxs[x]); 04509 localdropped = iaxs[x]->frames_dropped; 04510 } else { 04511 localdelay = localdropped = 0; 04512 } 04513 locallost = locallosspct = localooo = -1; 04514 #endif 04515 if (limit_fmt) 04516 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04517 else 04518 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04519 ast_cli(fd, fmt, 04520 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04521 iaxs[x]->pingtime, 04522 localjitter, 04523 localdelay, 04524 locallost, 04525 locallosspct, 04526 localdropped, 04527 localooo, 04528 iaxs[x]->frames_received/1000, 04529 iaxs[x]->remote_rr.jitter, 04530 iaxs[x]->remote_rr.delay, 04531 iaxs[x]->remote_rr.losscnt, 04532 iaxs[x]->remote_rr.losspct, 04533 iaxs[x]->remote_rr.dropped, 04534 iaxs[x]->remote_rr.ooo, 04535 iaxs[x]->remote_rr.packets/1000 04536 ); 04537 } 04538 numchans++; 04539 } 04540 ast_mutex_unlock(&iaxsl[x]); 04541 } 04542 return numchans; 04543 }
|
|
|
|
|
|
|
|
|
Definition at line 1693 of file chan_iax2.c. References iax_frame::af, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), attempt_transmit(), 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, iaxq, iaxs, iaxsl, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, iax2_registry::refresh, chan_iax2_pvt::reg, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, and update_packet(). Referenced by attempt_transmit(), and network_thread(). 01694 { 01695 /* Attempt to transmit the frame to the remote peer... 01696 Called without iaxsl held. */ 01697 struct iax_frame *f = data; 01698 int freeme=0; 01699 int callno = f->callno; 01700 char iabuf[INET_ADDRSTRLEN]; 01701 /* Make sure this call is still active */ 01702 if (callno) 01703 ast_mutex_lock(&iaxsl[callno]); 01704 if ((f->callno) && iaxs[f->callno]) { 01705 if ((f->retries < 0) /* Already ACK'd */ || 01706 (f->retries >= max_retries) /* Too many attempts */) { 01707 /* Record an error if we've transmitted too many times */ 01708 if (f->retries >= max_retries) { 01709 if (f->transfer) { 01710 /* Transfer timeout */ 01711 send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 01712 } else if (f->final) { 01713 if (f->final) 01714 iax2_destroy_nolock(f->callno); 01715 } else { 01716 if (iaxs[f->callno]->owner) 01717 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); 01718 iaxs[f->callno]->error = ETIMEDOUT; 01719 if (iaxs[f->callno]->owner) { 01720 struct ast_frame fr = { 0, }; 01721 /* Hangup the fd */ 01722 fr.frametype = AST_FRAME_CONTROL; 01723 fr.subclass = AST_CONTROL_HANGUP; 01724 iax2_queue_frame(f->callno, &fr); 01725 /* Remember, owner could disappear */ 01726 if (iaxs[f->callno]->owner) 01727 iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01728 } else { 01729 if (iaxs[f->callno]->reg) { 01730 memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us)); 01731 iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT; 01732 iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 01733 } 01734 iax2_destroy_nolock(f->callno); 01735 } 01736 } 01737 01738 } 01739 freeme++; 01740 } else { 01741 /* Update it if it needs it */ 01742 update_packet(f); 01743 /* Attempt transmission */ 01744 send_packet(f); 01745 f->retries++; 01746 /* Try again later after 10 times as long */ 01747 f->retrytime *= 10; 01748 if (f->retrytime > MAX_RETRY_TIME) 01749 f->retrytime = MAX_RETRY_TIME; 01750 /* Transfer messages max out at one second */ 01751 if (f->transfer && (f->retrytime > 1000)) 01752 f->retrytime = 1000; 01753 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 01754 } 01755 } else { 01756 /* Make sure it gets freed */ 01757 f->retries = -1; 01758 freeme++; 01759 } 01760 if (callno) 01761 ast_mutex_unlock(&iaxsl[callno]); 01762 /* Do not try again */ 01763 if (freeme) { 01764 /* Don't attempt delivery, just remove it from the queue */ 01765 ast_mutex_lock(&iaxq.lock); 01766 if (f->prev) 01767 f->prev->next = f->next; 01768 else 01769 iaxq.head = f->next; 01770 if (f->next) 01771 f->next->prev = f->prev; 01772 else 01773 iaxq.tail = f->prev; 01774 iaxq.count--; 01775 ast_mutex_unlock(&iaxq.lock); 01776 f->retrans = -1; 01777 /* Free the IAX frame */ 01778 iax2_frame_free(f); 01779 } 01780 return 0; 01781 }
|
|
Definition at line 5854 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iaxs, iaxsl, and sched. Referenced by socket_read(). 05855 { 05856 /* Schedule sending the authentication failure in one second, to prevent 05857 guessing */ 05858 ast_mutex_lock(&iaxsl[callno]); 05859 iaxs[callno]->authfail = failcode; 05860 if (delayreject) { 05861 ast_mutex_lock(&iaxsl[callno]); 05862 if (iaxs[callno]->authid > -1) 05863 ast_sched_del(sched, iaxs[callno]->authid); 05864 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 05865 ast_mutex_unlock(&iaxsl[callno]); 05866 } else 05867 auth_reject((void *)(long)callno); 05868 ast_mutex_unlock(&iaxsl[callno]); 05869 return 0; 05870 }
|
|
Definition at line 5832 of file chan_iax2.c. References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final(). Referenced by auth_fail(). 05833 { 05834 /* Called from IAX thread only, without iaxs lock */ 05835 int callno = (int)(long)(nothing); 05836 struct iax_ie_data ied; 05837 ast_mutex_lock(&iaxsl[callno]); 05838 if (iaxs[callno]) { 05839 iaxs[callno]->authid = -1; 05840 memset(&ied, 0, sizeof(ied)); 05841 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 05842 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 05843 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 05844 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 05845 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 05846 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 05847 } 05848 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 05849 } 05850 ast_mutex_unlock(&iaxsl[callno]); 05851 return 0; 05852 }
|
|
Definition at line 5162 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_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update(). Referenced by authenticate_reply(), process_message(), and registry_rerequest(). 05163 { 05164 int res = -1; 05165 int x; 05166 char iabuf[INET_ADDRSTRLEN]; 05167 if (!ast_strlen_zero(keyn)) { 05168 if (!(authmethods & IAX_AUTH_RSA)) { 05169 if (ast_strlen_zero(secret)) 05170 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)); 05171 } else if (ast_strlen_zero(challenge)) { 05172 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05173 } else { 05174 char sig[256]; 05175 struct ast_key *key; 05176 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05177 if (!key) { 05178 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05179 } else { 05180 if (ast_sign(key, challenge, sig)) { 05181 ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n"); 05182 res = -1; 05183 } else { 05184 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05185 res = 0; 05186 } 05187 } 05188 } 05189 } 05190 /* Fall back */ 05191 if (res && !ast_strlen_zero(secret)) { 05192 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05193 struct MD5Context md5; 05194 unsigned char digest[16]; 05195 char digres[128]; 05196 MD5Init(&md5); 05197 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05198 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05199 MD5Final(digest, &md5); 05200 /* If they support md5, authenticate with it. */ 05201 for (x=0;x<16;x++) 05202 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05203 if (ecx && dcx) 05204 build_enc_keys(digest, ecx, dcx); 05205 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05206 res = 0; 05207 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05208 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05209 res = 0; 05210 } else 05211 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); 05212 } 05213 return res; 05214 }
|
|
Definition at line 5216 of file chan_iax2.c. References iax2_peer::addr, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, authenticate(), iax_ies::authmethods, chan_iax2_pvt::challenge, iax_ies::challenge, chan_iax2_pvt::dcx, destroy_peer(), chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::next, iax2_peer::outkey, chan_iax2_pvt::peer, peerl, ast_peer_list::peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, chan_iax2_pvt::username, and iax_ies::username. Referenced by socket_read(). 05217 { 05218 struct iax2_peer *peer; 05219 /* Start pessimistic */ 05220 int res = -1; 05221 int authmethods = 0; 05222 struct iax_ie_data ied; 05223 05224 memset(&ied, 0, sizeof(ied)); 05225 05226 if (ies->username) 05227 ast_copy_string(p->username, ies->username, sizeof(p->username)); 05228 if (ies->challenge) 05229 ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge)); 05230 if (ies->authmethods) 05231 authmethods = ies->authmethods; 05232 if (authmethods & IAX_AUTH_MD5) 05233 merge_encryption(p, ies->encmethods); 05234 else 05235 p->encmethods = 0; 05236 05237 /* Check for override RSA authentication first */ 05238 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05239 /* Normal password authentication */ 05240 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05241 } else { 05242 ast_mutex_lock(&peerl.lock); 05243 peer = peerl.peers; 05244 while(peer) { 05245 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05246 /* No peer specified at our end, or this is the peer */ 05247 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05248 /* No username specified in peer rule, or this is the right username */ 05249 && (!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))) 05250 /* No specified host, or this is our host */ 05251 ) { 05252 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05253 if (!res) 05254 break; 05255 } 05256 peer = peer->next; 05257 } 05258 ast_mutex_unlock(&peerl.lock); 05259 if (!peer) { 05260 /* We checked our list and didn't find one. It's unlikely, but possible, 05261 that we're trying to authenticate *to* a realtime peer */ 05262 if ((peer = realtime_peer(p->peer, NULL))) { 05263 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05264 if (ast_test_flag(peer, IAX_TEMPONLY)) 05265 destroy_peer(peer); 05266 } 05267 } 05268 } 05269 if (ies->encmethods) 05270 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05271 if (!res) 05272 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05273 return res; 05274 }
|
|
Definition at line 4933 of file chan_iax2.c. References AST_FRAME_IAX, ast_set_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREQ, IAX_ENCRYPTED, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, send_command(), and chan_iax2_pvt::username. Referenced by socket_read(). 04934 { 04935 struct iax_ie_data ied; 04936 int res; 04937 memset(&ied, 0, sizeof(ied)); 04938 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 04939 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 04940 snprintf(p->challenge, sizeof(p->challenge), "%d", rand()); 04941 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 04942 } 04943 if (p->encmethods) 04944 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 04945 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 04946 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 04947 if (p->encmethods) 04948 ast_set_flag(p, IAX_ENCRYPTED); 04949 return res; 04950 }
|
|
Definition at line 4952 of file chan_iax2.c. References ast_check_signature, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, key(), LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, chan_iax2_pvt::state, and strsep(). Referenced by socket_read(). 04953 { 04954 char requeststr[256]; 04955 char md5secret[256] = ""; 04956 char secret[256] = ""; 04957 char rsasecret[256] = ""; 04958 int res = -1; 04959 int x; 04960 04961 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 04962 return res; 04963 if (ies->password) 04964 ast_copy_string(secret, ies->password, sizeof(secret)); 04965 if (ies->md5_result) 04966 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 04967 if (ies->rsa_result) 04968 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 04969 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 04970 struct ast_key *key; 04971 char *keyn; 04972 char tmpkey[256]; 04973 char *stringp=NULL; 04974 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 04975 stringp=tmpkey; 04976 keyn = strsep(&stringp, ":"); 04977 while(keyn) { 04978 key = ast_key_get(keyn, AST_KEY_PUBLIC); 04979 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 04980 res = 0; 04981 break; 04982 } else if (!key) 04983 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 04984 keyn = strsep(&stringp, ":"); 04985 } 04986 } else if (p->authmethods & IAX_AUTH_MD5) { 04987 struct MD5Context md5; 04988 unsigned char digest[16]; 04989 char *tmppw, *stringp; 04990 04991 tmppw = ast_strdupa(p->secret); 04992 stringp = tmppw; 04993 while((tmppw = strsep(&stringp, ";"))) { 04994 MD5Init(&md5); 04995 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 04996 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04997 MD5Final(digest, &md5); 04998 /* If they support md5, authenticate with it. */ 04999 for (x=0;x<16;x++) 05000 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05001 if (!strcasecmp(requeststr, md5secret)) { 05002 res = 0; 05003 break; 05004 } 05005 } 05006 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05007 if (!strcmp(secret, p->secret)) 05008 res = 0; 05009 } 05010 return res; 05011 }
|
|
Definition at line 2827 of file chan_iax2.c. References AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO. Referenced by iax2_call(). 02828 { 02829 int callno = PTR_TO_CALLNO(nothing); 02830 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02831 ast_mutex_lock(&iaxsl[callno]); 02832 if (iaxs[callno]) { 02833 iaxs[callno]->initid = -1; 02834 iax2_queue_frame(callno, &f); 02835 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02836 } 02837 ast_mutex_unlock(&iaxsl[callno]); 02838 return 0; 02839 }
|
|
Definition at line 5872 of file chan_iax2.c. References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final(). Referenced by iax2_dprequest(), and iax2_provision(). 05873 { 05874 /* Called from IAX thread only, without iaxs lock */ 05875 int callno = (int)(long)(nothing); 05876 struct iax_ie_data ied; 05877 ast_mutex_lock(&iaxsl[callno]); 05878 if (iaxs[callno]) { 05879 iaxs[callno]->autoid = -1; 05880 memset(&ied, 0, sizeof(ied)); 05881 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 05882 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 05883 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 05884 } 05885 ast_mutex_unlock(&iaxsl[callno]); 05886 return 0; 05887 }
|
|
Definition at line 7998 of file chan_iax2.c. References context, iax2_context::context, malloc, and iax2_context::next. Referenced by build_user(). 07999 { 08000 struct iax2_context *con = malloc(sizeof(struct iax2_context)); 08001 if (con) { 08002 ast_copy_string(con->context, context, sizeof(con->context)); 08003 con->next = NULL; 08004 } 08005 return con; 08006 }
|
|
Definition at line 3780 of file chan_iax2.c. References aes_decrypt_key128(), and aes_encrypt_key128(). Referenced by authenticate(), and decrypt_frame(). 03781 { 03782 aes_encrypt_key128(digest, ecx); 03783 aes_decrypt_key128(digest, dcx); 03784 }
|
|
Definition at line 8108 of file chan_iax2.c. References iax2_peer::addr, 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(), iax2_peer::authmethods, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, free, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, iax2_peer::mailbox, malloc, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, name, iax2_peer::name, ast_variable::next, iax2_peer::next, iax2_peer::outkey, peer_set_srcaddr(), iax2_peer::peercontext, peerl, ast_peer_list::peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, iax2_peer::regexten, sched, iax2_peer::secret, iax2_peer::smoothing, iax2_peer::sockfd, timingfd, iax2_peer::username, ast_variable::value, and iax2_peer::zonetag. 08109 { 08110 struct iax2_peer *peer; 08111 struct iax2_peer *prev; 08112 struct ast_ha *oldha = NULL; 08113 int maskfound=0; 08114 int found=0; 08115 prev = NULL; 08116 ast_mutex_lock(&peerl.lock); 08117 if (!temponly) { 08118 peer = peerl.peers; 08119 while(peer) { 08120 if (!strcmp(peer->name, name)) { 08121 break; 08122 } 08123 prev = peer; 08124 peer = peer->next; 08125 } 08126 } else 08127 peer = NULL; 08128 if (peer) { 08129 found++; 08130 oldha = peer->ha; 08131 peer->ha = NULL; 08132 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08133 if (prev) { 08134 prev->next = peer->next; 08135 } else { 08136 peerl.peers = peer->next; 08137 } 08138 ast_mutex_unlock(&peerl.lock); 08139 } else { 08140 ast_mutex_unlock(&peerl.lock); 08141 peer = malloc(sizeof(struct iax2_peer)); 08142 if (peer) { 08143 memset(peer, 0, sizeof(struct iax2_peer)); 08144 peer->expire = -1; 08145 peer->pokeexpire = -1; 08146 peer->sockfd = defaultsockfd; 08147 } 08148 } 08149 if (peer) { 08150 ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08151 peer->encmethods = iax2_encryption; 08152 peer->secret[0] = '\0'; 08153 if (!found) { 08154 ast_copy_string(peer->name, name, sizeof(peer->name)); 08155 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08156 peer->expiry = min_reg_expire; 08157 } 08158 peer->prefs = prefs; 08159 peer->capability = iax2_capability; 08160 peer->smoothing = 0; 08161 peer->pokefreqok = DEFAULT_FREQ_OK; 08162 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08163 peer->context[0] = '\0'; 08164 peer->peercontext[0] = '\0'; 08165 while(v) { 08166 if (!strcasecmp(v->name, "secret")) { 08167 if (!ast_strlen_zero(peer->secret)) { 08168 strncpy(peer->secret + strlen(peer->secret), ";", sizeof(peer->secret)-strlen(peer->secret) - 1); 08169 strncpy(peer->secret + strlen(peer->secret), v->value, sizeof(peer->secret)-strlen(peer->secret) - 1); 08170 } else 08171 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 08172 } else if (!strcasecmp(v->name, "mailbox")) { 08173 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 08174 } else if (!strcasecmp(v->name, "dbsecret")) { 08175 ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret)); 08176 } else if (!strcasecmp(v->name, "mailboxdetail")) { 08177 ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 08178 } else if (!strcasecmp(v->name, "trunk")) { 08179 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08180 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08181 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08182 ast_clear_flag(peer, IAX_TRUNK); 08183 } 08184 } else if (!strcasecmp(v->name, "auth")) { 08185 peer->authmethods = get_auth_methods(v->value); 08186 } else if (!strcasecmp(v->name, "encryption")) { 08187 peer->encmethods = get_encrypt_methods(v->value); 08188 } else if (!strcasecmp(v->name, "notransfer")) { 08189 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08190 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08191 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08192 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08193 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08194 } else if (!strcasecmp(v->name, "host")) { 08195 if (!strcasecmp(v->value, "dynamic")) { 08196 /* They'll register with us */ 08197 ast_set_flag(peer, IAX_DYNAMIC); 08198 if (!found) { 08199 /* Initialize stuff iff we're not found, otherwise 08200 we keep going with what we had */ 08201 memset(&peer->addr.sin_addr, 0, 4); 08202 if (peer->addr.sin_port) { 08203 /* If we've already got a port, make it the default rather than absolute */ 08204 peer->defaddr.sin_port = peer->addr.sin_port; 08205 peer->addr.sin_port = 0; 08206 } 08207 } 08208 } else { 08209 /* Non-dynamic. Make sure we become that way if we're not */ 08210 if (peer->expire > -1) 08211 ast_sched_del(sched, peer->expire); 08212 peer->expire = -1; 08213 ast_clear_flag(peer, IAX_DYNAMIC); 08214 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08215 free(peer); 08216 return NULL; 08217 } 08218 if (!peer->addr.sin_port) 08219 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08220 } 08221 if (!maskfound) 08222 inet_aton("255.255.255.255", &peer->mask); 08223 } else if (!strcasecmp(v->name, "defaultip")) { 08224 if (ast_get_ip(&peer->defaddr, v->value)) { 08225 free(peer); 08226 return NULL; 08227 } 08228 } else if (!strcasecmp(v->name, "sourceaddress")) { 08229 peer_set_srcaddr(peer, v->value); 08230 } else if (!strcasecmp(v->name, "permit") || 08231 !strcasecmp(v->name, "deny")) { 08232 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08233 } else if (!strcasecmp(v->name, "mask")) { 08234 maskfound++; 08235 inet_aton(v->value, &peer->mask); 08236 } else if (!strcasecmp(v->name, "context")) { 08237 if (ast_strlen_zero(peer->context)) 08238 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 08239 } else if (!strcasecmp(v->name, "regexten")) { 08240 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 08241 } else if (!strcasecmp(v->name, "peercontext")) { 08242 if (ast_strlen_zero(peer->peercontext)) 08243 ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext)); 08244 } else if (!strcasecmp(v->name, "port")) { 08245 if (ast_test_flag(peer, IAX_DYNAMIC)) 08246 peer->defaddr.sin_port = htons(atoi(v->value)); 08247 else 08248 peer->addr.sin_port = htons(atoi(v->value)); 08249 } else if (!strcasecmp(v->name, "username")) { 08250 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 08251 } else if (!strcasecmp(v->name, "allow")) { 08252 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08253 } else if (!strcasecmp(v->name, "disallow")) { 08254 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08255 } else if (!strcasecmp(v->name, "callerid")) { 08256 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), 08257 peer->cid_num, sizeof(peer->cid_num)); 08258 ast_set_flag(peer, IAX_HASCALLERID); 08259 } else if (!strcasecmp(v->name, "sendani")) { 08260 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08261 } else if (!strcasecmp(v->name, "inkeys")) { 08262 ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys)); 08263 } else if (!strcasecmp(v->name, "outkey")) { 08264 ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey)); 08265 } else if (!strcasecmp(v->name, "qualify")) { 08266 if (!strcasecmp(v->value, "no")) { 08267 peer->maxms = 0; 08268 } else if (!strcasecmp(v->value, "yes")) { 08269 peer->maxms = DEFAULT_MAXMS; 08270 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08271 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); 08272 peer->maxms = 0; 08273 } 08274 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08275 peer->smoothing = ast_true(v->value); 08276 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08277 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08278 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); 08279 } 08280 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08281 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08282 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); 08283 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08284 } else if (!strcasecmp(v->name, "timezone")) { 08285 ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag)); 08286 }/* else if (strcasecmp(v->name,"type")) */ 08287 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08288 v=v->next; 08289 } 08290 if (!peer->authmethods) 08291 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08292 ast_clear_flag(peer, IAX_DELME); 08293 /* Make sure these are IPv4 addresses */ 08294 peer->addr.sin_family = AF_INET; 08295 } 08296 if (oldha) 08297 ast_free_ha(oldha); 08298 return peer; 08299 }
|
|
Definition at line 8302 of file chan_iax2.c. References iax2_user::accountcode, iax2_user::amaflags, 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(), iax2_user::authmethods, build_context(), iax2_user::capability, iax2_user::cid_name, iax2_user::cid_num, iax2_user::contexts, iax2_user::dbsecret, iax2_user::encmethods, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, language, iax2_user::language, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, ast_variable::name, name, iax2_user::name, ast_variable::next, iax2_context::next, iax2_user::next, iax2_user::prefs, iax2_user::secret, timingfd, userl, ast_user_list::users, ast_variable::value, and iax2_user::vars. 08303 { 08304 struct iax2_user *prev, *user; 08305 struct iax2_context *con, *conl = NULL; 08306 struct ast_ha *oldha = NULL; 08307 struct iax2_context *oldcon = NULL; 08308 int format; 08309 char *varname = NULL, *varval = NULL; 08310 struct ast_variable *tmpvar = NULL; 08311 08312 prev = NULL; 08313 ast_mutex_lock(&userl.lock); 08314 if (!temponly) { 08315 user = userl.users; 08316 while(user) { 08317 if (!strcmp(user->name, name)) { 08318 break; 08319 } 08320 prev = user; 08321 user = user->next; 08322 } 08323 } else 08324 user = NULL; 08325 08326 if (user) { 08327 oldha = user->ha; 08328 oldcon = user->contexts; 08329 user->ha = NULL; 08330 user->contexts = NULL; 08331 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08332 if (prev) { 08333 prev->next = user->next; 08334 } else { 08335 userl.users = user->next; 08336 } 08337 ast_mutex_unlock(&userl.lock); 08338 } else { 08339 ast_mutex_unlock(&userl.lock); 08340 user = malloc(sizeof(struct iax2_user)); 08341 if (user) 08342 memset(user, 0, sizeof(struct iax2_user)); 08343 } 08344 08345 if (user) { 08346 memset(user, 0, sizeof(struct iax2_user)); 08347 user->prefs = prefs; 08348 user->capability = iax2_capability; 08349 user->encmethods = iax2_encryption; 08350 ast_copy_string(user->name, name, sizeof(user->name)); 08351 ast_copy_string(user->language, language, sizeof(user->language)); 08352 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08353 while(v) { 08354 if (!strcasecmp(v->name, "context")) { 08355 con = build_context(v->value); 08356 if (con) { 08357 if (conl) 08358 conl->next = con; 08359 else 08360 user->contexts = con; 08361 conl = con; 08362 } 08363 } else if (!strcasecmp(v->name, "permit") || 08364 !strcasecmp(v->name, "deny")) { 08365 user->ha = ast_append_ha(v->name, v->value, user->ha); 08366 } else if (!strcasecmp(v->name, "setvar")) { 08367 varname = ast_strdupa(v->value); 08368 if (varname && (varval = strchr(varname,'='))) { 08369 *varval = '\0'; 08370 varval++; 08371 if((tmpvar = ast_variable_new(varname, varval))) { 08372 tmpvar->next = user->vars; 08373 user->vars = tmpvar; 08374 } 08375 } 08376 } else if (!strcasecmp(v->name, "allow")) { 08377 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08378 } else if (!strcasecmp(v->name, "disallow")) { 08379 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08380 } else if (!strcasecmp(v->name, "trunk")) { 08381 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08382 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08383 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08384 ast_clear_flag(user, IAX_TRUNK); 08385 } 08386 } else if (!strcasecmp(v->name, "auth")) { 08387 user->authmethods = get_auth_methods(v->value); 08388 } else if (!strcasecmp(v->name, "encryption")) { 08389 user->encmethods = get_encrypt_methods(v->value); 08390 } else if (!strcasecmp(v->name, "notransfer")) { 08391 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08392 } else if (!strcasecmp(v->name, "codecpriority")) { 08393 if(!strcasecmp(v->value, "caller")) 08394 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08395 else if(!strcasecmp(v->value, "disabled")) 08396 ast_set_flag(user, IAX_CODEC_NOPREFS); 08397 else if(!strcasecmp(v->value, "reqonly")) { 08398 ast_set_flag(user, IAX_CODEC_NOCAP); 08399 ast_set_flag(user, IAX_CODEC_NOPREFS); 08400 } 08401 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08402 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08403 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08404 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08405 } else if (!strcasecmp(v->name, "dbsecret")) { 08406 ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret)); 08407 } else if (!strcasecmp(v->name, "secret")) { 08408 if (!ast_strlen_zero(user->secret)) { 08409 strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1); 08410 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); 08411 } else 08412 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 08413 } else if (!strcasecmp(v->name, "callerid")) { 08414 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 08415 ast_set_flag(user, IAX_HASCALLERID); 08416 } else if (!strcasecmp(v->name, "accountcode")) { 08417 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 08418 } else if (!strcasecmp(v->name, "language")) { 08419 ast_copy_string(user->language, v->value, sizeof(user->language)); 08420 } else if (!strcasecmp(v->name, "amaflags")) { 08421 format = ast_cdr_amaflags2int(v->value); 08422 if (format < 0) { 08423 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08424 } else { 08425 user->amaflags = format; 08426 } 08427 } else if (!strcasecmp(v->name, "inkeys")) { 08428 ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys)); 08429 }/* else if (strcasecmp(v->name,"type")) */ 08430 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08431 v = v->next; 08432 } 08433 if (!user->authmethods) { 08434 if (!ast_strlen_zero(user->secret)) { 08435 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08436 if (!ast_strlen_zero(user->inkeys)) 08437 user->authmethods |= IAX_AUTH_RSA; 08438 } else if (!ast_strlen_zero(user->inkeys)) { 08439 user->authmethods = IAX_AUTH_RSA; 08440 } else { 08441 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08442 } 08443 } 08444 ast_clear_flag(user, IAX_DELME); 08445 } 08446 if (oldha) 08447 ast_free_ha(oldha); 08448 if (oldcon) 08449 free_context(oldcon); 08450 return user; 08451 }
|
|
Definition at line 8863 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, chan_iax2_pvt::capability, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_DEBUG, LOG_WARNING, NEW_FORCE, chan_iax2_pvt::outkey, parse_dial_string(), chan_iax2_pvt::secret, and send_command(). Referenced by find_cache(). 08864 { 08865 struct sockaddr_in sin; 08866 int x; 08867 int callno; 08868 struct iax_ie_data ied; 08869 struct create_addr_info cai; 08870 struct parsed_dial_string pds; 08871 char *tmpstr; 08872 08873 for (x=0; x<IAX_MAX_CALLS; x++) { 08874 /* Look for an *exact match* call. Once a call is negotiated, it can only 08875 look up entries for a single context */ 08876 if (!ast_mutex_trylock(&iaxsl[x])) { 08877 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 08878 return x; 08879 ast_mutex_unlock(&iaxsl[x]); 08880 } 08881 } 08882 08883 /* No match found, we need to create a new one */ 08884 08885 memset(&cai, 0, sizeof(cai)); 08886 memset(&ied, 0, sizeof(ied)); 08887 memset(&pds, 0, sizeof(pds)); 08888 08889 tmpstr = ast_strdupa(data); 08890 parse_dial_string(tmpstr, &pds); 08891 08892 /* Populate our address from the given */ 08893 if (create_addr(pds.peer, &sin, &cai)) 08894 return -1; 08895 08896 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 08897 pds.peer, pds.username, pds.password, pds.context); 08898 08899 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 08900 if (callno < 1) { 08901 ast_log(LOG_WARNING, "Unable to create call\n"); 08902 return -1; 08903 } 08904 08905 ast_mutex_lock(&iaxsl[callno]); 08906 ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot)); 08907 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 08908 08909 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 08910 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 08911 /* the string format is slightly different from a standard dial string, 08912 because the context appears in the 'exten' position 08913 */ 08914 if (pds.exten) 08915 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 08916 if (pds.username) 08917 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 08918 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 08919 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 08920 /* Keep password handy */ 08921 if (pds.password) 08922 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 08923 if (pds.key) 08924 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 08925 /* Start the call going */ 08926 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 08927 08928 return callno; 08929 }
|
|
Definition at line 3643 of file chan_iax2.c. References ast_log(), ast_tvsub(), chan_iax2_pvt::callno, LOG_DEBUG, option_debug, and chan_iax2_pvt::rxcore. Referenced by ast_rtp_read(), and schedule_delivery(). 03644 { 03645 /* Returns where in "receive time" we are. That is, how many ms 03646 since we received (or would have received) the frame with timestamp 0 */ 03647 int ms; 03648 #ifdef IAXTESTS 03649 int jit; 03650 #endif /* IAXTESTS */ 03651 /* Setup rxcore if necessary */ 03652 if (ast_tvzero(p->rxcore)) { 03653 p->rxcore = ast_tvnow(); 03654 if (option_debug && iaxdebug) 03655 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03656 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03657 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03658 #if 1 03659 if (option_debug && iaxdebug) 03660 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03661 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03662 #endif 03663 } 03664 03665 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03666 #ifdef IAXTESTS 03667 if (test_jit) { 03668 if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) { 03669 jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0)); 03670 if ((int)(2.0 * rand() / (RAND_MAX + 1.0))) 03671 jit = -jit; 03672 ms += jit; 03673 } 03674 } 03675 if (test_late) { 03676 ms += test_late; 03677 test_late = 0; 03678 } 03679 #endif /* IAXTESTS */ 03680 return ms; 03681 }
|
|
Definition at line 3496 of file chan_iax2.c. References ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, iaxdebug, iaxs, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples. Referenced by iax2_send(), and socket_read(). 03497 { 03498 int ms; 03499 int voice = 0; 03500 int genuine = 0; 03501 int adjust; 03502 struct timeval *delivery = NULL; 03503 03504 03505 /* What sort of frame do we have?: voice is self-explanatory 03506 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03507 non-genuine frames are CONTROL frames [ringing etc], DTMF 03508 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03509 the others need a timestamp slaved to the voice frames so that they go in sequence 03510 */ 03511 if (f) { 03512 if (f->frametype == AST_FRAME_VOICE) { 03513 voice = 1; 03514 delivery = &f->delivery; 03515 } else if (f->frametype == AST_FRAME_IAX) { 03516 genuine = 1; 03517 } else if (f->frametype == AST_FRAME_CNG) { 03518 p->notsilenttx = 0; 03519 } 03520 } 03521 if (ast_tvzero(p->offset)) { 03522 gettimeofday(&p->offset, NULL); 03523 /* Round to nearest 20ms for nice looking traces */ 03524 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03525 } 03526 /* If the timestamp is specified, just send it as is */ 03527 if (ts) 03528 return ts; 03529 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03530 if (delivery && !ast_tvzero(*delivery)) { 03531 ms = ast_tvdiff_ms(*delivery, p->offset); 03532 if (option_debug > 2 && iaxdebug) 03533 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03534 } else { 03535 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03536 if (ms < 0) 03537 ms = 0; 03538 if (voice) { 03539 /* On a voice frame, use predicted values if appropriate */ 03540 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03541 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03542 /* AN EXPLANATION: 03543 When we send voice, we usually send "calculated" timestamps worked out 03544 on the basis of the number of samples sent. When we send other frames, 03545 we usually send timestamps worked out from the real clock. 03546 The problem is that they can tend to drift out of step because the 03547 source channel's clock and our clock may not be exactly at the same rate. 03548 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03549 for this call. Moving it adjusts timestamps for non-voice frames. 03550 We make the adjustment in the style of a moving average. Each time we 03551 adjust p->offset by 10% of the difference between our clock-derived 03552 timestamp and the predicted timestamp. That's why you see "10000" 03553 below even though IAX2 timestamps are in milliseconds. 03554 The use of a moving average avoids offset moving too radically. 03555 Generally, "adjust" roams back and forth around 0, with offset hardly 03556 changing at all. But if a consistent different starts to develop it 03557 will be eliminated over the course of 10 frames (200-300msecs) 03558 */ 03559 adjust = (ms - p->nextpred); 03560 if (adjust < 0) 03561 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03562 else if (adjust > 0) 03563 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03564 03565 if (!p->nextpred) { 03566 p->nextpred = ms; /*f->samples / 8;*/ 03567 if (p->nextpred <= p->lastsent) 03568 p->nextpred = p->lastsent + 3; 03569 } 03570 ms = p->nextpred; 03571 } else { 03572 /* in this case, just use the actual 03573 * time, since we're either way off 03574 * (shouldn't happen), or we're ending a 03575 * silent period -- and seed the next 03576 * predicted time. Also, round ms to the 03577 * next multiple of frame size (so our 03578 * silent periods are multiples of 03579 * frame size too) */ 03580 03581 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03582 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03583 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03584 03585 if (f->samples >= 8) /* check to make sure we dont core dump */ 03586 { 03587 int diff = ms % (f->samples / 8); 03588 if (diff) 03589 ms += f->samples/8 - diff; 03590 } 03591 03592 p->nextpred = ms; 03593 p->notsilenttx = 1; 03594 } 03595 } else { 03596 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03597 it's a genuine frame */ 03598 if (genuine) { 03599 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03600 if (ms <= p->lastsent) 03601 ms = p->lastsent + 3; 03602 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03603 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03604 ms = p->lastsent + 3; 03605 } 03606 } 03607 } 03608 p->lastsent = ms; 03609 if (voice) 03610 p->nextpred = p->nextpred + f->samples / 8; 03611 #if 0 03612 printf("TS: %s - %dms\n", voice ? "Audio" : "Control", ms); 03613 #endif 03614 return ms; 03615 }
|
|
Definition at line 3452 of file chan_iax2.c. References iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, iax2_trunk_peer::trunkact, tv, and iax2_trunk_peer::txtrunktime. Referenced by send_trunk(). 03453 { 03454 unsigned long int mssincetx; /* unsigned to handle overflows */ 03455 long int ms, pred; 03456 03457 tpeer->trunkact = *tv; 03458 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03459 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03460 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03461 tpeer->txtrunktime = *tv; 03462 tpeer->lastsent = 999999; 03463 } 03464 /* Update last transmit time now */ 03465 tpeer->lasttxtime = *tv; 03466 03467 /* Calculate ms offset */ 03468 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03469 /* Predict from last value */ 03470 pred = tpeer->lastsent + sampms; 03471 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03472 ms = pred; 03473 03474 /* We never send the same timestamp twice, so fudge a little if we must */ 03475 if (ms == tpeer->lastsent) 03476 ms = tpeer->lastsent + 1; 03477 tpeer->lastsent = ms; 03478 return ms; 03479 }
|
|
Definition at line 4709 of file chan_iax2.c. References chan_iax2_pvt::accountcode, accountcode, iax2_user::accountcode, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, chan_iax2_pvt::ani, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set2_flag, ast_shrink_phone_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, chan_iax2_pvt::cid_name, iax2_user::cid_num, chan_iax2_pvt::cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, destroy_user(), chan_iax2_pvt::dnid, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, chan_iax2_pvt::exten, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::inkeys, iax2_user::inkeys, key(), iax2_user::language, chan_iax2_pvt::language, language, iax_ies::language, ast_user_list::lock, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), chan_iax2_pvt::secret, iax2_user::secret, userl, chan_iax2_pvt::username, iax_ies::username, ast_user_list::users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version. Referenced by socket_read(). 04710 { 04711 /* Start pessimistic */ 04712 int res = -1; 04713 int version = 2; 04714 struct iax2_user *user, *best = NULL; 04715 int bestscore = 0; 04716 int gotcapability=0; 04717 char iabuf[INET_ADDRSTRLEN]; 04718 struct ast_variable *v = NULL, *tmpvar = NULL; 04719 04720 if (!iaxs[callno]) 04721 return res; 04722 if (ies->called_number) 04723 ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten)); 04724 if (ies->calling_number) { 04725 ast_shrink_phone_number(ies->calling_number); 04726 ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num)); 04727 } 04728 if (ies->calling_name) 04729 ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name)); 04730 if (ies->calling_ani) 04731 ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani)); 04732 if (ies->dnid) 04733 ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid)); 04734 if (ies->called_context) 04735 ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context)); 04736 if (ies->language) 04737 ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language)); 04738 if (ies->username) 04739 ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username)); 04740 if (ies->calling_ton > -1) 04741 iaxs[callno]->calling_ton = ies->calling_ton; 04742 if (ies->calling_tns > -1) 04743 iaxs[callno]->calling_tns = ies->calling_tns; 04744 if (ies->calling_pres > -1) 04745 iaxs[callno]->calling_pres = ies->calling_pres; 04746 if (ies->format) 04747 iaxs[callno]->peerformat = ies->format; 04748 if (ies->adsicpe) 04749 iaxs[callno]->peeradsicpe = ies->adsicpe; 04750 if (ies->capability) { 04751 gotcapability = 1; 04752 iaxs[callno]->peercapability = ies->capability; 04753 } 04754 if (ies->version) 04755 version = ies->version; 04756 04757 if(ies->codec_prefs) 04758 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04759 04760 if (!gotcapability) 04761 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04762 if (version > IAX_PROTO_VERSION) { 04763 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04764 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version); 04765 return res; 04766 } 04767 ast_mutex_lock(&userl.lock); 04768 /* Search the userlist for a compatible entry, and fill in the rest */ 04769 user = userl.users; 04770 while(user) { 04771 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04772 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04773 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04774 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04775 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04776 if (!ast_strlen_zero(iaxs[callno]->username)) { 04777 /* Exact match, stop right now. */ 04778 best = user; 04779 break; 04780 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04781 /* No required authentication */ 04782 if (user->ha) { 04783 /* There was host authentication and we passed, bonus! */ 04784 if (bestscore < 4) { 04785 bestscore = 4; 04786 best = user; 04787 } 04788 } else { 04789 /* No host access, but no secret, either, not bad */ 04790 if (bestscore < 3) { 04791 bestscore = 3; 04792 best = user; 04793 } 04794 } 04795 } else { 04796 if (user->ha) { 04797 /* Authentication, but host access too, eh, it's something.. */ 04798 if (bestscore < 2) { 04799 bestscore = 2; 04800 best = user; 04801 } 04802 } else { 04803 /* Authentication and no host access... This is our baseline */ 04804 if (bestscore < 1) { 04805 bestscore = 1; 04806 best = user; 04807 } 04808 } 04809 } 04810 } 04811 user = user->next; 04812 } 04813 ast_mutex_unlock(&userl.lock); 04814 user = best; 04815 if (!user && !ast_strlen_zero(iaxs[callno]->username) && (strlen(iaxs[callno]->username) < 128)) { 04816 user = realtime_user(iaxs[callno]->username); 04817 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04818 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04819 destroy_user(user); 04820 user = NULL; 04821 } 04822 } 04823 if (user) { 04824 /* We found our match (use the first) */ 04825 /* copy vars */ 04826 for (v = user->vars ; v ; v = v->next) { 04827 if((tmpvar = ast_variable_new(v->name, v->value))) { 04828 tmpvar->next = iaxs[callno]->vars; 04829 iaxs[callno]->vars = tmpvar; 04830 } 04831 } 04832 iaxs[callno]->prefs = user->prefs; 04833 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04834 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04835 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04836 iaxs[callno]->encmethods = user->encmethods; 04837 /* Store the requested username if not specified */ 04838 if (ast_strlen_zero(iaxs[callno]->username)) 04839 ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username)); 04840 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04841 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04842 iaxs[callno]->capability = user->capability; 04843 /* And use the default context */ 04844 if (ast_strlen_zero(iaxs[callno]->context)) { 04845 if (user->contexts) 04846 ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context)); 04847 else 04848 ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context)); 04849 } 04850 /* And any input keys */ 04851 ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys)); 04852 /* And the permitted authentication methods */ 04853 iaxs[callno]->authmethods = user->authmethods; 04854 /* If they have callerid, override the given caller id. Always store the ANI */ 04855 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 04856 if (ast_test_flag(user, IAX_HASCALLERID)) { 04857 iaxs[callno]->calling_tns = 0; 04858 iaxs[callno]->calling_ton = 0; 04859 ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num)); 04860 ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name)); 04861 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 04862 } 04863 ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani)); 04864 } else { 04865 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 04866 } 04867 if (!ast_strlen_zero(user->accountcode)) 04868 ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode)); 04869 if (user->amaflags) 04870 iaxs[callno]->amaflags = user->amaflags; 04871 if (!ast_strlen_zero(user->language)) 04872 ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language)); 04873 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04874 /* Keep this check last */ 04875 if (!ast_strlen_zero(user->dbsecret)) { 04876 char *family, *key=NULL; 04877 family = ast_strdupa(user->dbsecret); 04878 if (family) { 04879 key = strchr(family, '/'); 04880 if (key) { 04881 *key = '\0'; 04882 key++; 04883 } 04884 } 04885 if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret))) { 04886 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 04887 if (ast_test_flag(user, IAX_TEMPONLY)) { 04888 destroy_user(user); 04889 user = NULL; 04890 } 04891 } 04892 } else 04893 ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)); 04894 res = 0; 04895 } 04896 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 04897 return res; 04898 }
|
|
Definition at line 6209 of file chan_iax2.c. References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and si. Referenced by socket_read(). 06210 { 06211 unsigned int ourver; 06212 char rsi[80]; 06213 snprintf(rsi, sizeof(rsi), "si-%s", si); 06214 if (iax_provision_version(&ourver, rsi, 1)) 06215 return 0; 06216 if (option_debug) 06217 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06218 if (ourver != ver) 06219 iax2_provision(sin, sockfd, NULL, rsi, 1); 06220 return 0; 06221 }
|
|
Definition at line 8027 of file chan_iax2.c. References ast_log(), LOG_DEBUG, and LOG_ERROR. Referenced by peer_set_srcaddr(). 08028 { 08029 int sd; 08030 int res; 08031 08032 sd = socket(AF_INET, SOCK_DGRAM, 0); 08033 if (sd < 0) { 08034 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08035 return -1; 08036 } 08037 08038 res = bind(sd, sa, salen); 08039 if (res < 0) { 08040 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08041 close(sd); 08042 return 1; 08043 } 08044 08045 close(sd); 08046 return 0; 08047 }
|
|
Definition at line 5315 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters. Referenced by socket_read(). 05316 { 05317 char exten[256] = ""; 05318 int status = CACHE_FLAG_UNKNOWN; 05319 int expiry = iaxdefaultdpcache; 05320 int x; 05321 int matchmore = 0; 05322 struct iax2_dpcache *dp, *prev; 05323 05324 if (ies->called_number) 05325 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05326 05327 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05328 status = CACHE_FLAG_EXISTS; 05329 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05330 status = CACHE_FLAG_CANEXIST; 05331 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05332 status = CACHE_FLAG_NONEXISTENT; 05333 05334 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05335 /* Don't really do anything with this */ 05336 } 05337 if (ies->refresh) 05338 expiry = ies->refresh; 05339 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05340 matchmore = CACHE_FLAG_MATCHMORE; 05341 ast_mutex_lock(&dpcache_lock); 05342 prev = NULL; 05343 dp = pvt->dpentries; 05344 while(dp) { 05345 if (!strcmp(dp->exten, exten)) { 05346 /* Let them go */ 05347 if (prev) 05348 prev->peer = dp->peer; 05349 else 05350 pvt->dpentries = dp->peer; 05351 dp->peer = NULL; 05352 dp->callno = 0; 05353 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05354 if (dp->flags & CACHE_FLAG_PENDING) { 05355 dp->flags &= ~CACHE_FLAG_PENDING; 05356 dp->flags |= status; 05357 dp->flags |= matchmore; 05358 } 05359 /* Wake up waiters */ 05360 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05361 if (dp->waiters[x] > -1) 05362 write(dp->waiters[x], "asdf", 4); 05363 } 05364 prev = dp; 05365 dp = dp->peer; 05366 } 05367 ast_mutex_unlock(&dpcache_lock); 05368 return 0; 05369 }
|
|
Definition at line 1973 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. 01974 { 01975 int which = 0; 01976 struct iax2_peer *p; 01977 char *res = NULL; 01978 01979 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 01980 if(pos == 3) { 01981 ast_mutex_lock(&peerl.lock); 01982 for(p = peerl.peers ; p ; p = p->next) { 01983 if(!strncasecmp(p->name, word, strlen(word))) { 01984 if(++which > state) { 01985 res = strdup(p->name); 01986 break; 01987 } 01988 } 01989 } 01990 ast_mutex_unlock(&peerl.lock); 01991 } 01992 01993 return res; 01994 }
|
|
Definition at line 5371 of file chan_iax2.c. References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, iax_ies::callno, jb_frame::data, ast_iax2_queue::head, iax2_frame_free(), iaxq, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), 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, chan_iax2_pvt::transfercallno, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat. Referenced by socket_read(). 05372 { 05373 int peercallno = 0; 05374 struct chan_iax2_pvt *pvt = iaxs[callno]; 05375 struct iax_frame *cur; 05376 05377 if (ies->callno) 05378 peercallno = ies->callno; 05379 05380 if (peercallno < 1) { 05381 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05382 return -1; 05383 } 05384 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05385 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05386 /* Reset sequence numbers */ 05387 pvt->oseqno = 0; 05388 pvt->rseqno = 0; 05389 pvt->iseqno = 0; 05390 pvt->aseqno = 0; 05391 pvt->peercallno = peercallno; 05392 pvt->transferring = TRANSFER_NONE; 05393 pvt->svoiceformat = -1; 05394 pvt->voiceformat = 0; 05395 pvt->svideoformat = -1; 05396 pvt->videoformat = 0; 05397 pvt->transfercallno = -1; 05398 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05399 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05400 #ifdef NEWJB 05401 { /* reset jitterbuffer */ 05402 jb_frame frame; 05403 while(jb_getall(pvt->jb,&frame) == JB_OK) 05404 iax2_frame_free(frame.data); 05405 05406 jb_reset(pvt->jb); 05407 } 05408 #else 05409 memset(&pvt->history, 0, sizeof(pvt->history)); 05410 pvt->jitterbuffer = 0; 05411 pvt->jitter = 0; 05412 pvt->historicjitter = 0; 05413 #endif 05414 pvt->lag = 0; 05415 pvt->last = 0; 05416 pvt->lastsent = 0; 05417 pvt->nextpred = 0; 05418 pvt->pingtime = DEFAULT_RETRY_TIME; 05419 ast_mutex_lock(&iaxq.lock); 05420 for (cur = iaxq.head; cur ; cur = cur->next) { 05421 /* We must cancel any packets that would have been transmitted 05422 because now we're talking to someone new. It's okay, they 05423 were transmitted to someone that didn't care anyway. */ 05424 if (callno == cur->callno) 05425 cur->retries = -1; 05426 } 05427 ast_mutex_unlock(&iaxq.lock); 05428 return 0; 05429 }
|
|
Definition at line 809 of file chan_iax2.c. References ast_log(), and LOG_WARNING. Referenced by iax2_send(), and raw_hangup(). 00810 { 00811 int x; 00812 int power=-1; 00813 /* If it's 128 or smaller, just return it */ 00814 if (subclass < IAX_FLAG_SC_LOG) 00815 return subclass; 00816 /* Otherwise find its power */ 00817 for (x = 0; x < IAX_MAX_SHIFT; x++) { 00818 if (subclass & (1 << x)) { 00819 if (power > -1) { 00820 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 00821 return 0; 00822 } else 00823 power = x; 00824 } 00825 } 00826 return power | IAX_FLAG_SC_LOG; 00827 }
|
|
Definition at line 6223 of file chan_iax2.c. References ast_test_flag, jb_info::current, chan_iax2_pvt::frames_dropped, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, IAX_USEJITTERBUF, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, chan_iax2_pvt::min, and jb_info::min. Referenced by socket_read(). 06224 { 06225 #ifdef NEWJB 06226 jb_info stats; 06227 jb_getinfo(pvt->jb, &stats); 06228 06229 memset(iep, 0, sizeof(*iep)); 06230 06231 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06232 if(stats.frames_in == 0) stats.frames_in = 1; 06233 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06234 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06235 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06236 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06237 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06238 #else 06239 memset(iep, 0, sizeof(*iep)); 06240 iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter); 06241 iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received); 06242 if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 06243 iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0); 06244 else 06245 iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min); 06246 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped); 06247 /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */ 06248 /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */ 06249 #endif 06250 }
|
|
Definition at line 2739 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, 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. 02740 { 02741 struct ast_hostent ahp; 02742 struct hostent *hp; 02743 struct iax2_peer *peer; 02744 02745 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02746 cai->sockfd = defaultsockfd; 02747 cai->maxtime = 0; 02748 sin->sin_family = AF_INET; 02749 02750 if (!(peer = find_peer(peername, 1))) { 02751 cai->found = 0; 02752 02753 hp = ast_gethostbyname(peername, &ahp); 02754 if (hp) { 02755 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02756 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02757 /* use global iax prefs for unknown peer/user */ 02758 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02759 return 0; 02760 } else { 02761 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02762 return -1; 02763 } 02764 } 02765 02766 cai->found = 1; 02767 02768 /* if the peer has no address (current or default), return failure */ 02769 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 02770 if (ast_test_flag(peer, IAX_TEMPONLY)) 02771 destroy_peer(peer); 02772 return -1; 02773 } 02774 02775 /* if the peer is being monitored and is currently unreachable, return failure */ 02776 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) { 02777 if (ast_test_flag(peer, IAX_TEMPONLY)) 02778 destroy_peer(peer); 02779 return -1; 02780 } 02781 02782 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02783 cai->maxtime = peer->maxms; 02784 cai->capability = peer->capability; 02785 cai->encmethods = peer->encmethods; 02786 cai->sockfd = peer->sockfd; 02787 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02788 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02789 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02790 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02791 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02792 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02793 if (ast_strlen_zero(peer->dbsecret)) { 02794 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02795 } else { 02796 char *family; 02797 char *key = NULL; 02798 02799 family = ast_strdupa(peer->dbsecret); 02800 if (family) { 02801 key = strchr(family, '/'); 02802 if (key) 02803 *key++ = '\0'; 02804 } 02805 if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02806 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02807 if (ast_test_flag(peer, IAX_TEMPONLY)) 02808 destroy_peer(peer); 02809 return -1; 02810 } 02811 } 02812 02813 if (peer->addr.sin_addr.s_addr) { 02814 sin->sin_addr = peer->addr.sin_addr; 02815 sin->sin_port = peer->addr.sin_port; 02816 } else { 02817 sin->sin_addr = peer->defaddr.sin_addr; 02818 sin->sin_port = peer->defaddr.sin_port; 02819 } 02820 02821 if (ast_test_flag(peer, IAX_TEMPONLY)) 02822 destroy_peer(peer); 02823 02824 return 0; 02825 }
|
|
Definition at line 3834 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, ast_frame::frametype, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass(). Referenced by decrypt_frame(). 03835 { 03836 int padding; 03837 unsigned char *workspace; 03838 workspace = alloca(*datalen); 03839 if (!workspace) 03840 return -1; 03841 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03842 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03843 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03844 return -1; 03845 /* Decrypt */ 03846 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03847 03848 padding = 16 + (workspace[15] & 0xf); 03849 if (option_debug && iaxdebug) 03850 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03851 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03852 return -1; 03853 03854 *datalen -= padding; 03855 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03856 f->frametype = fh->type; 03857 if (f->frametype == AST_FRAME_VIDEO) { 03858 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03859 } else { 03860 f->subclass = uncompress_subclass(fh->csub); 03861 } 03862 } else { 03863 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03864 if (option_debug && iaxdebug) 03865 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03866 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03867 return -1; 03868 /* Decrypt */ 03869 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03870 padding = 16 + (workspace[15] & 0x0f); 03871 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03872 return -1; 03873 *datalen -= padding; 03874 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03875 } 03876 return 0; 03877 }
|
|
Definition at line 3920 of file chan_iax2.c. References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), and strsep(). Referenced by socket_read(). 03921 { 03922 int res=-1; 03923 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 03924 /* Search for possible keys, given secrets */ 03925 struct MD5Context md5; 03926 unsigned char digest[16]; 03927 char *tmppw, *stringp; 03928 03929 tmppw = ast_strdupa(iaxs[callno]->secret); 03930 stringp = tmppw; 03931 while((tmppw = strsep(&stringp, ";"))) { 03932 MD5Init(&md5); 03933 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 03934 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 03935 MD5Final(digest, &md5); 03936 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 03937 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03938 if (!res) { 03939 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 03940 break; 03941 } 03942 } 03943 } else 03944 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03945 return res; 03946 }
|
|
Definition at line 8453 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_registry::callno, iax2_registry::expire, free, iax2_destroy_nolock(), IAX_DELME, iaxs, iaxsl, ast_peer_list::lock, ast_user_list::lock, iax2_peer::next, iax2_registry::next, iax2_user::next, peerl, ast_peer_list::peers, chan_iax2_pvt::reg, registrations, sched, userl, and ast_user_list::users. 08454 { 08455 struct iax2_user *user; 08456 struct iax2_peer *peer; 08457 struct iax2_registry *reg, *regl; 08458 08459 ast_mutex_lock(&userl.lock); 08460 for (user=userl.users;user;) { 08461 ast_set_flag(user, IAX_DELME); 08462 user = user->next; 08463 } 08464 ast_mutex_unlock(&userl.lock); 08465 for (reg = registrations;reg;) { 08466 regl = reg; 08467 reg = reg->next; 08468 if (regl->expire > -1) { 08469 ast_sched_del(sched, regl->expire); 08470 } 08471 if (regl->callno) { 08472 /* XXX Is this a potential lock? I don't think so, but you never know */ 08473 ast_mutex_lock(&iaxsl[regl->callno]); 08474 if (iaxs[regl->callno]) { 08475 iaxs[regl->callno]->reg = NULL; 08476 iax2_destroy_nolock(regl->callno); 08477 } 08478 ast_mutex_unlock(&iaxsl[regl->callno]); 08479 } 08480 free(regl); 08481 } 08482 registrations = NULL; 08483 ast_mutex_lock(&peerl.lock); 08484 for (peer=peerl.peers;peer;) { 08485 /* Assume all will be deleted, and we'll find out for sure later */ 08486 ast_set_flag(peer, IAX_DELME); 08487 peer = peer->next; 08488 } 08489 ast_mutex_unlock(&peerl.lock); 08490 }
|
|
Provides a description of the module.
Definition at line 9646 of file chan_iax2.c. 09647 { 09648 return (char *) desc; 09649 }
|
|
Definition at line 1141 of file chan_iax2.c. References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh. Referenced by reload_firmware(). 01142 { 01143 /* Close firmware */ 01144 if (cur->fwh) { 01145 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01146 } 01147 close(cur->fd); 01148 free(cur); 01149 }
|
|
Definition at line 8522 of file chan_iax2.c. References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::expire, free, iax2_peer::ha, iax2_destroy(), iaxs, iaxsl, chan_iax2_pvt::peerpoke, iax2_peer::pokeexpire, register_peer_exten(), and sched. 08523 { 08524 int x; 08525 ast_free_ha(peer->ha); 08526 for (x=0;x<IAX_MAX_CALLS;x++) { 08527 ast_mutex_lock(&iaxsl[x]); 08528 if (iaxs[x] && (iaxs[x]->peerpoke == peer)) { 08529 iax2_destroy(x); 08530 } 08531 ast_mutex_unlock(&iaxsl[x]); 08532 } 08533 /* Delete it, it needs to disappear */ 08534 if (peer->expire > -1) 08535 ast_sched_del(sched, peer->expire); 08536 if (peer->pokeexpire > -1) 08537 ast_sched_del(sched, peer->pokeexpire); 08538 if (peer->callno > 0) 08539 iax2_destroy(peer->callno); 08540 register_peer_exten(peer, 0); 08541 if (peer->dnsmgr) 08542 ast_dnsmgr_release(peer->dnsmgr); 08543 free(peer); 08544 }
|
|
Definition at line 8492 of file chan_iax2.c. References ast_free_ha(), ast_variables_destroy(), iax2_user::contexts, free, free_context(), iax2_user::ha, and iax2_user::vars. Referenced by check_access(), and prune_users(). 08493 { 08494 ast_free_ha(user->ha); 08495 free_context(user->contexts); 08496 if(user->vars) { 08497 ast_variables_destroy(user->vars); 08498 user->vars = NULL; 08499 } 08500 free(user); 08501 }
|
|
Definition at line 6066 of file chan_iax2.c. References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), context, IAX_COMMAND_DPREP, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxdefaultdpcache, iaxs, iaxsl, and send_command(). Referenced by dp_lookup_thread(), and socket_read(). 06067 { 06068 unsigned short dpstatus = 0; 06069 struct iax_ie_data ied1; 06070 int mm; 06071 06072 memset(&ied1, 0, sizeof(ied1)); 06073 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06074 /* Must be started */ 06075 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06076 dpstatus = IAX_DPSTATUS_EXISTS; 06077 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06078 dpstatus = IAX_DPSTATUS_CANEXIST; 06079 } else { 06080 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06081 } 06082 if (ast_ignore_pattern(context, callednum)) 06083 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06084 if (mm) 06085 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06086 if (!skiplock) 06087 ast_mutex_lock(&iaxsl[callno]); 06088 if (iaxs[callno]) { 06089 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06090 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06091 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06092 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06093 } 06094 if (!skiplock) 06095 ast_mutex_unlock(&iaxsl[callno]); 06096 }
|
|
Definition at line 6098 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(). 06099 { 06100 /* Look up for dpreq */ 06101 struct dpreq_data *dpr = data; 06102 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06103 if (dpr->callerid) 06104 free(dpr->callerid); 06105 free(dpr); 06106 return NULL; 06107 }
|
|
Definition at line 3879 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, LOG_DEBUG, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type. Referenced by iax2_send(). 03880 { 03881 int padding; 03882 unsigned char *workspace; 03883 workspace = alloca(*datalen + 32); 03884 if (!workspace) 03885 return -1; 03886 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03887 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03888 if (option_debug && iaxdebug) 03889 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03890 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03891 padding = 16 + (padding & 0xf); 03892 memcpy(workspace, poo, padding); 03893 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03894 workspace[15] &= 0xf0; 03895 workspace[15] |= (padding & 0xf); 03896 if (option_debug && iaxdebug) 03897 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]); 03898 *datalen += padding; 03899 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03900 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03901 memcpy(poo, workspace + *datalen - 32, 32); 03902 } else { 03903 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03904 if (option_debug && iaxdebug) 03905 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03906 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03907 padding = 16 + (padding & 0xf); 03908 memcpy(workspace, poo, padding); 03909 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03910 workspace[15] &= 0xf0; 03911 workspace[15] |= (padding & 0x0f); 03912 *datalen += padding; 03913 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 03914 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 03915 memcpy(poo, workspace + *datalen - 32, 32); 03916 } 03917 return 0; 03918 }
|
|
Definition at line 5566 of file chan_iax2.c. References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_test_flag, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_TEMPONLY, LOG_DEBUG, iax2_peer::name, prune_peers(), and register_peer_exten(). Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry(). 05567 { 05568 struct iax2_peer *p = data; 05569 05570 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name); 05571 /* Reset the address */ 05572 memset(&p->addr, 0, sizeof(p->addr)); 05573 /* Reset expire notice */ 05574 p->expire = -1; 05575 /* Reset expiry value */ 05576 p->expiry = min_reg_expire; 05577 if (!ast_test_flag(p, IAX_TEMPONLY)) 05578 ast_db_del("IAX/Registry", p->name); 05579 register_peer_exten(p, 0); 05580 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05581 if (iax2_regfunk) 05582 iax2_regfunk(p->name, 0); 05583 05584 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) { 05585 ast_set_flag(p, IAX_DELME); 05586 prune_peers(); 05587 } 05588 05589 return 0; 05590 }
|
|
Definition at line 8931 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_get_callno_locked(), iax2_dpcache::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxdefaulttimeout, iaxs, iaxsl, LOG_WARNING, malloc, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, tv, and iax2_dpcache::waiters. Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore(). 08932 { 08933 struct iax2_dpcache *dp, *prev = NULL, *next; 08934 struct timeval tv; 08935 int x; 08936 int com[2]; 08937 int timeout; 08938 int old=0; 08939 int outfd; 08940 int abort; 08941 int callno; 08942 struct ast_channel *c; 08943 struct ast_frame *f; 08944 gettimeofday(&tv, NULL); 08945 dp = dpcache; 08946 while(dp) { 08947 next = dp->next; 08948 /* Expire old caches */ 08949 if (ast_tvcmp(tv, dp->expiry) > 0) { 08950 /* It's expired, let it disappear */ 08951 if (prev) 08952 prev->next = dp->next; 08953 else 08954 dpcache = dp->next; 08955 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 08956 /* Free memory and go again */ 08957 free(dp); 08958 } else { 08959 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); 08960 } 08961 dp = next; 08962 continue; 08963 } 08964 /* We found an entry that matches us! */ 08965 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 08966 break; 08967 prev = dp; 08968 dp = next; 08969 } 08970 if (!dp) { 08971 /* No matching entry. Create a new one. */ 08972 /* First, can we make a callno? */ 08973 callno = cache_get_callno_locked(data); 08974 if (callno < 0) { 08975 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 08976 return NULL; 08977 } 08978 dp = malloc(sizeof(struct iax2_dpcache)); 08979 if (!dp) { 08980 ast_mutex_unlock(&iaxsl[callno]); 08981 return NULL; 08982 } 08983 memset(dp, 0, sizeof(struct iax2_dpcache)); 08984 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 08985 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 08986 gettimeofday(&dp->expiry, NULL); 08987 dp->orig = dp->expiry; 08988 /* Expires in 30 mins by default */ 08989 dp->expiry.tv_sec += iaxdefaultdpcache; 08990 dp->next = dpcache; 08991 dp->flags = CACHE_FLAG_PENDING; 08992 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 08993 dp->waiters[x] = -1; 08994 dpcache = dp; 08995 dp->peer = iaxs[callno]->dpentries; 08996 iaxs[callno]->dpentries = dp; 08997 /* Send the request if we're already up */ 08998 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 08999 iax2_dprequest(dp, callno); 09000 ast_mutex_unlock(&iaxsl[callno]); 09001 } 09002 /* By here we must have a dp */ 09003 if (dp->flags & CACHE_FLAG_PENDING) { 09004 /* Okay, here it starts to get nasty. We need a pipe now to wait 09005 for a reply to come back so long as it's pending */ 09006 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09007 /* Find an empty slot */ 09008 if (dp->waiters[x] < 0) 09009 break; 09010 } 09011 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09012 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09013 return NULL; 09014 } 09015 if (pipe(com)) { 09016 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09017 return NULL; 09018 } 09019 dp->waiters[x] = com[1]; 09020 /* Okay, now we wait */ 09021 timeout = iaxdefaulttimeout * 1000; 09022 /* Temporarily unlock */ 09023 ast_mutex_unlock(&dpcache_lock); 09024 /* Defer any dtmf */ 09025 if (chan) 09026 old = ast_channel_defer_dtmf(chan); 09027 abort = 0; 09028 while(timeout) { 09029 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09030 if (outfd > -1) { 09031 break; 09032 } 09033 if (c) { 09034 f = ast_read(c); 09035 if (f) 09036 ast_frfree(f); 09037 else { 09038 /* Got hung up on, abort! */ 09039 break; 09040 abort = 1; 09041 } 09042 } 09043 } 09044 if (!timeout) { 09045 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09046 } 09047 ast_mutex_lock(&dpcache_lock); 09048 dp->waiters[x] = -1; 09049 close(com[1]); 09050 close(com[0]); 09051 if (abort) { 09052 /* Don't interpret anything, just abort. Not sure what th epoint 09053 of undeferring dtmf on a hung up channel is but hey whatever */ 09054 if (!old && chan) 09055 ast_channel_undefer_dtmf(chan); 09056 return NULL; 09057 } 09058 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09059 /* Now to do non-independent analysis the results of our wait */ 09060 if (dp->flags & CACHE_FLAG_PENDING) { 09061 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09062 pending. Don't let it take as long to timeout. */ 09063 dp->flags &= ~CACHE_FLAG_PENDING; 09064 dp->flags |= CACHE_FLAG_TIMEOUT; 09065 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09066 systems without leaving it unavailable once the server comes back online */ 09067 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09068 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09069 if (dp->waiters[x] > -1) 09070 write(dp->waiters[x], "asdf", 4); 09071 } 09072 } 09073 /* Our caller will obtain the rest */ 09074 if (!old && chan) 09075 ast_channel_undefer_dtmf(chan); 09076 } 09077 return dp; 09078 }
|
|
Definition at line 1039 of file chan_iax2.c. References accountcode, chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), chan_iax2_pvt::callno, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, match(), new_iax(), option_debug, chan_iax2_pvt::peercallno, ping_time, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, and update_max_nontrunk(). Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_read(). 01040 { 01041 int res = 0; 01042 int x; 01043 struct timeval now; 01044 char iabuf[INET_ADDRSTRLEN]; 01045 char host[80]; 01046 if (new <= NEW_ALLOW) { 01047 /* Look for an existing connection first */ 01048 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01049 ast_mutex_lock(&iaxsl[x]); 01050 if (iaxs[x]) { 01051 /* Look for an exact match */ 01052 if (match(sin, callno, dcallno, iaxs[x])) { 01053 res = x; 01054 } 01055 } 01056 ast_mutex_unlock(&iaxsl[x]); 01057 } 01058 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01059 ast_mutex_lock(&iaxsl[x]); 01060 if (iaxs[x]) { 01061 /* Look for an exact match */ 01062 if (match(sin, callno, dcallno, iaxs[x])) { 01063 res = x; 01064 } 01065 } 01066 ast_mutex_unlock(&iaxsl[x]); 01067 } 01068 } 01069 if ((res < 1) && (new >= NEW_ALLOW)) { 01070 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) 01071 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 01072 gettimeofday(&now, NULL); 01073 for (x=1;x<TRUNK_CALL_START;x++) { 01074 /* Find first unused call number that hasn't been used in a while */ 01075 ast_mutex_lock(&iaxsl[x]); 01076 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01077 ast_mutex_unlock(&iaxsl[x]); 01078 } 01079 /* We've still got lock held if we found a spot */ 01080 if (x >= TRUNK_CALL_START) { 01081 ast_log(LOG_WARNING, "No more space\n"); 01082 return 0; 01083 } 01084 iaxs[x] = new_iax(sin, lockpeer, host); 01085 update_max_nontrunk(); 01086 if (iaxs[x]) { 01087 if (option_debug && iaxdebug) 01088 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01089 iaxs[x]->sockfd = sockfd; 01090 iaxs[x]->addr.sin_port = sin->sin_port; 01091 iaxs[x]->addr.sin_family = sin->sin_family; 01092 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01093 iaxs[x]->peercallno = callno; 01094 iaxs[x]->callno = x; 01095 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01096 iaxs[x]->expiry = min_reg_expire; 01097 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01098 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01099 iaxs[x]->amaflags = amaflags; 01100 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01101 ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode)); 01102 } else { 01103 ast_log(LOG_WARNING, "Out of resources\n"); 01104 ast_mutex_unlock(&iaxsl[x]); 01105 return 0; 01106 } 01107 ast_mutex_unlock(&iaxsl[x]); 01108 res = x; 01109 } 01110 return res; 01111 }
|
|
Definition at line 843 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, name, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer(). 00844 { 00845 struct iax2_peer *peer; 00846 ast_mutex_lock(&peerl.lock); 00847 for(peer = peerl.peers; peer; peer = peer->next) { 00848 if (!strcasecmp(peer->name, name)) { 00849 break; 00850 } 00851 } 00852 ast_mutex_unlock(&peerl.lock); 00853 if(!peer && realtime) 00854 peer = realtime_peer(name, NULL); 00855 return peer; 00856 }
|
|
Definition at line 3683 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::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, malloc, iax2_trunk_peer::next, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact. Referenced by iax2_trunk_queue(), and socket_read(). 03684 { 03685 struct iax2_trunk_peer *tpeer; 03686 char iabuf[INET_ADDRSTRLEN]; 03687 /* Finds and locks trunk peer */ 03688 ast_mutex_lock(&tpeerlock); 03689 tpeer = tpeers; 03690 while(tpeer) { 03691 /* We don't lock here because tpeer->addr *never* changes */ 03692 if (!inaddrcmp(&tpeer->addr, sin)) { 03693 ast_mutex_lock(&tpeer->lock); 03694 break; 03695 } 03696 tpeer = tpeer->next; 03697 } 03698 if (!tpeer) { 03699 tpeer = malloc(sizeof(struct iax2_trunk_peer)); 03700 if (tpeer) { 03701 memset(tpeer, 0, sizeof(struct iax2_trunk_peer)); 03702 ast_mutex_init(&tpeer->lock); 03703 tpeer->lastsent = 9999; 03704 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03705 tpeer->trunkact = ast_tvnow(); 03706 ast_mutex_lock(&tpeer->lock); 03707 tpeer->next = tpeers; 03708 tpeer->sockfd = fd; 03709 tpeers = tpeer; 03710 #ifdef SO_NO_CHECK 03711 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03712 #endif 03713 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)); 03714 } 03715 } 03716 ast_mutex_unlock(&tpeerlock); 03717 return tpeer; 03718 }
|
|
Definition at line 3481 of file chan_iax2.c. References iaxs, chan_iax2_pvt::rxcore, and tv. Referenced by socket_read(). 03482 { 03483 long ms; /* NOT unsigned */ 03484 if (ast_tvzero(iaxs[callno]->rxcore)) { 03485 /* Initialize rxcore time if appropriate */ 03486 gettimeofday(&iaxs[callno]->rxcore, NULL); 03487 /* Round to nearest 20ms so traces look pretty */ 03488 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03489 } 03490 /* Calculate difference between trunk and channel */ 03491 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03492 /* Return as the sum of trunk time and the difference between trunk and real time */ 03493 return ms + ts; 03494 }
|
|
Definition at line 7838 of file chan_iax2.c. References free, and iax2_context::next. Referenced by build_user(), and destroy_user(). 07839 { 07840 struct iax2_context *conl; 07841 while(con) { 07842 conl = con; 07843 con = con->next; 07844 free(conl); 07845 } 07846 }
|
|
Definition at line 9203 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::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, iaxs, LOG_ERROR, iax2_peer::mailbox, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, and ast_channel::tech_pvt. 09204 { 09205 char *ret = NULL; 09206 struct iax2_peer *peer; 09207 char *peername, *colname; 09208 char iabuf[INET_ADDRSTRLEN]; 09209 09210 if (!(peername = ast_strdupa(data))) { 09211 ast_log(LOG_ERROR, "Memory Error!\n"); 09212 return ret; 09213 } 09214 09215 /* if our channel, return the IP address of the endpoint of current channel */ 09216 if (!strcmp(peername,"CURRENTCHANNEL")) { 09217 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt); 09218 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len); 09219 return buf; 09220 } 09221 09222 if ((colname = strchr(peername, ':'))) { 09223 *colname = '\0'; 09224 colname++; 09225 } else { 09226 colname = "ip"; 09227 } 09228 if (!(peer = find_peer(peername, 1))) 09229 return ret; 09230 09231 if (!strcasecmp(colname, "ip")) { 09232 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09233 } else if (!strcasecmp(colname, "status")) { 09234 peer_status(peer, buf, len); 09235 } else if (!strcasecmp(colname, "mailbox")) { 09236 ast_copy_string(buf, peer->mailbox, len); 09237 } else if (!strcasecmp(colname, "context")) { 09238 ast_copy_string(buf, peer->context, len); 09239 } else if (!strcasecmp(colname, "expire")) { 09240 snprintf(buf, len, "%d", peer->expire); 09241 } else if (!strcasecmp(colname, "dynamic")) { 09242 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09243 } else if (!strcasecmp(colname, "callerid_name")) { 09244 ast_copy_string(buf, peer->cid_name, len); 09245 } else if (!strcasecmp(colname, "callerid_num")) { 09246 ast_copy_string(buf, peer->cid_num, len); 09247 } else if (!strcasecmp(colname, "codecs")) { 09248 ast_getformatname_multiple(buf, len -1, peer->capability); 09249 } else if (!strncasecmp(colname, "codec[", 6)) { 09250 char *codecnum, *ptr; 09251 int index = 0, codec = 0; 09252 09253 codecnum = strchr(colname, '['); 09254 *codecnum = '\0'; 09255 codecnum++; 09256 if ((ptr = strchr(codecnum, ']'))) { 09257 *ptr = '\0'; 09258 } 09259 index = atoi(codecnum); 09260 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09261 ast_copy_string(buf, ast_getformatname(codec), len); 09262 } 09263 } 09264 ret = buf; 09265 09266 return ret; 09267 }
|
|
Definition at line 8008 of file chan_iax2.c. Referenced by build_peer(), and build_user(). 08009 { 08010 int methods = 0; 08011 if (strstr(value, "rsa")) 08012 methods |= IAX_AUTH_RSA; 08013 if (strstr(value, "md5")) 08014 methods |= IAX_AUTH_MD5; 08015 if (strstr(value, "plaintext")) 08016 methods |= IAX_AUTH_PLAINTEXT; 08017 return methods; 08018 }
|
|
Definition at line 783 of file chan_iax2.c. References ast_true(), and s. Referenced by build_peer(), build_user(), and set_config(). 00784 { 00785 int e; 00786 if (!strcasecmp(s, "aes128")) 00787 e = IAX_ENCRYPT_AES128; 00788 else if (ast_true(s)) 00789 e = IAX_ENCRYPT_AES128; 00790 else 00791 e = 0; 00792 return e; 00793 }
|
|
Definition at line 2167 of file chan_iax2.c. References __do_deliver(), 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, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, tv, update_jbsched(), and chan_iax2_pvt::voiceformat. Referenced by update_jbsched(). 02168 { 02169 /* make sure pvt is valid! */ 02170 struct chan_iax2_pvt *pvt = p; 02171 struct iax_frame *fr; 02172 jb_frame frame; 02173 int ret; 02174 long now; 02175 long next; 02176 struct timeval tv; 02177 02178 ast_mutex_lock(&iaxsl[pvt->callno]); 02179 /* fprintf(stderr, "get_from_jb called\n"); */ 02180 pvt->jbid = -1; 02181 02182 gettimeofday(&tv,NULL); 02183 /* round up a millisecond since ast_sched_runq does; */ 02184 /* prevents us from spinning while waiting for our now */ 02185 /* to catch up with runq's now */ 02186 tv.tv_usec += 1000; 02187 02188 now = ast_tvdiff_ms(tv, pvt->rxcore); 02189 02190 if(now >= (next = jb_next(pvt->jb))) { 02191 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02192 switch(ret) { 02193 case JB_OK: 02194 /*if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(pvt->jb), next); */ 02195 fr = frame.data; 02196 __do_deliver(fr); 02197 break; 02198 case JB_INTERP: 02199 { 02200 struct ast_frame af; 02201 02202 /*if(next + 20 != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(pvt->jb), next); */ 02203 02204 /* create an interpolation frame */ 02205 /*fprintf(stderr, "Making Interpolation frame\n"); */ 02206 af.frametype = AST_FRAME_VOICE; 02207 af.subclass = pvt->voiceformat; 02208 af.datalen = 0; 02209 af.samples = frame.ms * 8; 02210 af.mallocd = 0; 02211 af.src = "IAX2 JB interpolation"; 02212 af.data = NULL; 02213 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02214 af.offset=AST_FRIENDLY_OFFSET; 02215 02216 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02217 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02218 if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE)) 02219 iax2_queue_frame(pvt->callno, &af); 02220 } 02221 break; 02222 case JB_DROP: 02223 /*if(next != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(pvt->jb), next); */ 02224 iax2_frame_free(frame.data); 02225 break; 02226 case JB_NOFRAME: 02227 case JB_EMPTY: 02228 /* do nothing */ 02229 break; 02230 default: 02231 /* shouldn't happen */ 02232 break; 02233 } 02234 } 02235 update_jbsched(pvt); 02236 ast_mutex_unlock(&iaxsl[pvt->callno]); 02237 return 0; 02238 }
|
|
Definition at line 1435 of file chan_iax2.c. References ast_inet_ntoa(), ast_log(), and LOG_WARNING. Referenced by send_packet(), socket_read(), and transmit_trunk(). 01436 { 01437 /* XXX Ideally we should figure out why an error occured and then abort those 01438 rather than continuing to try. Unfortunately, the published interface does 01439 not seem to work XXX */ 01440 #if 0 01441 struct sockaddr_in *sin; 01442 int res; 01443 struct msghdr m; 01444 struct sock_extended_err e; 01445 m.msg_name = NULL; 01446 m.msg_namelen = 0; 01447 m.msg_iov = NULL; 01448 m.msg_control = &e; 01449 m.msg_controllen = sizeof(e); 01450 m.msg_flags = 0; 01451 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01452 if (res < 0) 01453 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01454 else { 01455 if (m.msg_controllen) { 01456 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01457 if (sin) 01458 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 01459 else 01460 ast_log(LOG_WARNING, "No address detected??\n"); 01461 } else { 01462 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01463 } 01464 } 01465 #endif 01466 return 0; 01467 }
|
|
Acknowledgment received for OUR registration.
Definition at line 5432 of file chan_iax2.c. References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iaxs, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax2_registry::refresh, iax_ies::refresh, chan_iax2_pvt::reg, sched, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3. Referenced by socket_read(). 05433 { 05434 struct iax2_registry *reg; 05435 /* Start pessimistic */ 05436 char peer[256] = ""; 05437 char msgstatus[40]; 05438 int refresh = 0; 05439 char ourip[256] = "<Unspecified>"; 05440 struct sockaddr_in oldus; 05441 struct sockaddr_in us; 05442 char iabuf[INET_ADDRSTRLEN]; 05443 int oldmsgs; 05444 05445 memset(&us, 0, sizeof(us)); 05446 if (ies->apparent_addr) 05447 memcpy(&us, ies->apparent_addr, sizeof(us)); 05448 if (ies->username) 05449 ast_copy_string(peer, ies->username, sizeof(peer)); 05450 if (ies->refresh) 05451 refresh = ies->refresh; 05452 if (ies->calling_number) { 05453 /* We don't do anything with it really, but maybe we should */ 05454 } 05455 reg = iaxs[callno]->reg; 05456 if (!reg) { 05457 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05458 return -1; 05459 } 05460 memcpy(&oldus, ®->us, sizeof(oldus)); 05461 oldmsgs = reg->messages; 05462 if (inaddrcmp(®->addr, sin)) { 05463 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05464 return -1; 05465 } 05466 memcpy(®->us, &us, sizeof(reg->us)); 05467 reg->messages = ies->msgcount; 05468 /* always refresh the registration at the interval requested by the server 05469 we are registering to 05470 */ 05471 reg->refresh = refresh; 05472 if (reg->expire > -1) 05473 ast_sched_del(sched, reg->expire); 05474 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05475 if ((inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) { 05476 if (reg->messages > 65534) 05477 snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n"); 05478 else if (reg->messages > 1) 05479 snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages); 05480 else if (reg->messages > 0) 05481 snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n"); 05482 else 05483 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05484 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 05485 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); 05486 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)); 05487 } 05488 reg->regstate = REG_STATE_REGISTERED; 05489 return 0; 05490 }
|
|
Definition at line 3332 of file chan_iax2.c. References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), LOG_DEBUG, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03333 { 03334 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03335 if (option_debug) 03336 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03337 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03338 }
|
|
Definition at line 3166 of file chan_iax2.c. References ast_channel::_softhangup, AST_BRIDGE_DTMF_CHANNEL_0, ast_bridge_result, ast_check_hangup(), ast_frfree(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, ast_frame::frametype, iax2_start_transfer(), IAX_NOTRANSFER, iaxdebug, iaxs, iaxsl, lock_both(), LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3. 03167 { 03168 struct ast_channel *cs[3]; 03169 struct ast_channel *who; 03170 int to = -1; 03171 int res = -1; 03172 int transferstarted=0; 03173 struct ast_frame *f; 03174 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03175 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03176 struct timeval waittimer = {0, 0}, tv; 03177 03178 lock_both(callno0, callno1); 03179 /* Put them in native bridge mode */ 03180 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03181 iaxs[callno0]->bridgecallno = callno1; 03182 iaxs[callno1]->bridgecallno = callno0; 03183 } 03184 unlock_both(callno0, callno1); 03185 03186 /* If not, try to bridge until we can execute a transfer, if we can */ 03187 cs[0] = c0; 03188 cs[1] = c1; 03189 for (/* ever */;;) { 03190 /* Check in case we got masqueraded into */ 03191 if ((c0->type != channeltype) || (c1->type != channeltype)) { 03192 if (option_verbose > 2) 03193 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03194 /* Remove from native mode */ 03195 if (c0->type == channeltype) { 03196 ast_mutex_lock(&iaxsl[callno0]); 03197 iaxs[callno0]->bridgecallno = 0; 03198 ast_mutex_unlock(&iaxsl[callno0]); 03199 } 03200 if (c1->type == channeltype) { 03201 ast_mutex_lock(&iaxsl[callno1]); 03202 iaxs[callno1]->bridgecallno = 0; 03203 ast_mutex_unlock(&iaxsl[callno1]); 03204 } 03205 return AST_BRIDGE_FAILED_NOWARN; 03206 } 03207 if (c0->nativeformats != c1->nativeformats) { 03208 if (option_verbose > 2) { 03209 char buf0[255]; 03210 char buf1[255]; 03211 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03212 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03213 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03214 } 03215 /* Remove from native mode */ 03216 lock_both(callno0, callno1); 03217 iaxs[callno0]->bridgecallno = 0; 03218 iaxs[callno1]->bridgecallno = 0; 03219 unlock_both(callno0, callno1); 03220 return AST_BRIDGE_FAILED_NOWARN; 03221 } 03222 /* check if transfered and if we really want native bridging */ 03223 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) && 03224 !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03225 /* Try the transfer */ 03226 if (iax2_start_transfer(callno0, callno1)) 03227 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03228 transferstarted = 1; 03229 } 03230 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03231 /* Call has been transferred. We're no longer involved */ 03232 gettimeofday(&tv, NULL); 03233 if (ast_tvzero(waittimer)) { 03234 waittimer = tv; 03235 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03236 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03237 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03238 *fo = NULL; 03239 *rc = c0; 03240 res = AST_BRIDGE_COMPLETE; 03241 break; 03242 } 03243 } 03244 to = 1000; 03245 who = ast_waitfor_n(cs, 2, &to); 03246 if (timeoutms > -1) { 03247 timeoutms -= (1000 - to); 03248 if (timeoutms < 0) 03249 timeoutms = 0; 03250 } 03251 if (!who) { 03252 if (!timeoutms) { 03253 res = AST_BRIDGE_RETRY; 03254 break; 03255 } 03256 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03257 res = AST_BRIDGE_FAILED; 03258 break; 03259 } 03260 continue; 03261 } 03262 f = ast_read(who); 03263 if (!f) { 03264 *fo = NULL; 03265 *rc = who; 03266 res = AST_BRIDGE_COMPLETE; 03267 break; 03268 } 03269 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03270 *fo = f; 03271 *rc = who; 03272 res = AST_BRIDGE_COMPLETE; 03273 break; 03274 } 03275 if ((f->frametype == AST_FRAME_VOICE) || 03276 (f->frametype == AST_FRAME_TEXT) || 03277 (f->frametype == AST_FRAME_VIDEO) || 03278 (f->frametype == AST_FRAME_IMAGE) || 03279 (f->frametype == AST_FRAME_DTMF)) { 03280 if ((f->frametype == AST_FRAME_DTMF) && 03281 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03282 if ((who == c0)) { 03283 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 03284 *rc = c0; 03285 *fo = f; 03286 res = AST_BRIDGE_COMPLETE; 03287 /* Remove from native mode */ 03288 break; 03289 } else 03290 goto tackygoto; 03291 } else 03292 if ((who == c1)) { 03293 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 03294 *rc = c1; 03295 *fo = f; 03296 res = AST_BRIDGE_COMPLETE; 03297 break; 03298 } else 03299 goto tackygoto; 03300 } 03301 } else { 03302 #if 0 03303 if (iaxdebug && option_debug) 03304 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03305 if (who == last) 03306 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03307 last = who; 03308 #endif 03309 tackygoto: 03310 if (who == c0) 03311 ast_write(c1, f); 03312 else 03313 ast_write(c0, f); 03314 } 03315 ast_frfree(f); 03316 } else 03317 ast_frfree(f); 03318 /* Swap who gets priority */ 03319 cs[2] = cs[0]; 03320 cs[0] = cs[1]; 03321 cs[1] = cs[2]; 03322 } 03323 lock_both(callno0, callno1); 03324 if(iaxs[callno0]) 03325 iaxs[callno0]->bridgecallno = 0; 03326 if(iaxs[callno1]) 03327 iaxs[callno1]->bridgecallno = 0; 03328 unlock_both(callno0, callno1); 03329 return res; 03330 }
|
|
Definition at line 2928 of file chan_iax2.c. References ast_channel::_state, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_sched_add(), ast_setstate(), AST_STATE_RINGING, ast_strdupa, ast_strlen_zero(), ast_test_flag, auto_congest(), autokill, CALLNO_TO_PTR, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, context, ast_channel::context, create_addr_info::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, iax2_datetime(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, chan_iax2_pvt::outkey, create_addr_info::outkey, parse_dial_string(), create_addr_info::peercontext, chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, chan_iax2_pvt::secret, create_addr_info::secret, send_command(), ast_channel::tech_pvt, chan_iax2_pvt::username, and create_addr_info::username. 02929 { 02930 struct sockaddr_in sin; 02931 char *l=NULL, *n=NULL, *tmpstr; 02932 struct iax_ie_data ied; 02933 char *defaultrdest = "s"; 02934 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02935 struct parsed_dial_string pds; 02936 struct create_addr_info cai; 02937 02938 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 02939 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 02940 return -1; 02941 } 02942 02943 memset(&cai, 0, sizeof(cai)); 02944 cai.encmethods = iax2_encryption; 02945 02946 memset(&pds, 0, sizeof(pds)); 02947 tmpstr = ast_strdupa(dest); 02948 parse_dial_string(tmpstr, &pds); 02949 02950 if (!pds.exten) 02951 pds.exten = defaultrdest; 02952 02953 if (create_addr(pds.peer, &sin, &cai)) { 02954 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 02955 return -1; 02956 } 02957 02958 if (!pds.username && !ast_strlen_zero(cai.username)) 02959 pds.username = cai.username; 02960 if (!pds.password && !ast_strlen_zero(cai.secret)) 02961 pds.password = cai.secret; 02962 if (!pds.key && !ast_strlen_zero(cai.outkey)) 02963 pds.key = cai.outkey; 02964 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 02965 pds.context = cai.peercontext; 02966 02967 /* Keep track of the context for outgoing calls too */ 02968 ast_copy_string(c->context, cai.context, sizeof(c->context)); 02969 02970 if (pds.port) 02971 sin.sin_port = htons(atoi(pds.port)); 02972 02973 l = c->cid.cid_num; 02974 n = c->cid.cid_name; 02975 02976 /* Now build request */ 02977 memset(&ied, 0, sizeof(ied)); 02978 02979 /* On new call, first IE MUST be IAX version of caller */ 02980 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 02981 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 02982 if (pds.options && strchr(pds.options, 'a')) { 02983 /* Request auto answer */ 02984 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 02985 } 02986 02987 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 02988 02989 if (l) { 02990 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 02991 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02992 } else { 02993 if (n) 02994 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02995 else 02996 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 02997 } 02998 02999 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03000 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03001 03002 if (n) 03003 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03004 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03005 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03006 03007 if (!ast_strlen_zero(c->language)) 03008 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03009 if (!ast_strlen_zero(c->cid.cid_dnid)) 03010 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03011 03012 if (pds.context) 03013 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03014 03015 if (pds.username) 03016 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03017 03018 if (cai.encmethods) 03019 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03020 03021 ast_mutex_lock(&iaxsl[callno]); 03022 03023 if (!ast_strlen_zero(c->context)) 03024 ast_copy_string(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context)); 03025 03026 if (pds.username) 03027 ast_copy_string(iaxs[callno]->username, pds.username, sizeof(iaxs[callno]->username)); 03028 03029 iaxs[callno]->encmethods = cai.encmethods; 03030 03031 if (pds.key) 03032 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 03033 if (pds.password) 03034 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 03035 03036 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03037 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03038 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03039 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03040 03041 if (iaxs[callno]->maxtime) { 03042 /* Initialize pingtime and auto-congest time */ 03043 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03044 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03045 } else if (autokill) { 03046 iaxs[callno]->pingtime = autokill / 2; 03047 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03048 } 03049 03050 /* Transmit the string in a "NEW" request */ 03051 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03052 03053 ast_mutex_unlock(&iaxsl[callno]); 03054 ast_setstate(c, AST_STATE_RINGING); 03055 03056 return 0; 03057 }
|
|
Definition at line 9104 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), context, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING. 09105 { 09106 int res = 0; 09107 struct iax2_dpcache *dp; 09108 #if 0 09109 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09110 #endif 09111 if ((priority != 1) && (priority != 2)) 09112 return 0; 09113 ast_mutex_lock(&dpcache_lock); 09114 dp = find_cache(chan, data, context, exten, priority); 09115 if (dp) { 09116 if (dp->flags & CACHE_FLAG_CANEXIST) 09117 res= 1; 09118 } 09119 ast_mutex_unlock(&dpcache_lock); 09120 if (!dp) { 09121 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09122 } 09123 return res; 09124 }
|
|
Definition at line 2841 of file chan_iax2.c. References ast_localtime(), and ast_strlen_zero(). Referenced by iax2_call(), and update_registry(). 02842 { 02843 time_t t; 02844 struct tm tm; 02845 unsigned int tmp; 02846 time(&t); 02847 localtime_r(&t, &tm); 02848 if (!ast_strlen_zero(tz)) 02849 ast_localtime(&t, &tm, tz); 02850 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02851 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02852 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02853 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02854 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02855 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02856 return tmp; 02857 }
|
|
Definition at line 1580 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_translator_free_path(), ast_variables_destroy(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgetrans, iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, ast_iax2_queue::head, iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, lastused, ast_channel::lock, LOG_NOTICE, iax_frame::next, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, chan_iax2_pvt::reg, iax_frame::retries, sched, update_max_trunk(), and chan_iax2_pvt::vars. Referenced by __unload_module(), destroy_peer(), iax2_destroy_nolock(), iax2_poke_noanswer(), and iax2_poke_peer(). 01581 { 01582 struct chan_iax2_pvt *pvt; 01583 struct iax_frame *cur; 01584 struct ast_channel *owner; 01585 01586 retry: 01587 ast_mutex_lock(&iaxsl[callno]); 01588 pvt = iaxs[callno]; 01589 gettimeofday(&lastused[callno], NULL); 01590 01591 if (pvt) 01592 owner = pvt->owner; 01593 else 01594 owner = NULL; 01595 if (owner) { 01596 if (ast_mutex_trylock(&owner->lock)) { 01597 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01598 ast_mutex_unlock(&iaxsl[callno]); 01599 usleep(1); 01600 goto retry; 01601 } 01602 } 01603 if (!owner) 01604 iaxs[callno] = NULL; 01605 if (pvt) { 01606 if (!owner) 01607 pvt->owner = NULL; 01608 /* No more pings or lagrq's */ 01609 if (pvt->pingid > -1) 01610 ast_sched_del(sched, pvt->pingid); 01611 if (pvt->lagid > -1) 01612 ast_sched_del(sched, pvt->lagid); 01613 if (pvt->autoid > -1) 01614 ast_sched_del(sched, pvt->autoid); 01615 if (pvt->authid > -1) 01616 ast_sched_del(sched, pvt->authid); 01617 if (pvt->initid > -1) 01618 ast_sched_del(sched, pvt->initid); 01619 #ifdef NEWJB 01620 if (pvt->jbid > -1) 01621 ast_sched_del(sched, pvt->jbid); 01622 pvt->jbid = -1; 01623 #endif 01624 pvt->pingid = -1; 01625 pvt->lagid = -1; 01626 pvt->autoid = -1; 01627 pvt->authid = -1; 01628 pvt->initid = -1; 01629 if (pvt->bridgetrans) 01630 ast_translator_free_path(pvt->bridgetrans); 01631 pvt->bridgetrans = NULL; 01632 01633 /* Already gone */ 01634 ast_set_flag(pvt, IAX_ALREADYGONE); 01635 01636 if (owner) { 01637 /* If there's an owner, prod it to give up */ 01638 owner->_softhangup |= AST_SOFTHANGUP_DEV; 01639 ast_queue_hangup(owner); 01640 } 01641 01642 for (cur = iaxq.head; cur ; cur = cur->next) { 01643 /* Cancel any pending transmissions */ 01644 if (cur->callno == pvt->callno) 01645 cur->retries = -1; 01646 } 01647 if (pvt->reg) { 01648 pvt->reg->callno = 0; 01649 } 01650 if (!owner) { 01651 if (pvt->vars) { 01652 ast_variables_destroy(pvt->vars); 01653 pvt->vars = NULL; 01654 } 01655 #ifdef NEWJB 01656 { 01657 jb_frame frame; 01658 while(jb_getall(pvt->jb,&frame) == JB_OK) 01659 iax2_frame_free(frame.data); 01660 jb_destroy(pvt->jb); 01661 } 01662 #endif 01663 free(pvt); 01664 } 01665 } 01666 if (owner) { 01667 ast_mutex_unlock(&owner->lock); 01668 } 01669 ast_mutex_unlock(&iaxsl[callno]); 01670 if (callno & 0x4000) 01671 update_max_trunk(); 01672 }
|
|
Definition at line 1673 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax2_destroy(), and iaxsl. Referenced by attempt_transmit(), delete_users(), iax2_hangup(), and socket_read(). 01674 { 01675 /* Actually it's easier to unlock, kill it, and relock */ 01676 ast_mutex_unlock(&iaxsl[callno]); 01677 iax2_destroy(callno); 01678 ast_mutex_lock(&iaxsl[callno]); 01679 }
|
|
Definition at line 9292 of file chan_iax2.c. References iax2_peer::addr, ast_log(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, LOG_DEBUG, iax2_peer::maxms, and option_debug. 09293 { 09294 char *dest = (char *) data; 09295 struct iax2_peer *p; 09296 int found = 0; 09297 char *ext, *host; 09298 char tmp[256]; 09299 int res = AST_DEVICE_INVALID; 09300 09301 ast_copy_string(tmp, dest, sizeof(tmp)); 09302 host = strchr(tmp, '@'); 09303 if (host) { 09304 *host = '\0'; 09305 host++; 09306 ext = tmp; 09307 } else { 09308 host = tmp; 09309 ext = NULL; 09310 } 09311 09312 if (option_debug > 2) 09313 ast_log(LOG_DEBUG, "Checking device state for device %s\n", dest); 09314 09315 /* SLD: FIXME: second call to find_peer during registration */ 09316 p = find_peer(host, 1); 09317 if (p) { 09318 found++; 09319 res = AST_DEVICE_UNAVAILABLE; 09320 if (option_debug > 2) 09321 ast_log(LOG_DEBUG, "iax2_devicestate(%s): Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09322 host, dest, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09323 09324 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09325 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09326 /* Peer is registered, or have default IP address 09327 and a valid registration */ 09328 if (p->historicms == 0 || p->historicms <= p->maxms) 09329 /* let the core figure out whether it is in use or not */ 09330 res = AST_DEVICE_UNKNOWN; 09331 } 09332 } else { 09333 if (option_debug > 2) 09334 ast_log(LOG_DEBUG, "Devicestate: Can't find peer %s.\n", host); 09335 } 09336 09337 if (p && ast_test_flag(p, IAX_TEMPONLY)) 09338 destroy_peer(p); 09339 return res; 09340 }
|
|
Definition at line 2530 of file chan_iax2.c. References AST_FRAME_DTMF, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 02531 { 02532 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1); 02533 }
|
|
Definition at line 4557 of file chan_iax2.c. References ast_cli(), and iaxdebug. 04558 { 04559 if (argc != 2) 04560 return RESULT_SHOWUSAGE; 04561 iaxdebug = 1; 04562 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04563 return RESULT_SUCCESS; 04564 }
|
|
Definition at line 4575 of file chan_iax2.c. References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), and jb_warning_output(). 04576 { 04577 if (argc != 3) 04578 return RESULT_SHOWUSAGE; 04579 #ifdef NEWJB 04580 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04581 #endif 04582 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04583 return RESULT_SUCCESS; 04584 }
|
|
Definition at line 7629 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, iaxs, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, sched, send_command(), and iax2_registry::username. Referenced by iax2_do_register_s(), and load_module(). 07630 { 07631 struct iax_ie_data ied; 07632 if (option_debug && iaxdebug) 07633 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07634 if (!reg->callno) { 07635 if (option_debug) 07636 ast_log(LOG_DEBUG, "Allocate call number\n"); 07637 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07638 if (reg->callno < 1) { 07639 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07640 return -1; 07641 } else if (option_debug) 07642 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07643 iaxs[reg->callno]->reg = reg; 07644 } 07645 /* Schedule the next registration attempt */ 07646 if (reg->expire > -1) 07647 ast_sched_del(sched, reg->expire); 07648 /* Setup the next registration a little early */ 07649 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07650 /* Send the request */ 07651 memset(&ied, 0, sizeof(ied)); 07652 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07653 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07654 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07655 reg->regstate = REG_STATE_REGSENT; 07656 return 0; 07657 }
|
|
Definition at line 5278 of file chan_iax2.c. References iax2_registry::expire, and iax2_do_register(). Referenced by iax2_ack_registry(), and iax2_do_register(). 05279 { 05280 struct iax2_registry *reg = data; 05281 reg->expire = -1; 05282 iax2_do_register(reg); 05283 return 0; 05284 }
|
|
Definition at line 4566 of file chan_iax2.c. References ast_cli(), and iaxtrunkdebug. 04567 { 04568 if (argc != 3) 04569 return RESULT_SHOWUSAGE; 04570 iaxtrunkdebug = 1; 04571 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04572 return RESULT_SUCCESS; 04573 }
|
|
Definition at line 5889 of file chan_iax2.c. References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command(). Referenced by find_cache(), and socket_read(). 05890 { 05891 struct iax_ie_data ied; 05892 /* Auto-hangup with 30 seconds of inactivity */ 05893 if (iaxs[callno]->autoid > -1) 05894 ast_sched_del(sched, iaxs[callno]->autoid); 05895 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 05896 memset(&ied, 0, sizeof(ied)); 05897 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 05898 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 05899 dp->flags |= CACHE_FLAG_TRANSMITTED; 05900 }
|
|
Definition at line 9150 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), context, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3. 09151 { 09152 char odata[256]; 09153 char req[256]; 09154 char *ncontext; 09155 char *dialstatus; 09156 struct iax2_dpcache *dp; 09157 struct ast_app *dial; 09158 #if 0 09159 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); 09160 #endif 09161 if (priority == 2) { 09162 /* Indicate status, can be overridden in dialplan */ 09163 dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09164 if (dialstatus) { 09165 dial = pbx_findapp(dialstatus); 09166 if (dial) 09167 pbx_exec(chan, dial, "", newstack); 09168 } 09169 return -1; 09170 } else if (priority != 1) 09171 return -1; 09172 ast_mutex_lock(&dpcache_lock); 09173 dp = find_cache(chan, data, context, exten, priority); 09174 if (dp) { 09175 if (dp->flags & CACHE_FLAG_EXISTS) { 09176 ast_copy_string(odata, data, sizeof(odata)); 09177 ncontext = strchr(odata, '/'); 09178 if (ncontext) { 09179 *ncontext = '\0'; 09180 ncontext++; 09181 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09182 } else { 09183 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09184 } 09185 if (option_verbose > 2) 09186 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09187 } else { 09188 ast_mutex_unlock(&dpcache_lock); 09189 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09190 return -1; 09191 } 09192 } 09193 ast_mutex_unlock(&dpcache_lock); 09194 dial = pbx_findapp("Dial"); 09195 if (dial) { 09196 return pbx_exec(chan, dial, req, newstack); 09197 } else { 09198 ast_log(LOG_WARNING, "No dial application registered\n"); 09199 } 09200 return -1; 09201 }
|
|
Definition at line 9081 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), context, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING. 09082 { 09083 struct iax2_dpcache *dp; 09084 int res = 0; 09085 #if 0 09086 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09087 #endif 09088 if ((priority != 1) && (priority != 2)) 09089 return 0; 09090 ast_mutex_lock(&dpcache_lock); 09091 dp = find_cache(chan, data, context, exten, priority); 09092 if (dp) { 09093 if (dp->flags & CACHE_FLAG_EXISTS) 09094 res= 1; 09095 } 09096 ast_mutex_unlock(&dpcache_lock); 09097 if (!dp) { 09098 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09099 } 09100 return res; 09101 }
|
|
Definition at line 2552 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt. 02553 { 02554 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02555 ast_mutex_lock(&iaxsl[callno]); 02556 if (iaxs[callno]) 02557 iaxs[callno]->owner = newchan; 02558 else 02559 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02560 ast_mutex_unlock(&iaxsl[callno]); 02561 return 0; 02562 }
|
|
Definition at line 1113 of file chan_iax2.c. References ast_sched_del(), iax_frame_free(), iax_frame::retrans, and sched. Referenced by __do_deliver(), attempt_transmit(), complete_transfer(), get_from_jb(), iax2_destroy(), and schedule_delivery(). 01114 { 01115 if (fr->retrans > -1) 01116 ast_sched_del(sched, fr->retrans); 01117 iax_frame_free(fr); 01118 }
|
|
Definition at line 858 of file chan_iax2.c. References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_peer(), IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer(). Referenced by find_callno(). 00859 { 00860 struct iax2_peer *peer; 00861 int res = 0; 00862 00863 if (lockpeer) 00864 ast_mutex_lock(&peerl.lock); 00865 peer = peerl.peers; 00866 while (peer) { 00867 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 00868 (peer->addr.sin_port == sin.sin_port)) { 00869 ast_copy_string(host, peer->name, len); 00870 res = 1; 00871 break; 00872 } 00873 peer = peer->next; 00874 } 00875 if (lockpeer) 00876 ast_mutex_unlock(&peerl.lock); 00877 if (!peer) { 00878 peer = realtime_peer(NULL, &sin); 00879 if (peer) { 00880 ast_copy_string(host, peer->name, len); 00881 if (ast_test_flag(peer, IAX_TEMPONLY)) 00882 destroy_peer(peer); 00883 res = 1; 00884 } 00885 } 00886 00887 return res; 00888 }
|
|
Definition at line 3371 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(). 03372 { 03373 struct iax2_peer *peer; 03374 int res = 0; 03375 ast_mutex_lock(&peerl.lock); 03376 peer = peerl.peers; 03377 while(peer) { 03378 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03379 (peer->addr.sin_port == sin.sin_port)) { 03380 res = ast_test_flag(peer, IAX_TRUNK); 03381 break; 03382 } 03383 peer = peer->next; 03384 } 03385 ast_mutex_unlock(&peerl.lock); 03386 return res; 03387 }
|
|
Definition at line 3059 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), chan_iax2_pvt::error, ast_channel::hangupcause, iax2_destroy_nolock(), iax2_predestroy_nolock(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_DEBUG, ast_channel::name, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3. 03060 { 03061 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03062 int alreadygone; 03063 struct iax_ie_data ied; 03064 memset(&ied, 0, sizeof(ied)); 03065 ast_mutex_lock(&iaxsl[callno]); 03066 if (callno && iaxs[callno]) { 03067 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03068 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03069 /* Send the hangup unless we have had a transmission error or are already gone */ 03070 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03071 if (!iaxs[callno]->error && !alreadygone) 03072 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03073 /* Explicitly predestroy it */ 03074 iax2_predestroy_nolock(callno); 03075 /* If we were already gone to begin with, destroy us now */ 03076 if (alreadygone) { 03077 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03078 iax2_destroy_nolock(callno); 03079 } 03080 } 03081 ast_mutex_unlock(&iaxsl[callno]); 03082 if (option_verbose > 2) 03083 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03084 return 0; 03085 }
|
|
Definition at line 3340 of file chan_iax2.c. References AST_FRAME_CONTROL, ast_log(), LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03341 { 03342 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03343 if (option_debug && iaxdebug) 03344 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03345 return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1); 03346 }
|
|
Definition at line 9127 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), context, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING. 09128 { 09129 int res = 0; 09130 struct iax2_dpcache *dp; 09131 #if 0 09132 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09133 #endif 09134 if ((priority != 1) && (priority != 2)) 09135 return 0; 09136 ast_mutex_lock(&dpcache_lock); 09137 dp = find_cache(chan, data, context, exten, priority); 09138 if (dp) { 09139 if (dp->flags & CACHE_FLAG_MATCHMORE) 09140 res= 1; 09141 } 09142 ast_mutex_unlock(&dpcache_lock); 09143 if (!dp) { 09144 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09145 } 09146 return res; 09147 }
|
|
Definition at line 4586 of file chan_iax2.c. References ast_cli(), and iaxdebug. 04587 { 04588 if (argc != 3) 04589 return RESULT_SHOWUSAGE; 04590 iaxdebug = 0; 04591 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04592 return RESULT_SUCCESS; 04593 }
|
|
Definition at line 4604 of file chan_iax2.c. References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), and jb_warning_output(). 04605 { 04606 if (argc != 4) 04607 return RESULT_SHOWUSAGE; 04608 #ifdef NEWJB 04609 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04610 jb_debug_output("\n"); 04611 #endif 04612 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04613 return RESULT_SUCCESS; 04614 }
|
|
Definition at line 4595 of file chan_iax2.c. References ast_cli(), and iaxtrunkdebug. 04596 { 04597 if (argc != 4) 04598 return RESULT_SHOWUSAGE; 04599 iaxtrunkdebug = 0; 04600 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04601 return RESULT_SUCCESS; 04602 }
|
|
Definition at line 7780 of file chan_iax2.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched. Referenced by iax2_poke_peer(). 07781 { 07782 struct iax2_peer *peer = data; 07783 peer->pokeexpire = -1; 07784 if (peer->lastms > -1) { 07785 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07786 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07787 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07788 } 07789 if (peer->callno > 0) 07790 iax2_destroy(peer->callno); 07791 peer->callno = 0; 07792 peer->lastms = -1; 07793 /* Try again quickly */ 07794 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07795 return 0; 07796 }
|
|
Definition at line 7798 of file chan_iax2.c. References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd. Referenced by iax2_poke_peer_s(), load_module(), reg_source_db(), and update_registry(). 07799 { 07800 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07801 /* IF we have no IP, or this isn't to be monitored, return 07802 imeediately after clearing things out */ 07803 peer->lastms = 0; 07804 peer->historicms = 0; 07805 peer->pokeexpire = -1; 07806 peer->callno = 0; 07807 return 0; 07808 } 07809 if (peer->callno > 0) { 07810 ast_log(LOG_NOTICE, "Still have a callno...\n"); 07811 iax2_destroy(peer->callno); 07812 } 07813 if (heldcall) 07814 ast_mutex_unlock(&iaxsl[heldcall]); 07815 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 07816 if (heldcall) 07817 ast_mutex_lock(&iaxsl[heldcall]); 07818 if (peer->callno < 1) { 07819 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 07820 return -1; 07821 } 07822 if (peer->pokeexpire > -1) 07823 ast_sched_del(sched, peer->pokeexpire); 07824 /* Speed up retransmission times */ 07825 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 07826 iaxs[peer->callno]->peerpoke = peer; 07827 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 07828 07829 /* If the host is already unreachable then use the unreachable interval instead */ 07830 if (peer->lastms < 0) { 07831 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 07832 } else 07833 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 07834 07835 return 0; 07836 }
|
|
Definition at line 5923 of file chan_iax2.c. References iax2_poke_peer(), and iax2_peer::pokeexpire. Referenced by iax2_poke_noanswer(), and socket_read(). 05924 { 05925 struct iax2_peer *peer = data; 05926 peer->pokeexpire = -1; 05927 iax2_poke_peer(peer, 0); 05928 return 0; 05929 }
|
|
Definition at line 1520 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_test_flag, ast_update_use_count(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, LOG_WARNING, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, sched, ast_channel::tech_pvt, and usecnt. Referenced by iax2_predestroy_nolock(). 01521 { 01522 struct ast_channel *c; 01523 struct chan_iax2_pvt *pvt; 01524 ast_mutex_lock(&iaxsl[callno]); 01525 pvt = iaxs[callno]; 01526 if (!pvt) { 01527 ast_mutex_unlock(&iaxsl[callno]); 01528 return -1; 01529 } 01530 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01531 /* No more pings or lagrq's */ 01532 if (pvt->pingid > -1) 01533 ast_sched_del(sched, pvt->pingid); 01534 if (pvt->lagid > -1) 01535 ast_sched_del(sched, pvt->lagid); 01536 if (pvt->autoid > -1) 01537 ast_sched_del(sched, pvt->autoid); 01538 if (pvt->authid > -1) 01539 ast_sched_del(sched, pvt->authid); 01540 if (pvt->initid > -1) 01541 ast_sched_del(sched, pvt->initid); 01542 #ifdef NEWJB 01543 if (pvt->jbid > -1) 01544 ast_sched_del(sched, pvt->jbid); 01545 pvt->jbid = -1; 01546 #endif 01547 pvt->pingid = -1; 01548 pvt->lagid = -1; 01549 pvt->autoid = -1; 01550 pvt->initid = -1; 01551 pvt->authid = -1; 01552 ast_set_flag(pvt, IAX_ALREADYGONE); 01553 } 01554 c = pvt->owner; 01555 if (c) { 01556 c->_softhangup |= AST_SOFTHANGUP_DEV; 01557 c->tech_pvt = NULL; 01558 ast_queue_hangup(c); 01559 pvt->owner = NULL; 01560 ast_mutex_lock(&usecnt_lock); 01561 usecnt--; 01562 if (usecnt < 0) 01563 ast_log(LOG_WARNING, "Usecnt < 0???\n"); 01564 ast_mutex_unlock(&usecnt_lock); 01565 } 01566 ast_mutex_unlock(&iaxsl[callno]); 01567 ast_update_use_count(); 01568 return 0; 01569 }
|
|
Definition at line 1571 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax2_predestroy(), and iaxsl. Referenced by iax2_hangup(), and send_command_final(). 01572 { 01573 int res; 01574 ast_mutex_unlock(&iaxsl[callno]); 01575 res = iax2_predestroy(callno); 01576 ast_mutex_lock(&iaxsl[callno]); 01577 return res; 01578 }
|
|
Definition at line 7758 of file chan_iax2.c. References ast_cli(), and iax2_provision(). 07759 { 07760 int force = 0; 07761 int res; 07762 if (argc < 4) 07763 return RESULT_SHOWUSAGE; 07764 if ((argc > 4)) { 07765 if (!strcasecmp(argv[4], "forced")) 07766 force = 1; 07767 else 07768 return RESULT_SHOWUSAGE; 07769 } 07770 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07771 if (res < 0) 07772 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07773 else if (res < 1) 07774 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07775 else 07776 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07777 return RESULT_SUCCESS; 07778 }
|
|
Definition at line 7659 of file chan_iax2.c. References iax_prov_complete_template(). 07660 { 07661 if (pos != 3) 07662 return NULL; 07663 return iax_prov_complete_template(line, word, pos, state); 07664 }
|
|
Definition at line 7666 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, LOG_DEBUG, NEW_FORCE, iax_ie_data::pos, sched, send_command(), and create_addr_info::sockfd. Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd(). 07667 { 07668 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07669 is found for template */ 07670 struct iax_ie_data provdata; 07671 struct iax_ie_data ied; 07672 unsigned int sig; 07673 struct sockaddr_in sin; 07674 int callno; 07675 struct create_addr_info cai; 07676 07677 memset(&cai, 0, sizeof(cai)); 07678 07679 if (option_debug) 07680 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07681 07682 if (iax_provision_build(&provdata, &sig, template, force)) { 07683 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07684 return 0; 07685 } 07686 07687 if (end) { 07688 memcpy(&sin, end, sizeof(sin)); 07689 cai.sockfd = sockfd; 07690 } else if (create_addr(dest, &sin, &cai)) 07691 return -1; 07692 07693 /* Build the rest of the message */ 07694 memset(&ied, 0, sizeof(ied)); 07695 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07696 07697 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07698 if (!callno) 07699 return -1; 07700 07701 ast_mutex_lock(&iaxsl[callno]); 07702 if (iaxs[callno]) { 07703 /* Schedule autodestruct in case they don't ever give us anything back */ 07704 if (iaxs[callno]->autoid > -1) 07705 ast_sched_del(sched, iaxs[callno]->autoid); 07706 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07707 ast_set_flag(iaxs[callno], IAX_PROVISION); 07708 /* Got a call number now, so go ahead and send the provisioning information */ 07709 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07710 } 07711 ast_mutex_unlock(&iaxsl[callno]); 07712 07713 return 1; 07714 }
|
|
Definition at line 1819 of file chan_iax2.c. References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, and reload_config(). 01820 { 01821 struct iax2_peer *peer; 01822 01823 if (argc != 4) 01824 return RESULT_SHOWUSAGE; 01825 if (!strcmp(argv[3],"all")) { 01826 reload_config(); 01827 ast_cli(fd, "OK cache is flushed.\n"); 01828 } else if ((peer = find_peer(argv[3], 0))) { 01829 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 01830 ast_set_flag(peer, IAX_RTAUTOCLEAR); 01831 expire_registry(peer); 01832 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 01833 } else { 01834 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 01835 } 01836 } else { 01837 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 01838 } 01839 01840 return RESULT_SUCCESS; 01841 }
|
|
Definition at line 1120 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), iaxs, iaxsl, and chan_iax2_pvt::owner. Referenced by __do_deliver(), attempt_transmit(), auto_congest(), get_from_jb(), and socket_read(). 01121 { 01122 /* Assumes lock for callno is already held... */ 01123 for (;;) { 01124 if (iaxs[callno] && iaxs[callno]->owner) { 01125 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01126 /* Avoid deadlock by pausing and trying again */ 01127 ast_mutex_unlock(&iaxsl[callno]); 01128 usleep(1); 01129 ast_mutex_lock(&iaxsl[callno]); 01130 } else { 01131 ast_queue_frame(iaxs[callno]->owner, f); 01132 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01133 break; 01134 } 01135 } else 01136 break; 01137 } 01138 return 0; 01139 }
|
|
Definition at line 3116 of file chan_iax2.c. References ast_log(), and LOG_NOTICE. 03117 { 03118 static struct ast_frame f = { AST_FRAME_NULL, }; 03119 ast_log(LOG_NOTICE, "I should never be called!\n"); 03120 return &f; 03121 }
|
|
Definition at line 5492 of file chan_iax2.c. References iax2_registry::addr, ahp, ast_gethostbyname(), ast_log(), iax2_registry::callno, iax2_registry::expire, hp, IAX_DEFAULT_PORTNO, LOG_ERROR, LOG_WARNING, malloc, iax2_registry::next, iax2_registry::refresh, registrations, iax2_registry::secret, strsep(), and iax2_registry::username. Referenced by set_config(). 05493 { 05494 struct iax2_registry *reg; 05495 char copy[256]; 05496 char *username, *hostname, *secret; 05497 char *porta; 05498 char *stringp=NULL; 05499 05500 struct ast_hostent ahp; struct hostent *hp; 05501 if (!value) 05502 return -1; 05503 ast_copy_string(copy, value, sizeof(copy)); 05504 stringp=copy; 05505 username = strsep(&stringp, "@"); 05506 hostname = strsep(&stringp, "@"); 05507 if (!hostname) { 05508 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno); 05509 return -1; 05510 } 05511 stringp=username; 05512 username = strsep(&stringp, ":"); 05513 secret = strsep(&stringp, ":"); 05514 stringp=hostname; 05515 hostname = strsep(&stringp, ":"); 05516 porta = strsep(&stringp, ":"); 05517 05518 if (porta && !atoi(porta)) { 05519 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05520 return -1; 05521 } 05522 hp = ast_gethostbyname(hostname, &ahp); 05523 if (!hp) { 05524 ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno); 05525 return -1; 05526 } 05527 reg = malloc(sizeof(struct iax2_registry)); 05528 if (reg) { 05529 memset(reg, 0, sizeof(struct iax2_registry)); 05530 ast_copy_string(reg->username, username, sizeof(reg->username)); 05531 if (secret) 05532 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05533 reg->expire = -1; 05534 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05535 reg->addr.sin_family = AF_INET; 05536 memcpy(®->addr.sin_addr, hp->h_addr, sizeof(®->addr.sin_addr)); 05537 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05538 reg->next = registrations; 05539 reg->callno = 0; 05540 registrations = reg; 05541 } else { 05542 ast_log(LOG_ERROR, "Out of memory\n"); 05543 return -1; 05544 } 05545 return 0; 05546 }
|
|
Definition at line 8853 of file chan_iax2.c. References reload_config(). 08854 { 08855 return reload_config(); 08856 }
|
|
Definition at line 7848 of file chan_iax2.c. References ast_best_codec(), 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_info::capability, create_addr(), find_callno(), fmt, globalflags, chan_iax2_pvt::host, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat. 07849 { 07850 int callno; 07851 int res; 07852 int fmt, native; 07853 struct sockaddr_in sin; 07854 struct ast_channel *c; 07855 struct parsed_dial_string pds; 07856 struct create_addr_info cai; 07857 char *tmpstr; 07858 07859 memset(&pds, 0, sizeof(pds)); 07860 tmpstr = ast_strdupa(data); 07861 parse_dial_string(tmpstr, &pds); 07862 07863 memset(&cai, 0, sizeof(cai)); 07864 cai.capability = iax2_capability; 07865 07866 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07867 07868 if (!pds.peer) { 07869 ast_log(LOG_WARNING, "No peer given\n"); 07870 return NULL; 07871 } 07872 07873 07874 /* Populate our address from the given */ 07875 if (create_addr(pds.peer, &sin, &cai)) { 07876 *cause = AST_CAUSE_UNREGISTERED; 07877 return NULL; 07878 } 07879 07880 if (pds.port) 07881 sin.sin_port = htons(atoi(pds.port)); 07882 07883 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07884 if (callno < 1) { 07885 ast_log(LOG_WARNING, "Unable to create call\n"); 07886 *cause = AST_CAUSE_CONGESTION; 07887 return NULL; 07888 } 07889 07890 ast_mutex_lock(&iaxsl[callno]); 07891 07892 /* If this is a trunk, update it now */ 07893 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07894 if (ast_test_flag(&cai, IAX_TRUNK)) 07895 callno = make_trunk(callno, 1); 07896 iaxs[callno]->maxtime = cai.maxtime; 07897 if (cai.found) 07898 ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host)); 07899 07900 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 07901 07902 ast_mutex_unlock(&iaxsl[callno]); 07903 07904 if (c) { 07905 /* Choose a format we can live with */ 07906 if (c->nativeformats & format) 07907 c->nativeformats &= format; 07908 else { 07909 native = c->nativeformats; 07910 fmt = format; 07911 res = ast_translator_best_choice(&fmt, &native); 07912 if (res < 0) { 07913 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 07914 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 07915 ast_hangup(c); 07916 return NULL; 07917 } 07918 c->nativeformats = native; 07919 } 07920 c->readformat = ast_best_codec(c->nativeformats); 07921 c->writeformat = c->readformat; 07922 } 07923 07924 return c; 07925 }
|
|
Definition at line 3948 of file chan_iax2.c. References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, 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, chan_iax2_pvt::ecx, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, 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, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, 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(). 03949 { 03950 /* Queue a packet for delivery on a given private structure. Use "ts" for 03951 timestamp, or calculate if ts is 0. Send immediately without retransmission 03952 or delayed, with retransmission */ 03953 struct ast_iax2_full_hdr *fh; 03954 struct ast_iax2_mini_hdr *mh; 03955 struct ast_iax2_video_hdr *vh; 03956 struct { 03957 struct iax_frame fr2; 03958 unsigned char buffer[4096]; 03959 } frb; 03960 struct iax_frame *fr; 03961 int res; 03962 int sendmini=0; 03963 unsigned int lastsent; 03964 unsigned int fts; 03965 03966 if (!pvt) { 03967 ast_log(LOG_WARNING, "No private structure for packet?\n"); 03968 return -1; 03969 } 03970 03971 lastsent = pvt->lastsent; 03972 03973 /* Calculate actual timestamp */ 03974 fts = calc_timestamp(pvt, ts, f); 03975 03976 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 03977 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 03978 * increment the "predicted timestamps" for voice, if we're predecting */ 03979 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 03980 return 0; 03981 03982 03983 if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L))) 03984 /* High two bytes are the same on timestamp, or sending on a trunk */ && 03985 (f->frametype == AST_FRAME_VOICE) 03986 /* is a voice frame */ && 03987 (f->subclass == pvt->svoiceformat) 03988 /* is the same type */ ) { 03989 /* Force immediate rather than delayed transmission */ 03990 now = 1; 03991 /* Mark that mini-style frame is appropriate */ 03992 sendmini = 1; 03993 } 03994 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 03995 (f->frametype == AST_FRAME_VIDEO) && 03996 ((f->subclass & ~0x1) == pvt->svideoformat)) { 03997 now = 1; 03998 sendmini = 1; 03999 } 04000 /* Allocate an iax_frame */ 04001 if (now) { 04002 fr = &frb.fr2; 04003 } else 04004 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen); 04005 if (!fr) { 04006 ast_log(LOG_WARNING, "Out of memory\n"); 04007 return -1; 04008 } 04009 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04010 iax_frame_wrap(fr, f); 04011 04012 fr->ts = fts; 04013 fr->callno = pvt->callno; 04014 fr->transfer = transfer; 04015 fr->final = final; 04016 if (!sendmini) { 04017 /* We need a full frame */ 04018 if (seqno > -1) 04019 fr->oseqno = seqno; 04020 else 04021 fr->oseqno = pvt->oseqno++; 04022 fr->iseqno = pvt->iseqno; 04023 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04024 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04025 fh->ts = htonl(fr->ts); 04026 fh->oseqno = fr->oseqno; 04027 if (transfer) { 04028 fh->iseqno = 0; 04029 } else 04030 fh->iseqno = fr->iseqno; 04031 /* Keep track of the last thing we've acknowledged */ 04032 if (!transfer) 04033 pvt->aseqno = fr->iseqno; 04034 fh->type = fr->af.frametype & 0xFF; 04035 if (fr->af.frametype == AST_FRAME_VIDEO) 04036 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04037 else 04038 fh->csub = compress_subclass(fr->af.subclass); 04039 if (transfer) { 04040 fr->dcallno = pvt->transfercallno; 04041 } else 04042 fr->dcallno = pvt->peercallno; 04043 fh->dcallno = htons(fr->dcallno); 04044 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04045 fr->data = fh; 04046 fr->retries = 0; 04047 /* Retry after 2x the ping time has passed */ 04048 fr->retrytime = pvt->pingtime * 2; 04049 if (fr->retrytime < MIN_RETRY_TIME) 04050 fr->retrytime = MIN_RETRY_TIME; 04051 if (fr->retrytime > MAX_RETRY_TIME) 04052 fr->retrytime = MAX_RETRY_TIME; 04053 /* Acks' don't get retried */ 04054 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04055 fr->retries = -1; 04056 else if (f->frametype == AST_FRAME_VOICE) 04057 pvt->svoiceformat = f->subclass; 04058 else if (f->frametype == AST_FRAME_VIDEO) 04059 pvt->svideoformat = f->subclass & ~0x1; 04060 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04061 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04062 if (iaxdebug) { 04063 if (fr->transfer) 04064 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04065 else 04066 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04067 } 04068 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04069 } else 04070 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04071 } 04072 04073 if (now) { 04074 res = send_packet(fr); 04075 } else 04076 res = iax2_transmit(fr); 04077 } else { 04078 if (ast_test_flag(pvt, IAX_TRUNK)) { 04079 iax2_trunk_queue(pvt, fr); 04080 res = 0; 04081 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04082 /* Video frame have no sequence number */ 04083 fr->oseqno = -1; 04084 fr->iseqno = -1; 04085 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04086 vh->zeros = 0; 04087 vh->callno = htons(0x8000 | fr->callno); 04088 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04089 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04090 fr->data = vh; 04091 fr->retries = -1; 04092 res = send_packet(fr); 04093 } else { 04094 /* Mini-frames have no sequence number */ 04095 fr->oseqno = -1; 04096 fr->iseqno = -1; 04097 /* Mini frame will do */ 04098 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04099 mh->callno = htons(fr->callno); 04100 mh->ts = htons(fr->ts & 0xFFFF); 04101 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04102 fr->data = mh; 04103 fr->retries = -1; 04104 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04105 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04106 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04107 } else 04108 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04109 } 04110 res = send_packet(fr); 04111 } 04112 } 04113 return res; 04114 }
|
|
Definition at line 2547 of file chan_iax2.c. References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 02548 { 02549 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02550 }
|
|
Definition at line 2542 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. 02543 { 02544 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02545 }
|
|
Definition at line 2535 of file chan_iax2.c. References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and text. 02536 { 02537 02538 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02539 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02540 }
|
|
Definition at line 1783 of file chan_iax2.c. References ast_cli(), iaxs, and max_jitter_buffer. 01784 { 01785 #ifdef NEWJB 01786 ast_cli(fd, "sorry, this command is deprecated\n"); 01787 return RESULT_SUCCESS; 01788 #else 01789 if ((argc != 4) && (argc != 5)) 01790 return RESULT_SHOWUSAGE; 01791 if (argc == 4) { 01792 max_jitter_buffer = atoi(argv[3]); 01793 if (max_jitter_buffer < 0) 01794 max_jitter_buffer = 0; 01795 } else { 01796 if (argc == 5) { 01797 if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) { 01798 if (iaxs[atoi(argv[3])]) { 01799 iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]); 01800 if (iaxs[atoi(argv[3])]->jitterbuffer < 0) 01801 iaxs[atoi(argv[3])]->jitterbuffer = 0; 01802 } else 01803 ast_cli(fd, "No such call '%d'\n", atoi(argv[3])); 01804 } else 01805 ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3])); 01806 } 01807 } 01808 return RESULT_SUCCESS; 01809 #endif 01810 }
|
|
Definition at line 3087 of file chan_iax2.c. References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_log(), AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_option_header::flag, free, LOG_WARNING, malloc, ast_option_header::option, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03088 { 03089 struct ast_option_header *h; 03090 int res; 03091 03092 switch (option) { 03093 case AST_OPTION_TXGAIN: 03094 case AST_OPTION_RXGAIN: 03095 /* these two cannot be sent, because they require a result */ 03096 errno = ENOSYS; 03097 return -1; 03098 default: 03099 h = malloc(datalen + sizeof(*h)); 03100 if (h) { 03101 h->flag = AST_OPTION_FLAG_REQUEST; 03102 h->option = htons(option); 03103 memcpy(h->data, data, datalen); 03104 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03105 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03106 datalen + sizeof(*h), -1); 03107 free(h); 03108 return res; 03109 } else { 03110 ast_log(LOG_WARNING, "Out of memory\n"); 03111 return -1; 03112 } 03113 } 03114 }
|
|
Definition at line 2016 of file chan_iax2.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, s, tv, and iax2_dpcache::waiters. 02017 { 02018 struct iax2_dpcache *dp; 02019 char tmp[1024], *pc; 02020 int s; 02021 int x,y; 02022 struct timeval tv; 02023 gettimeofday(&tv, NULL); 02024 ast_mutex_lock(&dpcache_lock); 02025 dp = dpcache; 02026 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02027 while(dp) { 02028 s = dp->expiry.tv_sec - tv.tv_sec; 02029 tmp[0] = '\0'; 02030 if (dp->flags & CACHE_FLAG_EXISTS) 02031 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02032 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02033 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02034 if (dp->flags & CACHE_FLAG_CANEXIST) 02035 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02036 if (dp->flags & CACHE_FLAG_PENDING) 02037 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02038 if (dp->flags & CACHE_FLAG_TIMEOUT) 02039 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02040 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02041 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02042 if (dp->flags & CACHE_FLAG_MATCHMORE) 02043 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02044 if (dp->flags & CACHE_FLAG_UNKNOWN) 02045 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02046 /* Trim trailing pipe */ 02047 if (!ast_strlen_zero(tmp)) 02048 tmp[strlen(tmp) - 1] = '\0'; 02049 else 02050 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02051 y=0; 02052 pc = strchr(dp->peercontext, '@'); 02053 if (!pc) 02054 pc = dp->peercontext; 02055 else 02056 pc++; 02057 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02058 if (dp->waiters[x] > -1) 02059 y++; 02060 if (s > 0) 02061 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02062 else 02063 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02064 dp = dp->next; 02065 } 02066 ast_mutex_unlock(&dpcache_lock); 02067 return RESULT_SUCCESS; 02068 }
|
|
Definition at line 4399 of file chan_iax2.c. References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::bridgecallno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, FORMATB, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, and chan_iax2_pvt::remote_rr. 04400 { 04401 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04402 #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" 04403 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04404 int x; 04405 int numchans = 0; 04406 char iabuf[INET_ADDRSTRLEN]; 04407 04408 if (argc != 3) 04409 return RESULT_SHOWUSAGE; 04410 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04411 for (x=0;x<IAX_MAX_CALLS;x++) { 04412 ast_mutex_lock(&iaxsl[x]); 04413 if (iaxs[x]) { 04414 #ifdef BRIDGE_OPTIMIZATION 04415 if (iaxs[x]->bridgecallno) 04416 ast_cli(fd, FORMATB, 04417 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04418 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04419 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04420 iaxs[x]->callno, iaxs[x]->peercallno, 04421 iaxs[x]->oseqno, iaxs[x]->iseqno, 04422 iaxs[x]->bridgecallno ); 04423 else 04424 #endif 04425 { 04426 int lag, jitter, localdelay; 04427 #ifdef NEWJB 04428 jb_info jbinfo; 04429 04430 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04431 jb_getinfo(iaxs[x]->jb, &jbinfo); 04432 jitter = jbinfo.jitter; 04433 localdelay = jbinfo.current - jbinfo.min; 04434 } else { 04435 jitter = -1; 04436 localdelay = 0; 04437 } 04438 #else 04439 jitter = iaxs[x]->jitter; 04440 localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0; 04441 #endif 04442 lag = iaxs[x]->remote_rr.delay; 04443 ast_cli(fd, FORMAT, 04444 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04445 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04446 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04447 iaxs[x]->callno, iaxs[x]->peercallno, 04448 iaxs[x]->oseqno, iaxs[x]->iseqno, 04449 lag, 04450 jitter, 04451 localdelay, 04452 ast_getformatname(iaxs[x]->voiceformat) ); 04453 } 04454 numchans++; 04455 } 04456 ast_mutex_unlock(&iaxsl[x]); 04457 } 04458 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04459 return RESULT_SUCCESS; 04460 #undef FORMAT 04461 #undef FORMAT2 04462 #undef FORMATB 04463 }
|
|
Definition at line 4296 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, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl. 04297 { 04298 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04299 #if !defined(__FreeBSD__) 04300 #define FORMAT "%-15.15s %-15d %-15d\n" 04301 #else /* __FreeBSD__ */ 04302 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04303 #endif /* __FreeBSD__ */ 04304 struct iax_firmware *cur; 04305 if ((argc != 3) && (argc != 4)) 04306 return RESULT_SHOWUSAGE; 04307 ast_mutex_lock(&waresl.lock); 04308 04309 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04310 for (cur = waresl.wares;cur;cur = cur->next) { 04311 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04312 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04313 (int)ntohl(cur->fwh->datalen)); 04314 } 04315 ast_mutex_unlock(&waresl.lock); 04316 return RESULT_SUCCESS; 04317 #undef FORMAT 04318 #undef FORMAT2 04319 }
|
|
Definition at line 4545 of file chan_iax2.c. References ast_cli(), and ast_cli_netstats(). 04546 { 04547 int numchans = 0; 04548 if (argc != 3) 04549 return RESULT_SHOWUSAGE; 04550 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04551 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04552 numchans = ast_cli_netstats(fd, 1); 04553 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04554 return RESULT_SUCCESS; 04555 }
|
|
Definition at line 1912 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, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username. 01913 { 01914 char status[30]; 01915 char cbuf[256]; 01916 char iabuf[INET_ADDRSTRLEN]; 01917 struct iax2_peer *peer; 01918 char codec_buf[512]; 01919 int x = 0, codec = 0, load_realtime = 0; 01920 01921 if (argc < 4) 01922 return RESULT_SHOWUSAGE; 01923 01924 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 01925 01926 peer = find_peer(argv[3], load_realtime); 01927 if (peer) { 01928 ast_cli(fd,"\n\n"); 01929 ast_cli(fd, " * Name : %s\n", peer->name); 01930 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 01931 ast_cli(fd, " Context : %s\n", peer->context); 01932 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 01933 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 01934 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 01935 ast_cli(fd, " Expire : %d\n", peer->expire); 01936 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 01937 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)); 01938 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 01939 ast_cli(fd, " Username : %s\n", peer->username); 01940 ast_cli(fd, " Codecs : "); 01941 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 01942 ast_cli(fd, "%s\n", codec_buf); 01943 01944 ast_cli(fd, " Codec Order : ("); 01945 for(x = 0; x < 32 ; x++) { 01946 codec = ast_codec_pref_index(&peer->prefs,x); 01947 if(!codec) 01948 break; 01949 ast_cli(fd, "%s", ast_getformatname(codec)); 01950 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 01951 ast_cli(fd, "|"); 01952 } 01953 01954 if (!x) 01955 ast_cli(fd, "none"); 01956 ast_cli(fd, ")\n"); 01957 01958 ast_cli(fd, " Status : "); 01959 peer_status(peer, status, sizeof(status)); 01960 ast_cli(fd, "%s\n",status); 01961 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 01962 ast_cli(fd,"\n"); 01963 if (ast_test_flag(peer, IAX_TEMPONLY)) 01964 destroy_peer(peer); 01965 } else { 01966 ast_cli(fd,"Peer %s not found.\n", argv[3]); 01967 ast_cli(fd,"\n"); 01968 } 01969 01970 return RESULT_SUCCESS; 01971 }
|
|
Definition at line 4285 of file chan_iax2.c. References __iax2_show_peers(). 04286 { 04287 return __iax2_show_peers(0, fd, argc, argv); 04288 }
|
|
Definition at line 4357 of file chan_iax2.c. References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), FORMAT, FORMAT2, ast_peer_list::lock, iax2_registry::next, peerl, iax2_registry::refresh, regstate2str(), iax2_registry::us, and iax2_registry::username. 04358 { 04359 #define FORMAT2 "%-20.20s %-10.10s %-20.20s %8.8s %s\n" 04360 #define FORMAT "%-20.20s %-10.10s %-20.20s %8d %s\n" 04361 struct iax2_registry *reg; 04362 char host[80]; 04363 char perceived[80]; 04364 char iabuf[INET_ADDRSTRLEN]; 04365 if (argc != 3) 04366 return RESULT_SHOWUSAGE; 04367 ast_mutex_lock(&peerl.lock); 04368 ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State"); 04369 for (reg = registrations;reg;reg = reg->next) { 04370 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04371 if (reg->us.sin_addr.s_addr) 04372 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 04373 else 04374 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04375 ast_cli(fd, FORMAT, host, 04376 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04377 } 04378 ast_mutex_unlock(&peerl.lock); 04379 return RESULT_SUCCESS; 04380 #undef FORMAT 04381 #undef FORMAT2 04382 }
|
|
Definition at line 1996 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, and iax_frame::retries. 01997 { 01998 struct iax_frame *cur; 01999 int cnt = 0, dead=0, final=0; 02000 if (argc != 3) 02001 return RESULT_SHOWUSAGE; 02002 for (cur = iaxq.head; cur ; cur = cur->next) { 02003 if (cur->retries < 0) 02004 dead++; 02005 if (cur->final) 02006 final++; 02007 cnt++; 02008 } 02009 ast_cli(fd, " IAX Statistics\n"); 02010 ast_cli(fd, "---------------------\n"); 02011 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02012 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt); 02013 return RESULT_SUCCESS; 02014 }
|
|
Definition at line 4118 of file chan_iax2.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, context, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, ast_user_list::lock, iax2_user::name, iax2_user::next, iax2_user::secret, userl, and ast_user_list::users. 04119 { 04120 regex_t regexbuf; 04121 int havepattern = 0; 04122 04123 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04124 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04125 04126 struct iax2_user *user; 04127 char auth[90]; 04128 char *pstr = ""; 04129 04130 switch (argc) { 04131 case 5: 04132 if (!strcasecmp(argv[3], "like")) { 04133 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04134 return RESULT_SHOWUSAGE; 04135 havepattern = 1; 04136 } else 04137 return RESULT_SHOWUSAGE; 04138 case 3: 04139 break; 04140 default: 04141 return RESULT_SHOWUSAGE; 04142 } 04143 04144 ast_mutex_lock(&userl.lock); 04145 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04146 for(user=userl.users;user;user=user->next) { 04147 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04148 continue; 04149 04150 if (!ast_strlen_zero(user->secret)) { 04151 ast_copy_string(auth,user->secret,sizeof(auth)); 04152 } else if (!ast_strlen_zero(user->inkeys)) { 04153 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04154 } else 04155 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04156 04157 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04158 pstr = "REQ Only"; 04159 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04160 pstr = "Disabled"; 04161 else 04162 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04163 04164 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04165 user->contexts ? user->contexts->context : context, 04166 user->ha ? "Yes" : "No", pstr); 04167 04168 } 04169 ast_mutex_unlock(&userl.lock); 04170 04171 if (havepattern) 04172 regfree(®exbuf); 04173 04174 return RESULT_SUCCESS; 04175 #undef FORMAT 04176 #undef FORMAT2 04177 }
|
|
Definition at line 3123 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, iaxs, and send_command(). Referenced by iax2_bridge(). 03124 { 03125 int res; 03126 struct iax_ie_data ied0; 03127 struct iax_ie_data ied1; 03128 unsigned int transferid = rand(); 03129 memset(&ied0, 0, sizeof(ied0)); 03130 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03131 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03132 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03133 03134 memset(&ied1, 0, sizeof(ied1)); 03135 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03136 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03137 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03138 03139 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03140 if (res) 03141 return -1; 03142 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03143 if (res) 03144 return -1; 03145 iaxs[callno0]->transferring = TRANSFER_BEGIN; 03146 iaxs[callno1]->transferring = TRANSFER_BEGIN; 03147 return 0; 03148 }
|
|
Definition at line 1843 of file chan_iax2.c. References test_losspct. 01844 { 01845 if (argc != 4) 01846 return RESULT_SHOWUSAGE; 01847 01848 test_losspct = atoi(argv[3]); 01849 01850 return RESULT_SUCCESS; 01851 }
|
|
Definition at line 3348 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, LOG_DEBUG, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt. 03349 { 03350 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03351 struct iax_ie_data ied; 03352 char tmp[256], *context; 03353 ast_copy_string(tmp, dest, sizeof(tmp)); 03354 context = strchr(tmp, '@'); 03355 if (context) { 03356 *context = '\0'; 03357 context++; 03358 } 03359 memset(&ied, 0, sizeof(ied)); 03360 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03361 if (context) 03362 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03363 if (option_debug) 03364 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03365 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03366 }
|
|
Definition at line 2502 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(). 02503 { 02504 /* Lock the queue and place this packet at the end */ 02505 fr->next = NULL; 02506 fr->prev = NULL; 02507 /* By setting this to 0, the network thread will send it for us, and 02508 queue retransmission if necessary */ 02509 fr->sentyet = 0; 02510 ast_mutex_lock(&iaxq.lock); 02511 if (!iaxq.head) { 02512 /* Empty queue */ 02513 iaxq.head = fr; 02514 iaxq.tail = fr; 02515 } else { 02516 /* Double link */ 02517 iaxq.tail->next = fr; 02518 fr->prev = iaxq.tail; 02519 iaxq.tail = fr; 02520 } 02521 iaxq.count++; 02522 ast_mutex_unlock(&iaxq.lock); 02523 /* Wake up the network thread */ 02524 pthread_kill(netthreadid, SIGURG); 02525 return 0; 02526 }
|
|
Definition at line 5974 of file chan_iax2.c. References iax2_trunk_peer::trunkact. Referenced by timing_read(). 05975 { 05976 /* Drop when trunk is about 5 seconds idle */ 05977 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 05978 return 1; 05979 return 0; 05980 }
|
|
Definition at line 3720 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_DEBUG, LOG_WARNING, 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(). 03721 { 03722 struct ast_frame *f; 03723 struct iax2_trunk_peer *tpeer; 03724 void *tmp, *ptr; 03725 struct ast_iax2_meta_trunk_entry *met; 03726 struct ast_iax2_meta_trunk_mini *mtm; 03727 char iabuf[INET_ADDRSTRLEN]; 03728 03729 f = &fr->af; 03730 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03731 if (tpeer) { 03732 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03733 /* Need to reallocate space */ 03734 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03735 tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE); 03736 if (tmp) { 03737 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03738 tpeer->trunkdata = tmp; 03739 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); 03740 } else { 03741 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)); 03742 ast_mutex_unlock(&tpeer->lock); 03743 return -1; 03744 } 03745 } else { 03746 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)); 03747 ast_mutex_unlock(&tpeer->lock); 03748 return -1; 03749 } 03750 } 03751 03752 /* Append to meta frame */ 03753 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03754 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03755 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03756 mtm->len = htons(f->datalen); 03757 mtm->mini.callno = htons(pvt->callno); 03758 mtm->mini.ts = htons(0xffff & fr->ts); 03759 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03760 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03761 } else { 03762 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03763 /* Store call number and length in meta header */ 03764 met->callno = htons(pvt->callno); 03765 met->len = htons(f->datalen); 03766 /* Advance pointers/decrease length past trunk entry header */ 03767 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03768 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03769 } 03770 /* Copy actual trunk data */ 03771 memcpy(ptr, f->data, f->datalen); 03772 tpeer->trunkdatalen += f->datalen; 03773 03774 tpeer->calls++; 03775 ast_mutex_unlock(&tpeer->lock); 03776 } 03777 return 0; 03778 }
|
|
Definition at line 5902 of file chan_iax2.c. References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate(). Referenced by socket_read(). 05903 { 05904 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 05905 }
|
|
Definition at line 4616 of file chan_iax2.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::error, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, LOG_DEBUG, PTR_TO_CALLNO, and ast_channel::tech_pvt. 04617 { 04618 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04619 int res = -1; 04620 ast_mutex_lock(&iaxsl[callno]); 04621 if (iaxs[callno]) { 04622 /* If there's an outstanding error, return failure now */ 04623 if (!iaxs[callno]->error) { 04624 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04625 res = 0; 04626 /* Don't waste bandwidth sending null frames */ 04627 else if (f->frametype == AST_FRAME_NULL) 04628 res = 0; 04629 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04630 res = 0; 04631 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04632 res = 0; 04633 else 04634 /* Simple, just queue for transmission */ 04635 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04636 } else { 04637 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04638 } 04639 } 04640 /* If it's already gone, just return */ 04641 ast_mutex_unlock(&iaxsl[callno]); 04642 return res; 04643 }
|
|
Definition at line 1298 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(). 01299 { 01300 int res = 0; 01301 struct iax_firmware *cur; 01302 if (!ast_strlen_zero(dev)) { 01303 ast_mutex_lock(&waresl.lock); 01304 cur = waresl.wares; 01305 while(cur) { 01306 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01307 res = ntohs(cur->fwh->version); 01308 break; 01309 } 01310 cur = cur->next; 01311 } 01312 ast_mutex_unlock(&waresl.lock); 01313 } 01314 return res; 01315 }
|
|
Definition at line 658 of file chan_iax2.c. References ast_verbose(). Referenced by load_module(). 00659 { 00660 if (iaxdebug) 00661 ast_verbose("%s", data); 00662 }
|
|
Definition at line 664 of file chan_iax2.c. References ast_log(), and LOG_WARNING. Referenced by load_module(). 00665 { 00666 ast_log(LOG_WARNING, "%s", data); 00667 }
|
|
Definition at line 1317 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, desc, 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(). 01318 { 01319 int res = -1; 01320 unsigned int bs = desc & 0xff; 01321 unsigned int start = (desc >> 8) & 0xffffff; 01322 unsigned int bytes; 01323 struct iax_firmware *cur; 01324 if (!ast_strlen_zero((char *)dev) && bs) { 01325 start *= bs; 01326 ast_mutex_lock(&waresl.lock); 01327 cur = waresl.wares; 01328 while(cur) { 01329 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01330 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01331 if (start < ntohl(cur->fwh->datalen)) { 01332 bytes = ntohl(cur->fwh->datalen) - start; 01333 if (bytes > bs) 01334 bytes = bs; 01335 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01336 } else { 01337 bytes = 0; 01338 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01339 } 01340 if (bytes == bs) 01341 res = 0; 01342 else 01343 res = 1; 01344 break; 01345 } 01346 cur = cur->next; 01347 } 01348 ast_mutex_unlock(&waresl.lock); 01349 } 01350 return res; 01351 }
|
|
Definition at line 6153 of file chan_iax2.c. References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create, iax_dual::chan1, 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(). 06154 { 06155 struct iax_dual *d; 06156 struct ast_channel *chan1m, *chan2m; 06157 pthread_t th; 06158 chan1m = ast_channel_alloc(0); 06159 chan2m = ast_channel_alloc(0); 06160 if (chan2m && chan1m) { 06161 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 06162 /* Make formats okay */ 06163 chan1m->readformat = chan1->readformat; 06164 chan1m->writeformat = chan1->writeformat; 06165 ast_channel_masquerade(chan1m, chan1); 06166 /* Setup the extensions and such */ 06167 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06168 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06169 chan1m->priority = chan1->priority; 06170 06171 /* We make a clone of the peer channel too, so we can play 06172 back the announcement */ 06173 snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name); 06174 /* Make formats okay */ 06175 chan2m->readformat = chan2->readformat; 06176 chan2m->writeformat = chan2->writeformat; 06177 ast_channel_masquerade(chan2m, chan2); 06178 /* Setup the extensions and such */ 06179 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06180 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06181 chan2m->priority = chan2->priority; 06182 if (ast_do_masquerade(chan2m)) { 06183 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06184 ast_hangup(chan2m); 06185 return -1; 06186 } 06187 } else { 06188 if (chan1m) 06189 ast_hangup(chan1m); 06190 if (chan2m) 06191 ast_hangup(chan2m); 06192 return -1; 06193 } 06194 d = malloc(sizeof(struct iax_dual)); 06195 if (d) { 06196 memset(d, 0, sizeof(*d)); 06197 d->chan1 = chan1m; 06198 d->chan2 = chan2m; 06199 if (!ast_pthread_create(&th, NULL, iax_park_thread, d)) 06200 return 0; 06201 free(d); 06202 } 06203 return -1; 06204 }
|
|
Definition at line 6133 of file chan_iax2.c. References ast_frfree(), ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, free, and LOG_NOTICE. Referenced by iax_park(). 06134 { 06135 struct ast_channel *chan1, *chan2; 06136 struct iax_dual *d; 06137 struct ast_frame *f; 06138 int ext; 06139 int res; 06140 d = stuff; 06141 chan1 = d->chan1; 06142 chan2 = d->chan2; 06143 free(d); 06144 f = ast_read(chan1); 06145 if (f) 06146 ast_frfree(f); 06147 res = ast_park_call(chan1, chan2, 0, &ext); 06148 ast_hangup(chan2); 06149 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06150 return NULL; 06151 }
|
|
Definition at line 925 of file chan_iax2.c. References iax_frame::af, iax_frame::data, iax_frame::datalen, ast_frame::datalen, iax_frame::direction, DIRECTION_INGRESS, iax_frame_new(), iax_frame_wrap(), and iax_frame::retrans. Referenced by socket_read(). 00926 { 00927 /* Malloc() a copy of a frame */ 00928 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen); 00929 if (new) { 00930 memcpy(new, fr, sizeof(struct iax_frame)); 00931 iax_frame_wrap(new, &fr->af); 00932 new->data = NULL; 00933 new->datalen = 0; 00934 new->direction = DIRECTION_INGRESS; 00935 new->retrans = -1; 00936 } 00937 return new; 00938 }
|
|
Definition at line 694 of file chan_iax2.c. References ast_verbose(), and fmt. Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug(). 00695 { 00696 va_list args; 00697 char buf[1024]; 00698 00699 va_start(args, fmt); 00700 vsnprintf(buf, 1024, fmt, args); 00701 va_end(args); 00702 00703 ast_verbose(buf); 00704 }
|
|
Definition at line 670 of file chan_iax2.c. References ast_log(), fmt, and LOG_ERROR. Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module(). 00671 { 00672 va_list args; 00673 char buf[1024]; 00674 00675 va_start(args, fmt); 00676 vsnprintf(buf, 1024, fmt, args); 00677 va_end(args); 00678 00679 ast_log(LOG_ERROR, buf); 00680 }
|
|
Definition at line 682 of file chan_iax2.c. References ast_log(), fmt, and LOG_WARNING. Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module(). 00683 { 00684 va_list args; 00685 char buf[1024]; 00686 00687 va_start(args, fmt); 00688 vsnprintf(buf, 1024, fmt, args); 00689 va_end(args); 00690 00691 ast_log(LOG_WARNING, buf); 00692 }
|
|
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 9656 of file chan_iax2.c. 09657 {
09658 return ASTERISK_GPL_KEY;
09659 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 9535 of file chan_iax2.c. References __unload_module(), ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_bindaddr(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_register_application(), ast_register_switch(), ast_verbose(), channeltype, defaultsockfd, iax2_cli, iax2_do_register(), iax2_poke_peer(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), IAX_DEFAULT_PORTNO, iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), netsock, iax2_peer::next, iax2_registry::next, option_verbose, papp, pdescrip, peerl, ast_peer_list::peers, psyn, reload_firmware(), sched, sched_context_create(), set_config(), socket_read(), iax2_peer::sockfd, start_network_thread(), timingfd, tos, userl, VERBOSE_PREFIX_2, and waresl. 09536 { 09537 char *config = "iax.conf"; 09538 int res = 0; 09539 int x; 09540 struct iax2_registry *reg; 09541 struct iax2_peer *peer; 09542 09543 struct ast_netsock *ns; 09544 struct sockaddr_in sin; 09545 09546 ast_custom_function_register(&iaxpeer_function); 09547 09548 iax_set_output(iax_debug_output); 09549 iax_set_error(iax_error_output); 09550 #ifdef NEWJB 09551 jb_setoutput(jb_error_output, jb_warning_output, NULL); 09552 #endif 09553 09554 sin.sin_family = AF_INET; 09555 sin.sin_port = htons(IAX_DEFAULT_PORTNO); 09556 sin.sin_addr.s_addr = INADDR_ANY; 09557 09558 #ifdef IAX_TRUNKING 09559 #ifdef ZT_TIMERACK 09560 timingfd = open("/dev/zap/timer", O_RDWR); 09561 if (timingfd < 0) 09562 #endif 09563 timingfd = open("/dev/zap/pseudo", O_RDWR); 09564 if (timingfd < 0) 09565 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 09566 #endif 09567 09568 memset(iaxs, 0, sizeof(iaxs)); 09569 09570 for (x=0;x<IAX_MAX_CALLS;x++) 09571 ast_mutex_init(&iaxsl[x]); 09572 09573 io = io_context_create(); 09574 sched = sched_context_create(); 09575 09576 if (!io || !sched) { 09577 ast_log(LOG_ERROR, "Out of memory\n"); 09578 return -1; 09579 } 09580 09581 netsock = ast_netsock_list_alloc(); 09582 if (!netsock) { 09583 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 09584 return -1; 09585 } 09586 ast_netsock_init(netsock); 09587 09588 ast_mutex_init(&iaxq.lock); 09589 ast_mutex_init(&userl.lock); 09590 ast_mutex_init(&peerl.lock); 09591 ast_mutex_init(&waresl.lock); 09592 09593 ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0])); 09594 09595 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 09596 09597 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 09598 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 09599 09600 set_config(config, 0); 09601 09602 if (ast_channel_register(&iax2_tech)) { 09603 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype); 09604 __unload_module(); 09605 return -1; 09606 } 09607 09608 if (ast_register_switch(&iax2_switch)) 09609 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 09610 09611 if (defaultsockfd < 0) { 09612 if (!(ns = ast_netsock_bindaddr(netsock, io, &sin, tos, socket_read, NULL))) { 09613 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09614 return -1; 09615 } else { 09616 if (option_verbose > 1) 09617 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", IAX_DEFAULT_PORTNO); 09618 defaultsockfd = ast_netsock_sockfd(ns); 09619 ast_netsock_unref(ns); 09620 } 09621 } 09622 09623 res = start_network_thread(); 09624 if (!res) { 09625 if (option_verbose > 1) 09626 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 09627 } else { 09628 ast_log(LOG_ERROR, "Unable to start network thread\n"); 09629 ast_netsock_release(netsock); 09630 } 09631 09632 for (reg = registrations; reg; reg = reg->next) 09633 iax2_do_register(reg); 09634 ast_mutex_lock(&peerl.lock); 09635 for (peer = peerl.peers; peer; peer = peer->next) { 09636 if (peer->sockfd < 0) 09637 peer->sockfd = defaultsockfd; 09638 iax2_poke_peer(peer, 0); 09639 } 09640 ast_mutex_unlock(&peerl.lock); 09641 reload_firmware(); 09642 iax_provision_reload(); 09643 return res; 09644 }
|
|
Definition at line 3150 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl. Referenced by iax2_bridge(). 03151 { 03152 ast_mutex_lock(&iaxsl[callno0]); 03153 while (ast_mutex_trylock(&iaxsl[callno1])) { 03154 ast_mutex_unlock(&iaxsl[callno0]); 03155 usleep(10); 03156 ast_mutex_lock(&iaxsl[callno0]); 03157 } 03158 }
|
|
Definition at line 992 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_DEBUG, LOG_WARNING, chan_iax2_pvt::oseqno, ping_time, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), update_max_nontrunk(), and update_max_trunk(). Referenced by iax2_request(), and socket_read(). 00993 { 00994 int x; 00995 int res= 0; 00996 struct timeval now; 00997 if (iaxs[callno]->oseqno) { 00998 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 00999 return -1; 01000 } 01001 if (callno & TRUNK_CALL_START) { 01002 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01003 return -1; 01004 } 01005 gettimeofday(&now, NULL); 01006 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01007 ast_mutex_lock(&iaxsl[x]); 01008 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01009 iaxs[x] = iaxs[callno]; 01010 iaxs[x]->callno = x; 01011 iaxs[callno] = NULL; 01012 /* Update the two timers that should have been started */ 01013 if (iaxs[x]->pingid > -1) 01014 ast_sched_del(sched, iaxs[x]->pingid); 01015 if (iaxs[x]->lagid > -1) 01016 ast_sched_del(sched, iaxs[x]->lagid); 01017 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01018 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01019 if (locked) 01020 ast_mutex_unlock(&iaxsl[callno]); 01021 res = x; 01022 if (!locked) 01023 ast_mutex_unlock(&iaxsl[x]); 01024 break; 01025 } 01026 ast_mutex_unlock(&iaxsl[x]); 01027 } 01028 if (x >= IAX_MAX_CALLS - 1) { 01029 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01030 return -1; 01031 } 01032 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01033 /* We move this call from a non-trunked to a trunked call */ 01034 update_max_trunk(); 01035 update_max_nontrunk(); 01036 return res; 01037 }
|
|
Definition at line 4289 of file chan_iax2.c. References ast_cli(), ast_cli_netstats(), mansession::fd, and s. Referenced by load_module(). 04290 { 04291 ast_cli_netstats(s->fd, 0); 04292 ast_cli(s->fd, "\r\n"); 04293 return RESULT_SUCCESS; 04294 }
|
|
Definition at line 4322 of file chan_iax2.c. References __iax2_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), mansession::fd, and s. Referenced by load_module(). 04323 { 04324 char *a[] = { "iax2", "show", "users" }; 04325 int ret; 04326 char *id; 04327 id = astman_get_header(m,"ActionID"); 04328 if (!ast_strlen_zero(id)) 04329 ast_cli(s->fd, "ActionID: %s\r\n",id); 04330 ret = __iax2_show_peers(1, s->fd, 3, a ); 04331 ast_cli(s->fd, "\r\n\r\n" ); 04332 return ret; 04333 } /* /JDG */
|
|
Definition at line 944 of file chan_iax2.c. References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, and chan_iax2_pvt::transfer. Referenced by find_callno(), and schedule_delivery(). 00945 { 00946 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 00947 (cur->addr.sin_port == sin->sin_port)) { 00948 /* This is the main host */ 00949 if ((cur->peercallno == callno) || 00950 ((dcallno == cur->callno) && !cur->peercallno)) { 00951 /* That's us. Be sure we keep track of the peer call number */ 00952 return 1; 00953 } 00954 } 00955 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 00956 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 00957 /* We're transferring */ 00958 if (dcallno == cur->callno) 00959 return 1; 00960 } 00961 return 0; 00962 }
|
|
Definition at line 3786 of file chan_iax2.c. References aes_decrypt(), ast_log(), and LOG_WARNING. Referenced by decode_frame(). 03787 { 03788 #if 0 03789 /* Debug with "fake encryption" */ 03790 int x; 03791 if (len % 16) 03792 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03793 for (x=0;x<len;x++) 03794 dst[x] = src[x] ^ 0xff; 03795 #else 03796 unsigned char lastblock[16] = { 0 }; 03797 int x; 03798 while(len > 0) { 03799 aes_decrypt(src, dst, dcx); 03800 for (x=0;x<16;x++) 03801 dst[x] ^= lastblock[x]; 03802 memcpy(lastblock, src, sizeof(lastblock)); 03803 dst += 16; 03804 src += 16; 03805 len -= 16; 03806 } 03807 #endif 03808 }
|
|
Definition at line 3810 of file chan_iax2.c. References aes_encrypt(), ast_log(), and LOG_WARNING. Referenced by encrypt_frame(). 03811 { 03812 #if 0 03813 /* Debug with "fake encryption" */ 03814 int x; 03815 if (len % 16) 03816 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03817 for (x=0;x<len;x++) 03818 dst[x] = src[x] ^ 0xff; 03819 #else 03820 unsigned char curblock[16] = { 0 }; 03821 int x; 03822 while(len > 0) { 03823 for (x=0;x<16;x++) 03824 curblock[x] ^= src[x]; 03825 aes_encrypt(curblock, dst, ecx); 03826 memcpy(curblock, dst, sizeof(curblock)); 03827 dst += 16; 03828 src += 16; 03829 len -= 16; 03830 } 03831 #endif 03832 }
|
|
Definition at line 4921 of file chan_iax2.c. References chan_iax2_pvt::encmethods. Referenced by authenticate_reply(), and socket_read(). 04922 { 04923 /* Select exactly one common encryption if there are any */ 04924 p->encmethods &= enc; 04925 if (p->encmethods) { 04926 if (p->encmethods & IAX_ENCRYPT_AES128) 04927 p->encmethods = IAX_ENCRYPT_AES128; 04928 else 04929 p->encmethods = 0; 04930 } 04931 }
|
|
Definition at line 7927 of file chan_iax2.c. References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_runq(), ast_sched_wait(), attempt_transmit(), iax_frame::callno, ast_iax2_queue::count, ast_iax2_queue::head, iax_frame_free(), iaxq, iaxs, io, ast_iax2_queue::lock, LOG_DEBUG, iax_frame::next, iax_frame::prev, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), iax_frame::sentyet, ast_iax2_queue::tail, timing_read(), and timingfd. Referenced by start_network_thread(). 07928 { 07929 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 07930 from the network, and queue them for delivery to the channels */ 07931 int res, count; 07932 struct iax_frame *f, *freeme; 07933 if (timingfd > -1) 07934 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 07935 for(;;) { 07936 /* Go through the queue, sending messages which have not yet been 07937 sent, and scheduling retransmissions if appropriate */ 07938 ast_mutex_lock(&iaxq.lock); 07939 f = iaxq.head; 07940 count = 0; 07941 while(f) { 07942 freeme = NULL; 07943 if (!f->sentyet) { 07944 f->sentyet++; 07945 /* Send a copy immediately -- errors here are ok, so don't bother locking */ 07946 if (iaxs[f->callno]) { 07947 send_packet(f); 07948 count++; 07949 } 07950 if (f->retries < 0) { 07951 /* This is not supposed to be retransmitted */ 07952 if (f->prev) 07953 f->prev->next = f->next; 07954 else 07955 iaxq.head = f->next; 07956 if (f->next) 07957 f->next->prev = f->prev; 07958 else 07959 iaxq.tail = f->prev; 07960 iaxq.count--; 07961 /* Free the iax frame */ 07962 freeme = f; 07963 } else { 07964 /* We need reliable delivery. Schedule a retransmission */ 07965 f->retries++; 07966 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 07967 } 07968 } 07969 f = f->next; 07970 if (freeme) 07971 iax_frame_free(freeme); 07972 } 07973 ast_mutex_unlock(&iaxq.lock); 07974 if (count >= 20) 07975 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 07976 07977 /* Now do the IO, and run scheduled tasks */ 07978 res = ast_sched_wait(sched); 07979 if ((res > 1000) || (res < 0)) 07980 res = 1000; 07981 res = ast_io_wait(io, res); 07982 if (res >= 0) { 07983 if (res >= 20) 07984 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 07985 count = ast_sched_runq(sched); 07986 if (count >= 20) 07987 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 07988 } 07989 } 07990 return NULL; 07991 }
|
|
Definition at line 890 of file chan_iax2.c. References chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, chan_iax2_pvt::exten, chan_iax2_pvt::host, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, malloc, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::prefs, jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno. Referenced by find_callno(). 00891 { 00892 struct chan_iax2_pvt *tmp; 00893 tmp = malloc(sizeof(struct chan_iax2_pvt)); 00894 if (tmp) { 00895 memset(tmp, 0, sizeof(struct chan_iax2_pvt)); 00896 tmp->prefs = prefs; 00897 tmp->callno = 0; 00898 tmp->peercallno = 0; 00899 tmp->transfercallno = 0; 00900 tmp->bridgecallno = 0; 00901 tmp->pingid = -1; 00902 tmp->lagid = -1; 00903 tmp->autoid = -1; 00904 tmp->authid = -1; 00905 tmp->initid = -1; 00906 /* ast_copy_string(tmp->context, context, sizeof(tmp->context)); */ 00907 ast_copy_string(tmp->exten, "s", sizeof(tmp->exten)); 00908 ast_copy_string(tmp->host, host, sizeof(tmp->host)); 00909 #ifdef NEWJB 00910 { 00911 jb_conf jbconf; 00912 00913 tmp->jb = jb_new(); 00914 tmp->jbid = -1; 00915 jbconf.max_jitterbuf = maxjitterbuffer; 00916 jbconf.resync_threshold = resyncthreshold; 00917 jbconf.max_contig_interp = maxjitterinterps; 00918 jb_setconf(tmp->jb,&jbconf); 00919 } 00920 #endif 00921 } 00922 return tmp; 00923 }
|
|
Parses an IAX dial string into its component parts.
Definition at line 2888 of file chan_iax2.c. References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username. Referenced by cache_get_callno_locked(), iax2_call(), and iax2_request(). 02889 { 02890 if (ast_strlen_zero(data)) 02891 return; 02892 02893 pds->peer = strsep(&data, "/"); 02894 pds->exten = strsep(&data, "/"); 02895 pds->options = data; 02896 02897 if (pds->exten) { 02898 data = pds->exten; 02899 pds->exten = strsep(&data, "@"); 02900 pds->context = data; 02901 } 02902 02903 if (strchr(pds->peer, '@')) { 02904 data = pds->peer; 02905 pds->username = strsep(&data, "@"); 02906 pds->peer = data; 02907 } 02908 02909 if (pds->username) { 02910 data = pds->username; 02911 pds->username = strsep(&data, ":"); 02912 pds->password = data; 02913 } 02914 02915 data = pds->peer; 02916 pds->peer = strsep(&data, ":"); 02917 pds->port = data; 02918 02919 /* check for a key name wrapped in [] in the secret position, if found, 02920 move it to the key field instead 02921 */ 02922 if (pds->password && (pds->password[0] == '[')) { 02923 pds->key = ast_strip_quoted(pds->password, "[", "]"); 02924 pds->password = NULL; 02925 } 02926 }
|
|
Definition at line 8052 of file chan_iax2.c. References ast_get_ip(), ast_log(), ast_netsock_find(), ast_netsock_sockfd(), ast_strdupa, check_srcaddr(), LOG_DEBUG, LOG_WARNING, iax2_peer::name, netsock, iax2_peer::sockfd, and strsep(). Referenced by build_peer(). 08053 { 08054 struct sockaddr_in sin; 08055 int nonlocal = 1; 08056 int port = IAX_DEFAULT_PORTNO; 08057 int sockfd = defaultsockfd; 08058 char *tmp; 08059 char *addr; 08060 char *portstr; 08061 08062 tmp = ast_strdupa(srcaddr); 08063 if (!tmp) { 08064 ast_log(LOG_WARNING, "Out of memory!\n"); 08065 return -1; 08066 } 08067 08068 addr = strsep(&tmp, ":"); 08069 portstr = tmp; 08070 08071 if (portstr) { 08072 port = atoi(portstr); 08073 if (port < 1) 08074 port = IAX_DEFAULT_PORTNO; 08075 } 08076 08077 if (!ast_get_ip(&sin, addr)) { 08078 struct ast_netsock *sock; 08079 int res; 08080 08081 sin.sin_port = 0; 08082 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08083 if (res == 0) { 08084 /* ip address valid. */ 08085 sin.sin_port = htons(port); 08086 sock = ast_netsock_find(netsock, &sin); 08087 if (sock) { 08088 sockfd = ast_netsock_sockfd(sock); 08089 nonlocal = 0; 08090 } 08091 } 08092 } 08093 08094 peer->sockfd = sockfd; 08095 08096 if (nonlocal) { 08097 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08098 srcaddr, peer->name); 08099 return -1; 08100 } else { 08101 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08102 return 0; 08103 } 08104 }
|
|
peer_status: Report Peer status in character string
Definition at line 1889 of file chan_iax2.c. References iax2_peer::lastms, and iax2_peer::maxms. 01890 { 01891 int res = 0; 01892 if (peer->maxms) { 01893 if (peer->lastms < 0) { 01894 ast_copy_string(status, "UNREACHABLE", statuslen); 01895 } else if (peer->lastms > peer->maxms) { 01896 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 01897 res = 1; 01898 } else if (peer->lastms) { 01899 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 01900 res = 1; 01901 } else { 01902 ast_copy_string(status, "UNKNOWN", statuslen); 01903 } 01904 } else { 01905 ast_copy_string(status, "Unmonitored", statuslen); 01906 res = -1; 01907 } 01908 return res; 01909 }
|
|
Definition at line 2190 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers. Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module(). 02191 { 02192 /* Prune peers who still are supposed to be deleted */ 02193 struct oh323_peer *peer, *peerlast, *peernext; 02194 ast_mutex_lock(&peerl.lock); 02195 peerlast = NULL; 02196 for (peer=peerl.peers;peer;) { 02197 peernext = peer->next; 02198 if (peer->delme) { 02199 free(peer); 02200 if (peerlast) { 02201 peerlast->next = peernext; 02202 } else { 02203 peerl.peers = peernext; 02204 } 02205 } else { 02206 peerlast = peer; 02207 } 02208 peer = peernext; 02209 } 02210 ast_mutex_unlock(&peerl.lock); 02211 }
|
|
Definition at line 8503 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, userl, and ast_user_list::users. 08504 { 08505 struct iax2_user *user, *usernext, *userlast = NULL; 08506 ast_mutex_lock(&userl.lock); 08507 for (user=userl.users;user;) { 08508 usernext = user->next; 08509 if (ast_test_flag(user, IAX_DELME)) { 08510 destroy_user(user); 08511 if (userlast) 08512 userlast->next = usernext; 08513 else 08514 userl.users = usernext; 08515 } else 08516 userlast = user; 08517 user = usernext; 08518 } 08519 ast_mutex_unlock(&userl.lock); 08520 }
|
|
Definition at line 4900 of file chan_iax2.c. References ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, LOG_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(). 04901 { 04902 struct ast_iax2_full_hdr fh; 04903 char iabuf[INET_ADDRSTRLEN]; 04904 fh.scallno = htons(src | IAX_FLAG_FULL); 04905 fh.dcallno = htons(dst); 04906 fh.ts = 0; 04907 fh.oseqno = 0; 04908 fh.iseqno = 0; 04909 fh.type = AST_FRAME_IAX; 04910 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 04911 if (iaxdebug) 04912 iax_showframe(NULL, &fh, 0, sin, 0); 04913 #if 0 04914 if (option_debug) 04915 #endif 04916 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 04917 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst); 04918 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 04919 }
|
|
Definition at line 2570 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(), iax2_peer::expire, expire_registry(), global_rtautoclear, globalflags, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, LOG_DEBUG, ast_variable::name, iax2_peer::next, ast_variable::next, peerl, ast_peer_list::peers, reg_source_db(), sched, ast_variable::value, and var. 02571 { 02572 struct ast_variable *var; 02573 struct ast_variable *tmp; 02574 struct iax2_peer *peer=NULL; 02575 time_t regseconds, nowtime; 02576 int dynamic=0; 02577 02578 if (peername) 02579 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02580 else { 02581 char iabuf[INET_ADDRSTRLEN]; 02582 char porta[25]; 02583 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 02584 sprintf(porta, "%d", ntohs(sin->sin_port)); 02585 var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL); 02586 if (var) { 02587 /* We'll need the peer name in order to build the structure! */ 02588 tmp = var; 02589 while(tmp) { 02590 if (!strcasecmp(tmp->name, "name")) 02591 peername = tmp->value; 02592 tmp = tmp->next; 02593 } 02594 } 02595 } 02596 if (!var) 02597 return NULL; 02598 02599 peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02600 02601 if (!peer) 02602 return NULL; 02603 02604 tmp = var; 02605 while(tmp) { 02606 /* Make sure it's not a user only... */ 02607 if (!strcasecmp(tmp->name, "type")) { 02608 if (strcasecmp(tmp->value, "friend") && 02609 strcasecmp(tmp->value, "peer")) { 02610 /* Whoops, we weren't supposed to exist! */ 02611 destroy_peer(peer); 02612 peer = NULL; 02613 break; 02614 } 02615 } else if (!strcasecmp(tmp->name, "regseconds")) { 02616 if (sscanf(tmp->value, "%ld", (time_t *)®seconds) != 1) 02617 regseconds = 0; 02618 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02619 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02620 } else if (!strcasecmp(tmp->name, "port")) { 02621 peer->addr.sin_port = htons(atoi(tmp->value)); 02622 } else if (!strcasecmp(tmp->name, "host")) { 02623 if (!strcasecmp(tmp->value, "dynamic")) 02624 dynamic = 1; 02625 } 02626 tmp = tmp->next; 02627 } 02628 if (!peer) 02629 return NULL; 02630 02631 ast_variables_destroy(var); 02632 02633 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02634 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02635 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02636 if (peer->expire > -1) 02637 ast_sched_del(sched, peer->expire); 02638 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer); 02639 } 02640 ast_mutex_lock(&peerl.lock); 02641 peer->next = peerl.peers; 02642 peerl.peers = peer; 02643 ast_mutex_unlock(&peerl.lock); 02644 if (ast_test_flag(peer, IAX_DYNAMIC)) 02645 reg_source_db(peer); 02646 } else { 02647 ast_set_flag(peer, IAX_TEMPONLY); 02648 } 02649 02650 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02651 time(&nowtime); 02652 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02653 memset(&peer->addr, 0, sizeof(peer->addr)); 02654 if (option_debug) 02655 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02656 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02657 } 02658 else { 02659 if (option_debug) 02660 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02661 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02662 } 02663 } 02664 02665 return peer; 02666 }
|
|
Definition at line 2709 of file chan_iax2.c. References ast_inet_ntoa(), and ast_update_realtime(). 02710 { 02711 char port[10]; 02712 char ipaddr[20]; 02713 char regseconds[20]; 02714 time_t nowtime; 02715 02716 time(&nowtime); 02717 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); 02718 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 02719 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02720 ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL); 02721 }
|
|
Definition at line 2668 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, iax2_user::next, ast_variable::next, userl, ast_user_list::users, ast_variable::value, and var. 02669 { 02670 struct ast_variable *var; 02671 struct ast_variable *tmp; 02672 struct iax2_user *user=NULL; 02673 02674 var = ast_load_realtime("iaxusers", "name", username, NULL); 02675 if (!var) 02676 return NULL; 02677 02678 tmp = var; 02679 while(tmp) { 02680 /* Make sure it's not a peer only... */ 02681 if (!strcasecmp(tmp->name, "type")) { 02682 if (strcasecmp(tmp->value, "friend") && 02683 strcasecmp(tmp->value, "user")) { 02684 return NULL; 02685 } 02686 } 02687 tmp = tmp->next; 02688 } 02689 02690 user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02691 if (!user) 02692 return NULL; 02693 02694 ast_variables_destroy(var); 02695 02696 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02697 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02698 ast_mutex_lock(&userl.lock); 02699 user->next = userl.users; 02700 userl.users = user; 02701 ast_mutex_unlock(&userl.lock); 02702 } else { 02703 ast_set_flag(user, IAX_TEMPONLY); 02704 } 02705 02706 return user; 02707 }
|
|
Definition at line 5595 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(), sched, and VERBOSE_PREFIX_3. 05596 { 05597 char data[80]; 05598 struct in_addr in; 05599 char iabuf[INET_ADDRSTRLEN]; 05600 char *c, *d; 05601 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05602 c = strchr(data, ':'); 05603 if (c) { 05604 *c = '\0'; 05605 c++; 05606 if (inet_aton(data, &in)) { 05607 d = strchr(c, ':'); 05608 if (d) { 05609 *d = '\0'; 05610 d++; 05611 if (option_verbose > 2) 05612 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05613 ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); 05614 iax2_poke_peer(p, 0); 05615 p->expiry = atoi(d); 05616 memset(&p->addr, 0, sizeof(p->addr)); 05617 p->addr.sin_family = AF_INET; 05618 p->addr.sin_addr = in; 05619 p->addr.sin_port = htons(atoi(c)); 05620 if (p->expire > -1) 05621 ast_sched_del(sched, p->expire); 05622 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05623 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05624 if (iax2_regfunk) 05625 iax2_regfunk(p->name, 1); 05626 register_peer_exten(p, 1); 05627 } 05628 05629 } 05630 } 05631 } 05632 }
|
|
Definition at line 5548 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(). 05549 { 05550 char multi[256]; 05551 char *stringp, *ext; 05552 if (!ast_strlen_zero(regcontext)) { 05553 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 05554 stringp = multi; 05555 while((ext = strsep(&stringp, "&"))) { 05556 if (onoff) { 05557 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05558 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype); 05559 } else 05560 ast_context_remove_extension(regcontext, ext, 1, NULL); 05561 } 05562 } 05563 }
|
|
Verify inbound registration.
Definition at line 5014 of file chan_iax2.c. References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_device_state_changed(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, chan_iax2_pvt::inkeys, iax2_peer::inkeys, key(), LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, chan_iax2_pvt::peer, iax_ies::refresh, iax_ies::rsa_result, chan_iax2_pvt::secret, iax2_peer::secret, strsep(), and iax_ies::username. 05015 { 05016 char requeststr[256] = ""; 05017 char peer[256] = ""; 05018 char md5secret[256] = ""; 05019 char rsasecret[256] = ""; 05020 char secret[256] = ""; 05021 char iabuf[INET_ADDRSTRLEN]; 05022 struct iax2_peer *p; 05023 struct ast_key *key; 05024 char *keyn; 05025 int x; 05026 int expire = 0; 05027 05028 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05029 iaxs[callno]->peer[0] = '\0'; 05030 if (ies->username) 05031 ast_copy_string(peer, ies->username, sizeof(peer)); 05032 if (ies->password) 05033 ast_copy_string(secret, ies->password, sizeof(secret)); 05034 if (ies->md5_result) 05035 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05036 if (ies->rsa_result) 05037 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05038 if (ies->refresh) 05039 expire = ies->refresh; 05040 05041 if (ast_strlen_zero(peer)) { 05042 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05043 return -1; 05044 } 05045 /* We release the lock for the call to prevent a deadlock, but it's okay because 05046 only the current thread could possibly make it go away or make changes */ 05047 ast_mutex_unlock(&iaxsl[callno]); 05048 /* SLD: first call to lookup peer during registration */ 05049 p = find_peer(peer, 1); 05050 ast_mutex_lock(&iaxsl[callno]); 05051 05052 if (!p) { 05053 if (authdebug) 05054 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05055 return -1; 05056 } 05057 05058 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05059 if (authdebug) 05060 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05061 if (ast_test_flag(p, IAX_TEMPONLY)) 05062 destroy_peer(p); 05063 return -1; 05064 } 05065 05066 if (!ast_apply_ha(p->ha, sin)) { 05067 if (authdebug) 05068 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); 05069 if (ast_test_flag(p, IAX_TEMPONLY)) 05070 destroy_peer(p); 05071 return -1; 05072 } 05073 ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret)); 05074 ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys)); 05075 /* Check secret against what we have on file */ 05076 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05077 if (!ast_strlen_zero(p->inkeys)) { 05078 char tmpkeys[256]; 05079 char *stringp=NULL; 05080 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05081 stringp=tmpkeys; 05082 keyn = strsep(&stringp, ":"); 05083 while(keyn) { 05084 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05085 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05086 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05087 break; 05088 } else if (!key) 05089 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05090 keyn = strsep(&stringp, ":"); 05091 } 05092 if (!keyn) { 05093 if (authdebug) 05094 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05095 if (ast_test_flag(p, IAX_TEMPONLY)) 05096 destroy_peer(p); 05097 return -1; 05098 } 05099 } else { 05100 if (authdebug) 05101 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05102 if (ast_test_flag(p, IAX_TEMPONLY)) 05103 destroy_peer(p); 05104 return -1; 05105 } 05106 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05107 /* They've provided a plain text password and we support that */ 05108 if (strcmp(secret, p->secret)) { 05109 if (authdebug) 05110 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); 05111 if (ast_test_flag(p, IAX_TEMPONLY)) 05112 destroy_peer(p); 05113 return -1; 05114 } else 05115 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05116 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05117 struct MD5Context md5; 05118 unsigned char digest[16]; 05119 char *tmppw, *stringp; 05120 05121 tmppw = ast_strdupa(p->secret); 05122 stringp = tmppw; 05123 while((tmppw = strsep(&stringp, ";"))) { 05124 MD5Init(&md5); 05125 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05126 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05127 MD5Final(digest, &md5); 05128 for (x=0;x<16;x++) 05129 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05130 if (!strcasecmp(requeststr, md5secret)) 05131 break; 05132 } 05133 if (tmppw) { 05134 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05135 } else { 05136 if (authdebug) 05137 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); 05138 if (ast_test_flag(p, IAX_TEMPONLY)) 05139 destroy_peer(p); 05140 return -1; 05141 } 05142 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05143 if (authdebug) 05144 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05145 if (ast_test_flag(p, IAX_TEMPONLY)) 05146 destroy_peer(p); 05147 return -1; 05148 } 05149 ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer)); 05150 /* Choose lowest expiry number */ 05151 if (expire && (expire < iaxs[callno]->expiry)) 05152 iaxs[callno]->expiry = expire; 05153 05154 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05155 05156 if (ast_test_flag(p, IAX_TEMPONLY)) 05157 destroy_peer(p); 05158 return 0; 05159 05160 }
|
|
Definition at line 5736 of file chan_iax2.c. References AST_FRAME_IAX, ast_log(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, IAX_TEMPONLY, iaxs, LOG_WARNING, name, and send_command(). Referenced by socket_read(). 05737 { 05738 struct iax_ie_data ied; 05739 struct iax2_peer *p; 05740 /* SLD: third call to find_peer in registration */ 05741 p = find_peer(name, 1); 05742 if (p) { 05743 memset(&ied, 0, sizeof(ied)); 05744 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05745 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 05746 /* Build the challenge */ 05747 snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand()); 05748 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 05749 } 05750 iax_ie_append_str(&ied, IAX_IE_USERNAME, name); 05751 if (ast_test_flag(p, IAX_TEMPONLY)) 05752 destroy_peer(p); 05753 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 05754 } 05755 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05756 return 0; 05757 }
|
|
Definition at line 5759 of file chan_iax2.c. References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username. Referenced by socket_read(). 05760 { 05761 struct iax2_registry *reg; 05762 /* Start pessimistic */ 05763 struct iax_ie_data ied; 05764 char peer[256] = ""; 05765 char iabuf[INET_ADDRSTRLEN]; 05766 char challenge[256] = ""; 05767 int res; 05768 int authmethods = 0; 05769 if (ies->authmethods) 05770 authmethods = ies->authmethods; 05771 if (ies->username) 05772 ast_copy_string(peer, ies->username, sizeof(peer)); 05773 if (ies->challenge) 05774 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 05775 memset(&ied, 0, sizeof(ied)); 05776 reg = iaxs[callno]->reg; 05777 if (reg) { 05778 if (inaddrcmp(®->addr, sin)) { 05779 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05780 return -1; 05781 } 05782 if (ast_strlen_zero(reg->secret)) { 05783 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 05784 reg->regstate = REG_STATE_NOAUTH; 05785 return -1; 05786 } 05787 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 05788 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 05789 if (reg->secret[0] == '[') { 05790 char tmpkey[256]; 05791 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 05792 tmpkey[strlen(tmpkey) - 1] = '\0'; 05793 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 05794 } else 05795 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 05796 if (!res) { 05797 reg->regstate = REG_STATE_AUTHSENT; 05798 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 05799 } else 05800 return -1; 05801 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 05802 } else 05803 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 05804 return -1; 05805 }
|
|
Definition at line 4335 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 iax2_show_registry(). 04336 { 04337 switch(regstate) { 04338 case REG_STATE_UNREGISTERED: 04339 return "Unregistered"; 04340 case REG_STATE_REGSENT: 04341 return "Request Sent"; 04342 case REG_STATE_AUTHSENT: 04343 return "Auth. Sent"; 04344 case REG_STATE_REGISTERED: 04345 return "Registered"; 04346 case REG_STATE_REJECTED: 04347 return "Rejected"; 04348 case REG_STATE_TIMEOUT: 04349 return "Timeout"; 04350 case REG_STATE_NOAUTH: 04351 return "No Authentication"; 04352 default: 04353 return "Unknown"; 04354 } 04355 }
|
|
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 8858 of file chan_iax2.c. References reload_config(). 08859 { 08860 return reload_config(); 08861 }
|
|
Definition at line 1999 of file chan_h323.c. References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, 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(), userbyalias, userl, ast_user_list::users, usingGk, ast_variable::value, and VERBOSE_PREFIX_2. Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), and reload(). 02000 { 02001 int format; 02002 struct ast_config *cfg; 02003 struct ast_variable *v; 02004 struct oh323_peer *peer = NULL; 02005 struct oh323_user *user = NULL; 02006 struct oh323_alias *alias = NULL; 02007 struct ast_hostent ahp; struct hostent *hp; 02008 char *cat; 02009 char *utype; 02010 02011 cfg = ast_config_load(config); 02012 02013 /* We *must* have a config file otherwise stop immediately */ 02014 if (!cfg) { 02015 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02016 return 1; 02017 } 02018 02019 /* fire up the H.323 Endpoint */ 02020 if (!h323_end_point_exist()) { 02021 h323_end_point_create(); 02022 } 02023 h323debug = 0; 02024 memset(&bindaddr, 0, sizeof(bindaddr)); 02025 memset(&global_options, 0, sizeof(global_options)); 02026 global_options.dtmfcodec = 101; 02027 global_options.dtmfmode = H323_DTMF_RFC2833; 02028 global_options.capability = ~0; /* All capabilities */ 02029 global_options.bridge = 1; /* Do native bridging by default */ 02030 v = ast_variable_browse(cfg, "general"); 02031 while(v) { 02032 /* Create the interface list */ 02033 if (!strcasecmp(v->name, "port")) { 02034 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02035 } else if (!strcasecmp(v->name, "bindaddr")) { 02036 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02037 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02038 } else { 02039 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02040 } 02041 } else if (!strcasecmp(v->name, "tos")) { 02042 if (sscanf(v->value, "%d", &format)) { 02043 tos = format & 0xff; 02044 } else if (!strcasecmp(v->value, "lowdelay")) { 02045 tos = IPTOS_LOWDELAY; 02046 } else if (!strcasecmp(v->value, "throughput")) { 02047 tos = IPTOS_THROUGHPUT; 02048 } else if (!strcasecmp(v->value, "reliability")) { 02049 tos = IPTOS_RELIABILITY; 02050 } else if (!strcasecmp(v->value, "mincost")) { 02051 tos = IPTOS_MINCOST; 02052 } else if (!strcasecmp(v->value, "none")) { 02053 tos = 0; 02054 } else { 02055 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02056 } 02057 } else if (!strcasecmp(v->name, "gatekeeper")) { 02058 if (!strcasecmp(v->value, "DISABLE")) { 02059 gatekeeper_disable = 1; 02060 usingGk = 0; 02061 } else if (!strcasecmp(v->value, "DISCOVER")) { 02062 gatekeeper_disable = 0; 02063 gatekeeper_discover = 1; 02064 usingGk = 1; 02065 } else { 02066 gatekeeper_disable = 0; 02067 usingGk = 1; 02068 strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1); 02069 } 02070 } else if (!strcasecmp(v->name, "secret")) { 02071 strncpy(secret, v->value, sizeof(secret) - 1); 02072 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02073 gkroute = ast_true(v->value); 02074 } else if (!strcasecmp(v->name, "context")) { 02075 strncpy(default_context, v->value, sizeof(default_context) - 1); 02076 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02077 } else if (!strcasecmp(v->name, "UserByAlias")) { 02078 userbyalias = ast_true(v->value); 02079 } else if (!update_common_options(v, &global_options)) { 02080 /* dummy */ 02081 } 02082 v = v->next; 02083 } 02084 02085 cat = ast_category_browse(cfg, NULL); 02086 while(cat) { 02087 if (strcasecmp(cat, "general")) { 02088 utype = ast_variable_retrieve(cfg, cat, "type"); 02089 if (utype) { 02090 if (!strcasecmp(utype, "user")) { 02091 user = build_user(cat, ast_variable_browse(cfg, cat)); 02092 if (user) { 02093 ast_mutex_lock(&userl.lock); 02094 user->next = userl.users; 02095 userl.users = user; 02096 ast_mutex_unlock(&userl.lock); 02097 } 02098 } else if (!strcasecmp(utype, "peer")) { 02099 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02100 if (peer) { 02101 ast_mutex_lock(&peerl.lock); 02102 peer->next = peerl.peers; 02103 peerl.peers = peer; 02104 ast_mutex_unlock(&peerl.lock); 02105 } 02106 } else if (!strcasecmp(utype, "friend")) { 02107 user = build_user(cat, ast_variable_browse(cfg, cat)); 02108 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02109 if (user) { 02110 ast_mutex_lock(&userl.lock); 02111 user->next = userl.users; 02112 userl.users = user; 02113 ast_mutex_unlock(&userl.lock); 02114 } 02115 if (peer) { 02116 ast_mutex_lock(&peerl.lock); 02117 peer->next = peerl.peers; 02118 peerl.peers = peer; 02119 ast_mutex_unlock(&peerl.lock); 02120 } 02121 } else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) { 02122 alias = build_alias(cat, ast_variable_browse(cfg, cat)); 02123 if (alias) { 02124 ast_mutex_lock(&aliasl.lock); 02125 alias->next = aliasl.aliases; 02126 aliasl.aliases = alias; 02127 ast_mutex_unlock(&aliasl.lock); 02128 } 02129 } else { 02130 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02131 } 02132 } else { 02133 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02134 } 02135 } 02136 cat = ast_category_browse(cfg, cat); 02137 } 02138 ast_config_destroy(cfg); 02139 02140 /* Register our H.323 aliases if any*/ 02141 while (alias) { 02142 if (h323_set_alias(alias)) { 02143 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02144 return -1; 02145 } 02146 alias = alias->next; 02147 } 02148 02149 return 0; 02150 }
|
|
Definition at line 1354 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(). 01355 { 01356 struct iax_firmware *cur, *curl, *curp; 01357 DIR *fwd; 01358 struct dirent *de; 01359 char dir[256]; 01360 char fn[256]; 01361 /* Mark all as dead */ 01362 ast_mutex_lock(&waresl.lock); 01363 cur = waresl.wares; 01364 while(cur) { 01365 cur->dead = 1; 01366 cur = cur->next; 01367 } 01368 /* Now that we've freed them, load the new ones */ 01369 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_VAR_DIR); 01370 fwd = opendir(dir); 01371 if (fwd) { 01372 while((de = readdir(fwd))) { 01373 if (de->d_name[0] != '.') { 01374 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01375 if (!try_firmware(fn)) { 01376 if (option_verbose > 1) 01377 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01378 } 01379 } 01380 } 01381 closedir(fwd); 01382 } else 01383 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01384 01385 /* Clean up leftovers */ 01386 cur = waresl.wares; 01387 curp = NULL; 01388 while(cur) { 01389 curl = cur; 01390 cur = cur->next; 01391 if (curl->dead) { 01392 if (curp) { 01393 curp->next = cur; 01394 } else { 01395 waresl.wares = cur; 01396 } 01397 destroy_firmware(curl); 01398 } else { 01399 curp = cur; 01400 } 01401 } 01402 ast_mutex_unlock(&waresl.lock); 01403 }
|
|
Definition at line 6252 of file chan_iax2.c. References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts. Referenced by socket_read(). 06253 { 06254 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06255 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06256 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06257 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06258 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06259 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06260 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06261 }
|
|
Definition at line 2243 of file chan_iax2.c. References __do_deliver(), iax_frame::af, ast_bridged_channel(), ast_codec_get_samples(), AST_FRAME_VOICE, ast_log(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, chan_iax2_pvt::frames_dropped, ast_frame::frametype, GAMMA, iax2_dropcount, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, jb_getall(), jb_put(), jb_reset(), chan_iax2_pvt::jbid, chan_iax2_pvt::last, LOG_DEBUG, match(), MEMORY_SIZE, chan_iax2_pvt::min, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, iax_frame::retrans, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, unwrap_timestamp(), and update_jbsched(). Referenced by socket_read(). 02244 { 02245 #ifdef NEWJB 02246 int type, len; 02247 int ret; 02248 int needfree = 0; 02249 #else 02250 int x; 02251 int ms; 02252 int delay; 02253 unsigned int orig_ts; 02254 int drops[MEMORY_SIZE]; 02255 int min, max=0, prevjitterbuffer, maxone=0,y,z, match; 02256 02257 /* Remember current jitterbuffer so we can log any change */ 02258 prevjitterbuffer = iaxs[fr->callno]->jitterbuffer; 02259 /* Similarly for the frame timestamp */ 02260 orig_ts = fr->ts; 02261 #endif 02262 02263 #if 0 02264 if (option_debug && iaxdebug) 02265 ast_log(LOG_DEBUG, "schedule_delivery: ts=%d, last=%d, update=%d\n", 02266 fr->ts, iaxs[fr->callno]->last, updatehistory); 02267 #endif 02268 02269 /* Attempt to recover wrapped timestamps */ 02270 unwrap_timestamp(fr); 02271 02272 if (updatehistory) { 02273 #ifndef NEWJB 02274 02275 /* Attempt to spot a change of timebase on timestamps coming from the other side 02276 We detect by noticing a jump in consecutive timestamps that can't reasonably be explained 02277 by network jitter or reordering. Sometimes, also, the peer stops sending us frames 02278 for a while - in this case this code might also resync us. But that's not a bad thing. 02279 Be careful of non-voice frames which are timestamped differently (especially ACKS!) 02280 [that's why we only do this when updatehistory is true] 02281 */ 02282 x = fr->ts - iaxs[fr->callno]->last; 02283 if (x > TS_GAP_FOR_JB_RESYNC || x < -TS_GAP_FOR_JB_RESYNC) { 02284 if (option_debug && iaxdebug) 02285 ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped. resyncing rxcore (ts=%d, last=%d)\n", 02286 fr->callno, fr->ts, iaxs[fr->callno]->last); 02287 /* zap rxcore - calc_rxstamp will make a new one based on this frame */ 02288 iaxs[fr->callno]->rxcore = ast_tv(0, 0); 02289 /* wipe "last" if stamps have jumped backwards */ 02290 if (x<0) 02291 iaxs[fr->callno]->last = 0; 02292 /* should we also empty history? */ 02293 } 02294 /* ms is a measure of the "lateness" of the frame relative to the "reference" 02295 frame we received. (initially the very first, but also see code just above here). 02296 Understand that "ms" can easily be -ve if lag improves since the reference frame. 02297 Called by IAX thread, with iaxsl lock held. */ 02298 ms = calc_rxstamp(iaxs[fr->callno], fr->ts) - fr->ts; 02299 02300 /* Rotate our history queue of "lateness". Don't worry about those initial 02301 zeros because the first entry will always be zero */ 02302 for (x=0;x<MEMORY_SIZE - 1;x++) 02303 iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1]; 02304 /* Add a history entry for this one */ 02305 iaxs[fr->callno]->history[x] = ms; 02306 #endif 02307 } 02308 #ifndef NEWJB 02309 else 02310 ms = 0; 02311 #endif 02312 02313 02314 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02315 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02316 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02317 else { 02318 #if 0 02319 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02320 #endif 02321 fr->af.delivery = ast_tv(0,0); 02322 } 02323 02324 #ifndef NEWJB 02325 /* Initialize the minimum to reasonable values. It's too much 02326 work to do the same for the maximum, repeatedly */ 02327 min=iaxs[fr->callno]->history[0]; 02328 for (z=0;z < iax2_dropcount + 1;z++) { 02329 /* Start very optimistic ;-) */ 02330 max=-999999999; 02331 for (x=0;x<MEMORY_SIZE;x++) { 02332 if (max < iaxs[fr->callno]->history[x]) { 02333 /* We have a candidate new maximum value. Make 02334 sure it's not in our drop list */ 02335 match = 0; 02336 for (y=0;!match && (y<z);y++) 02337 match |= (drops[y] == x); 02338 if (!match) { 02339 /* It's not in our list, use it as the new maximum */ 02340 max = iaxs[fr->callno]->history[x]; 02341 maxone = x; 02342 } 02343 02344 } 02345 if (!z) { 02346 /* On our first pass, find the minimum too */ 02347 if (min > iaxs[fr->callno]->history[x]) 02348 min = iaxs[fr->callno]->history[x]; 02349 } 02350 } 02351 #if 1 02352 drops[z] = maxone; 02353 #endif 02354 } 02355 #endif 02356 02357 #ifdef NEWJB 02358 type = JB_TYPE_CONTROL; 02359 len = 0; 02360 02361 if(fr->af.frametype == AST_FRAME_VOICE) { 02362 type = JB_TYPE_VOICE; 02363 len = ast_codec_get_samples(&fr->af) / 8; 02364 } else if(fr->af.frametype == AST_FRAME_CNG) { 02365 type = JB_TYPE_SILENCE; 02366 } 02367 02368 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02369 if (tsout) 02370 *tsout = fr->ts; 02371 __do_deliver(fr); 02372 return -1; 02373 } 02374 02375 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02376 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02377 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02378 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02379 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02380 jb_frame frame; 02381 02382 /* deliver any frames in the jb */ 02383 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK) 02384 __do_deliver(frame.data); 02385 02386 jb_reset(iaxs[fr->callno]->jb); 02387 02388 if (iaxs[fr->callno]->jbid > -1) 02389 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02390 02391 iaxs[fr->callno]->jbid = -1; 02392 02393 /* deliver this frame now */ 02394 if (tsout) 02395 *tsout = fr->ts; 02396 __do_deliver(fr); 02397 return -1; 02398 02399 } 02400 02401 02402 /* insert into jitterbuffer */ 02403 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02404 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02405 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02406 if (ret == JB_DROP) { 02407 needfree++; 02408 } else if (ret == JB_SCHED) { 02409 update_jbsched(iaxs[fr->callno]); 02410 } 02411 #else 02412 /* Just for reference, keep the "jitter" value, the difference between the 02413 earliest and the latest. */ 02414 if (max >= min) 02415 iaxs[fr->callno]->jitter = max - min; 02416 02417 /* IIR filter for keeping track of historic jitter, but always increase 02418 historic jitter immediately for increase */ 02419 02420 if (iaxs[fr->callno]->jitter > iaxs[fr->callno]->historicjitter ) 02421 iaxs[fr->callno]->historicjitter = iaxs[fr->callno]->jitter; 02422 else 02423 iaxs[fr->callno]->historicjitter = GAMMA * (double)iaxs[fr->callno]->jitter + (1-GAMMA) * 02424 iaxs[fr->callno]->historicjitter; 02425 02426 /* If our jitter buffer is too big (by a significant margin), then we slowly 02427 shrink it to avoid letting the change be perceived */ 02428 if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer) 02429 iaxs[fr->callno]->jitterbuffer -= jittershrinkrate; 02430 02431 /* If our jitter buffer headroom is too small (by a significant margin), then we slowly enlarge it */ 02432 /* min_jitter_buffer should be SMALLER than max_jitter_buffer - leaving a "no mans land" 02433 in between - otherwise the jitterbuffer size will hunt up and down causing unnecessary 02434 disruption. Set maxexcessbuffer to say 150msec, minexcessbuffer to say 50 */ 02435 if (max > iaxs[fr->callno]->jitterbuffer - min_jitter_buffer) 02436 iaxs[fr->callno]->jitterbuffer += jittershrinkrate; 02437 02438 /* If our jitter buffer is smaller than our maximum delay, grow the jitter 02439 buffer immediately to accomodate it (and a little more). */ 02440 if (max > iaxs[fr->callno]->jitterbuffer) 02441 iaxs[fr->callno]->jitterbuffer = max 02442 /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */; 02443 02444 /* update "min", just for RRs and stats */ 02445 iaxs[fr->callno]->min = min; 02446 02447 /* Subtract the lateness from our jitter buffer to know how long to wait 02448 before sending our packet. */ 02449 delay = iaxs[fr->callno]->jitterbuffer - ms; 02450 02451 /* Whatever happens, no frame waits longer than maxjitterbuffer */ 02452 if (delay > maxjitterbuffer) 02453 delay = maxjitterbuffer; 02454 02455 /* If jitter buffer is disabled then just pretend the frame is "right on time" */ 02456 /* If frame came from trunk, also don't do any delay */ 02457 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) || fromtrunk ) 02458 delay = 0; 02459 02460 if (option_debug && iaxdebug) { 02461 /* Log jitter stats for possible offline analysis */ 02462 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", 02463 fr->callno, fr->ts, orig_ts, iaxs[fr->callno]->last, 02464 (fr->af.frametype == AST_FRAME_VOICE) ? "VOICE" : "CONTROL", 02465 min, max, iaxs[fr->callno]->jitterbuffer, 02466 iaxs[fr->callno]->jitterbuffer - prevjitterbuffer, 02467 ms, delay, 02468 iaxs[fr->callno]->jitter, iaxs[fr->callno]->historicjitter); 02469 } 02470 02471 if (delay < 1) { 02472 /* Don't deliver it more than 4 ms late */ 02473 if ((delay > -4) || (fr->af.frametype != AST_FRAME_VOICE)) { 02474 if (option_debug && iaxdebug) 02475 ast_log(LOG_DEBUG, "schedule_delivery: Delivering immediately (Calculated delay is %d)\n", delay); 02476 if (tsout) 02477 *tsout = fr->ts; 02478 __do_deliver(fr); 02479 return -1; 02480 } else { 02481 if (option_debug && iaxdebug) 02482 ast_log(LOG_DEBUG, "schedule_delivery: Dropping voice packet since %dms delay is too old\n", delay); 02483 iaxs[fr->callno]->frames_dropped++; 02484 needfree++; 02485 } 02486 } else { 02487 if (option_debug && iaxdebug) 02488 ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay); 02489 fr->retrans = ast_sched_add(sched, delay, do_deliver, fr); 02490 } 02491 #endif 02492 if (tsout) 02493 *tsout = fr->ts; 02494 if (needfree) { 02495 /* Free our iax frame */ 02496 iax2_frame_free(fr); 02497 return -1; 02498 } 02499 return 0; 02500 }
|
|
Definition at line 4660 of file chan_iax2.c. References __send_command(), and type. Referenced by attempt_transmit(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), send_command_locked(), send_lagrq(), send_ping(), and socket_read(). 04661 { 04662 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04663 }
|
|
Definition at line 4681 of file chan_iax2.c. References __send_command(), chan_iax2_pvt::callno, iax2_predestroy_nolock(), and type. Referenced by auth_reject(), auto_hangup(), iax2_hangup(), socket_read(), and update_registry(). 04682 { 04683 /* It is assumed that the callno has already been locked */ 04684 iax2_predestroy_nolock(i->callno); 04685 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04686 }
|
|
Definition at line 4688 of file chan_iax2.c. References __send_command(), and type. Referenced by iax2_vnak(), and socket_read(). 04689 { 04690 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04691 }
|
|
Definition at line 4665 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, send_command(), and type. Referenced by iax2_answer(), iax2_digit(), iax2_indicate(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer(). 04666 { 04667 int res; 04668 ast_mutex_lock(&iaxsl[callno]); 04669 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04670 ast_mutex_unlock(&iaxsl[callno]); 04671 return res; 04672 }
|
|
Definition at line 4693 of file chan_iax2.c. References __send_command(), and type. Referenced by socket_read(), and try_transfer(). 04694 { 04695 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04696 }
|
|
Definition at line 795 of file chan_iax2.c. References AST_FRAME_IAX, chan_iax2_pvt::bridgecallno, IAX_COMMAND_LAGRQ, iaxs, and send_command(). Referenced by find_callno(), and make_trunk(). 00796 { 00797 int callno = (long)data; 00798 /* Ping only if it's real not if it's bridged */ 00799 if (iaxs[callno]) { 00800 #ifdef BRIDGE_OPTIMIZATION 00801 if (!iaxs[callno]->bridgecallno) 00802 #endif 00803 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 00804 return 1; 00805 } else 00806 return 0; 00807 }
|
|
Definition at line 1483 of file chan_iax2.c. References ast_inet_ntoa(), ast_log(), iax_frame::callno, iax_frame::data, iax_frame::datalen, chan_iax2_pvt::error, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, LOG_WARNING, option_debug, iax_frame::sockfd, iax_frame::transfer, and iax_frame::ts. Referenced by attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit(). 01484 { 01485 int res; 01486 char iabuf[INET_ADDRSTRLEN]; 01487 /* Called with iaxsl held */ 01488 if (option_debug > 2 && iaxdebug) 01489 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)); 01490 /* Don't send if there was an error, but return error instead */ 01491 if (!f->callno) { 01492 ast_log(LOG_WARNING, "Call number = %d\n", f->callno); 01493 return -1; 01494 } 01495 if (!iaxs[f->callno]) 01496 return -1; 01497 if (iaxs[f->callno]->error) 01498 return -1; 01499 if (f->transfer) { 01500 if (iaxdebug) 01501 iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01502 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer, 01503 sizeof(iaxs[f->callno]->transfer)); 01504 } else { 01505 if (iaxdebug) 01506 iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01507 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr, 01508 sizeof(iaxs[f->callno]->addr)); 01509 } 01510 if (res < 0) { 01511 if (option_debug && iaxdebug) 01512 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01513 handle_error(); 01514 } else 01515 res = 0; 01516 return res; 01517 }
|
|
Definition at line 769 of file chan_iax2.c. References AST_FRAME_IAX, chan_iax2_pvt::bridgecallno, IAX_COMMAND_PING, iaxs, and send_command(). Referenced by find_callno(), and make_trunk(). 00770 { 00771 int callno = (long)data; 00772 /* Ping only if it's real, not if it's bridged */ 00773 if (iaxs[callno]) { 00774 #ifdef BRIDGE_OPTIMIZATION 00775 if (!iaxs[callno]->bridgecallno) 00776 #endif 00777 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00778 return 1; 00779 } else 00780 return 0; 00781 }
|
|
Definition at line 5931 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, globalflags, IAX_TRUNKTIMESTAMPS, LOG_DEBUG, 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(). 05932 { 05933 int res = 0; 05934 struct iax_frame *fr; 05935 struct ast_iax2_meta_hdr *meta; 05936 struct ast_iax2_meta_trunk_hdr *mth; 05937 int calls = 0; 05938 05939 /* Point to frame */ 05940 fr = (struct iax_frame *)tpeer->trunkdata; 05941 /* Point to meta data */ 05942 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 05943 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 05944 if (tpeer->trunkdatalen) { 05945 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 05946 meta->zeros = 0; 05947 meta->metacmd = IAX_META_TRUNK; 05948 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 05949 meta->cmddata = IAX_META_TRUNK_MINI; 05950 else 05951 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 05952 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 05953 /* And the rest of the ast_iax2 header */ 05954 fr->direction = DIRECTION_OUTGRESS; 05955 fr->retrans = -1; 05956 fr->transfer = 0; 05957 /* Any appropriate call will do */ 05958 fr->data = fr->afdata; 05959 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 05960 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 05961 calls = tpeer->calls; 05962 #if 0 05963 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)); 05964 #endif 05965 /* Reset transmit trunk side data */ 05966 tpeer->trunkdatalen = 0; 05967 tpeer->calls = 0; 05968 } 05969 if (res < 0) 05970 return res; 05971 return calls; 05972 }
|
|
Definition at line 8583 of file chan_iax2.c. References accountcode, amaflags, ast_category_browse(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_bind(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), authdebug, autokill, build_peer(), build_user(), cfg, channeltype, defaultsockfd, delayreject, get_encrypt_methods(), global_rtautoclear, globalflags, iax2_capability, iax2_dropcount, iax2_encryption, iax2_register(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, 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_NOTICE, LOG_WARNING, max_jitter_buffer, max_reg_expire, maxjitterbuffer, maxjitterinterps, min_jitter_buffer, min_reg_expire, ast_variable::name, netsock, iax2_peer::next, iax2_user::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, ping_time, prefs, reg_source_db(), regcontext, resyncthreshold, set_timing(), socket_read(), tos, trunkfreq, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2. 08584 { 08585 struct ast_config *cfg; 08586 int capability=iax2_capability; 08587 struct ast_variable *v; 08588 char *cat; 08589 char *utype; 08590 char *tosval; 08591 int format; 08592 int portno = IAX_DEFAULT_PORTNO; 08593 int x; 08594 struct iax2_user *user; 08595 struct iax2_peer *peer; 08596 struct ast_netsock *ns; 08597 #if 0 08598 static unsigned short int last_port=0; 08599 #endif 08600 08601 cfg = ast_config_load(config_file); 08602 08603 if (!cfg) { 08604 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08605 return -1; 08606 } 08607 08608 /* Reset global codec prefs */ 08609 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08610 08611 /* Reset Global Flags */ 08612 memset(&globalflags, 0, sizeof(globalflags)); 08613 ast_set_flag(&globalflags, IAX_RTUPDATE); 08614 08615 #ifdef SO_NO_CHECK 08616 nochecksums = 0; 08617 #endif 08618 08619 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08620 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08621 08622 v = ast_variable_browse(cfg, "general"); 08623 08624 /* Seed initial tos value */ 08625 tosval = ast_variable_retrieve(cfg, "general", "tos"); 08626 if (tosval) { 08627 if (ast_str2tos(tosval, &tos)) 08628 ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n"); 08629 } 08630 while(v) { 08631 if (!strcasecmp(v->name, "bindport")){ 08632 if (reload) 08633 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 08634 else 08635 portno = atoi(v->value); 08636 } else if (!strcasecmp(v->name, "pingtime")) 08637 ping_time = atoi(v->value); 08638 else if (!strcasecmp(v->name, "nochecksums")) { 08639 #ifdef SO_NO_CHECK 08640 if (ast_true(v->value)) 08641 nochecksums = 1; 08642 else 08643 nochecksums = 0; 08644 #else 08645 if (ast_true(v->value)) 08646 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 08647 #endif 08648 } 08649 else if (!strcasecmp(v->name, "maxjitterbuffer")) 08650 maxjitterbuffer = atoi(v->value); 08651 #ifdef NEWJB 08652 else if (!strcasecmp(v->name, "resyncthreshold")) 08653 resyncthreshold = atoi(v->value); 08654 else if (!strcasecmp(v->name, "maxjitterinterps")) 08655 maxjitterinterps = atoi(v->value); 08656 #endif 08657 else if (!strcasecmp(v->name, "jittershrinkrate")) 08658 jittershrinkrate = atoi(v->value); 08659 else if (!strcasecmp(v->name, "maxexcessbuffer")) 08660 max_jitter_buffer = atoi(v->value); 08661 else if (!strcasecmp(v->name, "minexcessbuffer")) 08662 min_jitter_buffer = atoi(v->value); 08663 else if (!strcasecmp(v->name, "lagrqtime")) 08664 lagrq_time = atoi(v->value); 08665 else if (!strcasecmp(v->name, "dropcount")) 08666 iax2_dropcount = atoi(v->value); 08667 else if (!strcasecmp(v->name, "maxregexpire")) 08668 max_reg_expire = atoi(v->value); 08669 else if (!strcasecmp(v->name, "minregexpire")) 08670 min_reg_expire = atoi(v->value); 08671 else if (!strcasecmp(v->name, "bindaddr")) { 08672 if (reload) { 08673 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 08674 } else { 08675 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 08676 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 08677 } else { 08678 if (option_verbose > 1) { 08679 if (strchr(v->value, ':')) 08680 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 08681 else 08682 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 08683 } 08684 if (defaultsockfd < 0) 08685 defaultsockfd = ast_netsock_sockfd(ns); 08686 ast_netsock_unref(ns); 08687 } 08688 } 08689 } else if (!strcasecmp(v->name, "authdebug")) 08690 authdebug = ast_true(v->value); 08691 else if (!strcasecmp(v->name, "encryption")) 08692 iax2_encryption = get_encrypt_methods(v->value); 08693 else if (!strcasecmp(v->name, "notransfer")) 08694 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 08695 else if (!strcasecmp(v->name, "codecpriority")) { 08696 if(!strcasecmp(v->value, "caller")) 08697 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 08698 else if(!strcasecmp(v->value, "disabled")) 08699 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08700 else if(!strcasecmp(v->value, "reqonly")) { 08701 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 08702 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08703 } 08704 } else if (!strcasecmp(v->name, "jitterbuffer")) 08705 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 08706 else if (!strcasecmp(v->name, "forcejitterbuffer")) 08707 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 08708 else if (!strcasecmp(v->name, "delayreject")) 08709 delayreject = ast_true(v->value); 08710 else if (!strcasecmp(v->name, "mailboxdetail")) 08711 ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL); 08712 else if (!strcasecmp(v->name, "rtcachefriends")) 08713 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 08714 else if (!strcasecmp(v->name, "rtignoreregexpire")) 08715 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 08716 else if (!strcasecmp(v->name, "rtupdate")) 08717 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 08718 else if (!strcasecmp(v->name, "trunktimestamps")) 08719 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 08720 else if (!strcasecmp(v->name, "rtautoclear")) { 08721 int i = atoi(v->value); 08722 if(i > 0) 08723 global_rtautoclear = i; 08724 else 08725 i = 0; 08726 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 08727 } else if (!strcasecmp(v->name, "trunkfreq")) { 08728 trunkfreq = atoi(v->value); 08729 if (trunkfreq < 10) 08730 trunkfreq = 10; 08731 } else if (!strcasecmp(v->name, "autokill")) { 08732 if (sscanf(v->value, "%d", &x) == 1) { 08733 if (x >= 0) 08734 autokill = x; 08735 else 08736 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 08737 } else if (ast_true(v->value)) { 08738 autokill = DEFAULT_MAXMS; 08739 } else { 08740 autokill = 0; 08741 } 08742 } else if (!strcasecmp(v->name, "bandwidth")) { 08743 if (!strcasecmp(v->value, "low")) { 08744 capability = IAX_CAPABILITY_LOWBANDWIDTH; 08745 } else if (!strcasecmp(v->value, "medium")) { 08746 capability = IAX_CAPABILITY_MEDBANDWIDTH; 08747 } else if (!strcasecmp(v->value, "high")) { 08748 capability = IAX_CAPABILITY_FULLBANDWIDTH; 08749 } else 08750 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 08751 } else if (!strcasecmp(v->name, "allow")) { 08752 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 08753 } else if (!strcasecmp(v->name, "disallow")) { 08754 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 08755 } else if (!strcasecmp(v->name, "register")) { 08756 iax2_register(v->value, v->lineno); 08757 } else if (!strcasecmp(v->name, "iaxcompat")) { 08758 iaxcompat = ast_true(v->value); 08759 } else if (!strcasecmp(v->name, "regcontext")) { 08760 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 08761 /* Create context if it doesn't exist already */ 08762 if (!ast_context_find(regcontext)) 08763 ast_context_create(NULL, regcontext, channeltype); 08764 } else if (!strcasecmp(v->name, "tos")) { 08765 if (ast_str2tos(v->value, &tos)) 08766 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 08767 } else if (!strcasecmp(v->name, "accountcode")) { 08768 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 08769 } else if (!strcasecmp(v->name, "amaflags")) { 08770 format = ast_cdr_amaflags2int(v->value); 08771 if (format < 0) { 08772 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08773 } else { 08774 amaflags = format; 08775 } 08776 } else if (!strcasecmp(v->name, "language")) { 08777 ast_copy_string(language, v->value, sizeof(language)); 08778 } /*else if (strcasecmp(v->name,"type")) */ 08779 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08780 v = v->next; 08781 } 08782 if (min_reg_expire > max_reg_expire) { 08783 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 08784 min_reg_expire, max_reg_expire, max_reg_expire); 08785 min_reg_expire = max_reg_expire; 08786 } 08787 iax2_capability = capability; 08788 cat = ast_category_browse(cfg, NULL); 08789 while(cat) { 08790 if (strcasecmp(cat, "general")) { 08791 utype = ast_variable_retrieve(cfg, cat, "type"); 08792 if (utype) { 08793 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 08794 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 08795 if (user) { 08796 ast_mutex_lock(&userl.lock); 08797 user->next = userl.users; 08798 userl.users = user; 08799 ast_mutex_unlock(&userl.lock); 08800 } 08801 } 08802 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 08803 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 08804 if (peer) { 08805 ast_mutex_lock(&peerl.lock); 08806 peer->next = peerl.peers; 08807 peerl.peers = peer; 08808 ast_mutex_unlock(&peerl.lock); 08809 if (ast_test_flag(peer, IAX_DYNAMIC)) 08810 reg_source_db(peer); 08811 } 08812 } else if (strcasecmp(utype, "user")) { 08813 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 08814 } 08815 } else 08816 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 08817 } 08818 cat = ast_category_browse(cfg, cat); 08819 } 08820 ast_config_destroy(cfg); 08821 set_timing(); 08822 return capability; 08823 }
|
|
Definition at line 8566 of file chan_iax2.c. References ast_log(), LOG_WARNING, timingfd, and trunkfreq. Referenced by set_config(). 08567 { 08568 #ifdef IAX_TRUNKING 08569 int bs = trunkfreq * 8; 08570 if (timingfd > -1) { 08571 if ( 08572 #ifdef ZT_TIMERACK 08573 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08574 #endif 08575 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08576 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08577 } 08578 #endif 08579 }
|
|
Definition at line 6263 of file chan_iax2.c. References iax_frame::af, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_string(), AST_CONTROL_PROGRESS, ast_device_state_changed(), ast_exists_extension(), ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, 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(), chan_iax2_pvt::authmethods, chan_iax2_pvt::bridgecallno, iax_ie_data::buf, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_frame::callno, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::dpentries, chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_error(), ast_channel::hangupcause, 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_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_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxdebug, iaxfrdup2(), iaxq, iaxs, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::lag, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, ast_channel::nativeformats, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, iax2_dpcache::peer, chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, chan_iax2_pvt::reg, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, stop_stuff(), ast_frame::subclass, iax_frame::transfer, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, ast_channel::writeformat, ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros. Referenced by load_module(), and set_config(). 06264 { 06265 struct sockaddr_in sin; 06266 int res; 06267 int updatehistory=1; 06268 int new = NEW_PREVENT; 06269 unsigned char buf[4096]; 06270 void *ptr; 06271 socklen_t len = sizeof(sin); 06272 int dcallno = 0; 06273 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf; 06274 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf; 06275 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; 06276 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf; 06277 struct ast_iax2_meta_trunk_hdr *mth; 06278 struct ast_iax2_meta_trunk_entry *mte; 06279 struct ast_iax2_meta_trunk_mini *mtm; 06280 char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */ 06281 struct iax_frame fr; 06282 struct iax_frame *cur; 06283 char iabuf[INET_ADDRSTRLEN]; 06284 struct ast_frame f; 06285 struct ast_channel *c; 06286 struct iax2_dpcache *dp; 06287 struct iax2_peer *peer; 06288 struct iax2_trunk_peer *tpeer; 06289 struct timeval rxtrunktime; 06290 struct iax_ies ies; 06291 struct iax_ie_data ied0, ied1; 06292 int format; 06293 int exists; 06294 int minivid = 0; 06295 unsigned int ts; 06296 char empty[32]=""; /* Safety measure */ 06297 struct iax_frame *duped_fr; 06298 char host_pref_buf[128]; 06299 char caller_pref_buf[128]; 06300 struct ast_codec_pref pref,rpref; 06301 char *using_prefs = "mine"; 06302 06303 dblbuf[0] = 0; /* Keep GCC from whining */ 06304 fr.callno = 0; 06305 06306 res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len); 06307 if (res < 0) { 06308 if (errno != ECONNREFUSED) 06309 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06310 handle_error(); 06311 return 1; 06312 } 06313 if(test_losspct) { /* simulate random loss condition */ 06314 if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct) 06315 return 1; 06316 06317 } 06318 if (res < sizeof(struct ast_iax2_mini_hdr)) { 06319 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr)); 06320 return 1; 06321 } 06322 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06323 /* This is a video frame, get call number */ 06324 fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06325 minivid = 1; 06326 } else if (meta->zeros == 0) { 06327 unsigned char metatype; 06328 /* This is a meta header */ 06329 switch(meta->metacmd) { 06330 case IAX_META_TRUNK: 06331 if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) { 06332 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr)); 06333 return 1; 06334 } 06335 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06336 ts = ntohl(mth->ts); 06337 metatype = meta->cmddata; 06338 res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)); 06339 ptr = mth->data; 06340 tpeer = find_tpeer(&sin, fd); 06341 if (!tpeer) { 06342 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)); 06343 return 1; 06344 } 06345 tpeer->trunkact = ast_tvnow(); 06346 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06347 tpeer->rxtrunktime = tpeer->trunkact; 06348 rxtrunktime = tpeer->rxtrunktime; 06349 ast_mutex_unlock(&tpeer->lock); 06350 while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) { 06351 /* Process channels */ 06352 unsigned short callno, trunked_ts, len; 06353 06354 if(metatype == IAX_META_TRUNK_MINI) { 06355 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06356 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06357 res -= sizeof(struct ast_iax2_meta_trunk_mini); 06358 len = ntohs(mtm->len); 06359 callno = ntohs(mtm->mini.callno); 06360 trunked_ts = ntohs(mtm->mini.ts); 06361 } else if ( metatype == IAX_META_TRUNK_SUPERMINI ) { 06362 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06363 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06364 res -= sizeof(struct ast_iax2_meta_trunk_entry); 06365 len = ntohs(mte->len); 06366 callno = ntohs(mte->callno); 06367 trunked_ts = 0; 06368 } else { 06369 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)); 06370 break; 06371 } 06372 /* Stop if we don't have enough data */ 06373 if (len > res) 06374 break; 06375 fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06376 if (fr.callno) { 06377 ast_mutex_lock(&iaxsl[fr.callno]); 06378 /* If it's a valid call, deliver the contents. If not, we 06379 drop it, since we don't have a scallno to use for an INVAL */ 06380 /* Process as a mini frame */ 06381 f.frametype = AST_FRAME_VOICE; 06382 if (iaxs[fr.callno]) { 06383 if (iaxs[fr.callno]->voiceformat > 0) { 06384 f.subclass = iaxs[fr.callno]->voiceformat; 06385 f.datalen = len; 06386 if (f.datalen >= 0) { 06387 if (f.datalen) 06388 f.data = ptr; 06389 else 06390 f.data = NULL; 06391 if(trunked_ts) { 06392 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06393 } else 06394 fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts); 06395 /* Don't pass any packets until we're started */ 06396 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06397 /* Common things */ 06398 f.src = "IAX2"; 06399 f.mallocd = 0; 06400 f.offset = 0; 06401 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06402 f.samples = ast_codec_get_samples(&f); 06403 else 06404 f.samples = 0; 06405 fr.outoforder = 0; 06406 iax_frame_wrap(&fr, &f); 06407 #ifdef BRIDGE_OPTIMIZATION 06408 if (iaxs[fr.callno]->bridgecallno) { 06409 forward_delivery(&fr); 06410 } else { 06411 duped_fr = iaxfrdup2(&fr); 06412 if (duped_fr) { 06413 schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); 06414 } 06415 } 06416 #else 06417 duped_fr = iaxfrdup2(&fr); 06418 if (duped_fr) { 06419 schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); 06420 } 06421 #endif 06422 if (iaxs[fr.callno]->last < fr.ts) { 06423 iaxs[fr.callno]->last = fr.ts; 06424 #if 1 06425 if (option_debug) 06426 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 06427 #endif 06428 } 06429 } 06430 } else { 06431 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06432 } 06433 } else { 06434 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06435 iax2_vnak(fr.callno); 06436 } 06437 } 06438 ast_mutex_unlock(&iaxsl[fr.callno]); 06439 } 06440 ptr += len; 06441 res -= len; 06442 } 06443 06444 } 06445 return 1; 06446 } 06447 #ifdef DEBUG_SUPPORT 06448 if (iaxdebug) 06449 iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr)); 06450 #endif 06451 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06452 /* Get the destination call number */ 06453 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06454 /* Retrieve the type and subclass */ 06455 f.frametype = fh->type; 06456 if (f.frametype == AST_FRAME_VIDEO) { 06457 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06458 } else { 06459 f.subclass = uncompress_subclass(fh->csub); 06460 } 06461 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06462 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06463 (f.subclass == IAX_COMMAND_REGREL))) 06464 new = NEW_ALLOW; 06465 } else { 06466 /* Don't know anything about it yet */ 06467 f.frametype = AST_FRAME_NULL; 06468 f.subclass = 0; 06469 } 06470 06471 if (!fr.callno) 06472 fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06473 06474 if (fr.callno > 0) 06475 ast_mutex_lock(&iaxsl[fr.callno]); 06476 06477 if (!fr.callno || !iaxs[fr.callno]) { 06478 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06479 frame, reply with an inval */ 06480 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06481 /* We can only raw hangup control frames */ 06482 if (((f.subclass != IAX_COMMAND_INVAL) && 06483 (f.subclass != IAX_COMMAND_TXCNT) && 06484 (f.subclass != IAX_COMMAND_TXACC) && 06485 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06486 (f.frametype != AST_FRAME_IAX)) 06487 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06488 fd); 06489 } 06490 if (fr.callno > 0) 06491 ast_mutex_unlock(&iaxsl[fr.callno]); 06492 return 1; 06493 } 06494 if (ast_test_flag(iaxs[fr.callno], IAX_ENCRYPTED)) { 06495 if (decrypt_frame(fr.callno, fh, &f, &res)) { 06496 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06497 ast_mutex_unlock(&iaxsl[fr.callno]); 06498 return 1; 06499 } 06500 #ifdef DEBUG_SUPPORT 06501 else if (iaxdebug) 06502 iax_showframe(NULL, fh, 3, &sin, res - sizeof(struct ast_iax2_full_hdr)); 06503 #endif 06504 } 06505 06506 /* count this frame */ 06507 iaxs[fr.callno]->frames_received++; 06508 06509 if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid && 06510 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06511 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06512 iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06513 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06514 if (option_debug && iaxdebug) 06515 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06516 /* Check if it's out of order (and not an ACK or INVAL) */ 06517 fr.oseqno = fh->oseqno; 06518 fr.iseqno = fh->iseqno; 06519 fr.ts = ntohl(fh->ts); 06520 #ifdef IAXTESTS 06521 if (test_resync) { 06522 if (option_debug) 06523 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr.ts, fr.ts + test_resync); 06524 fr.ts += test_resync; 06525 } 06526 #endif /* IAXTESTS */ 06527 #if 0 06528 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06529 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06530 (f.subclass == IAX_COMMAND_NEW || 06531 f.subclass == IAX_COMMAND_AUTHREQ || 06532 f.subclass == IAX_COMMAND_ACCEPT || 06533 f.subclass == IAX_COMMAND_REJECT)) ) ) 06534 #endif 06535 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06536 updatehistory = 0; 06537 if ((iaxs[fr.callno]->iseqno != fr.oseqno) && 06538 (iaxs[fr.callno]->iseqno || 06539 ((f.subclass != IAX_COMMAND_TXCNT) && 06540 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06541 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06542 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06543 (f.subclass != IAX_COMMAND_TXACC)) || 06544 (f.frametype != AST_FRAME_IAX))) { 06545 if ( 06546 ((f.subclass != IAX_COMMAND_ACK) && 06547 (f.subclass != IAX_COMMAND_INVAL) && 06548 (f.subclass != IAX_COMMAND_TXCNT) && 06549 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06550 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06551 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06552 (f.subclass != IAX_COMMAND_TXACC) && 06553 (f.subclass != IAX_COMMAND_VNAK)) || 06554 (f.frametype != AST_FRAME_IAX)) { 06555 /* If it's not an ACK packet, it's out of order. */ 06556 if (option_debug) 06557 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06558 iaxs[fr.callno]->iseqno, fr.oseqno, f.frametype, f.subclass); 06559 if (iaxs[fr.callno]->iseqno > fr.oseqno) { 06560 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06561 if ((f.frametype != AST_FRAME_IAX) || 06562 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06563 if (option_debug) 06564 ast_log(LOG_DEBUG, "Acking anyway\n"); 06565 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06566 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06567 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06568 } 06569 } else { 06570 /* Send a VNAK requesting retransmission */ 06571 iax2_vnak(fr.callno); 06572 } 06573 ast_mutex_unlock(&iaxsl[fr.callno]); 06574 return 1; 06575 } 06576 } else { 06577 /* Increment unless it's an ACK or VNAK */ 06578 if (((f.subclass != IAX_COMMAND_ACK) && 06579 (f.subclass != IAX_COMMAND_INVAL) && 06580 (f.subclass != IAX_COMMAND_TXCNT) && 06581 (f.subclass != IAX_COMMAND_TXACC) && 06582 (f.subclass != IAX_COMMAND_VNAK)) || 06583 (f.frametype != AST_FRAME_IAX)) 06584 iaxs[fr.callno]->iseqno++; 06585 } 06586 /* A full frame */ 06587 if (res < sizeof(struct ast_iax2_full_hdr)) { 06588 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_full_hdr)); 06589 ast_mutex_unlock(&iaxsl[fr.callno]); 06590 return 1; 06591 } 06592 f.datalen = res - sizeof(struct ast_iax2_full_hdr); 06593 06594 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06595 from the real peer, not the transfer peer */ 06596 if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 06597 ((f.subclass != IAX_COMMAND_INVAL) || 06598 (f.frametype != AST_FRAME_IAX))) { 06599 unsigned char x; 06600 /* XXX This code is not very efficient. Surely there is a better way which still 06601 properly handles boundary conditions? XXX */ 06602 /* First we have to qualify that the ACKed value is within our window */ 06603 for (x=iaxs[fr.callno]->rseqno; x != iaxs[fr.callno]->oseqno; x++) 06604 if (fr.iseqno == x) 06605 break; 06606 if ((x != iaxs[fr.callno]->oseqno) || (iaxs[fr.callno]->oseqno == fr.iseqno)) { 06607 /* The acknowledgement is within our window. Time to acknowledge everything 06608 that it says to */ 06609 for (x=iaxs[fr.callno]->rseqno; x != fr.iseqno; x++) { 06610 /* Ack the packet with the given timestamp */ 06611 if (option_debug && iaxdebug) 06612 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06613 ast_mutex_lock(&iaxq.lock); 06614 for (cur = iaxq.head; cur ; cur = cur->next) { 06615 /* If it's our call, and our timestamp, mark -1 retries */ 06616 if ((fr.callno == cur->callno) && (x == cur->oseqno)) { 06617 cur->retries = -1; 06618 /* Destroy call if this is the end */ 06619 if (cur->final) { 06620 if (iaxdebug && option_debug) 06621 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr.callno); 06622 iax2_destroy_nolock(fr.callno); 06623 } 06624 } 06625 } 06626 ast_mutex_unlock(&iaxq.lock); 06627 } 06628 /* Note how much we've received acknowledgement for */ 06629 if (iaxs[fr.callno]) 06630 iaxs[fr.callno]->rseqno = fr.iseqno; 06631 else { 06632 /* Stop processing now */ 06633 ast_mutex_unlock(&iaxsl[fr.callno]); 06634 return 1; 06635 } 06636 } else 06637 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno); 06638 } 06639 if (inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 06640 ((f.frametype != AST_FRAME_IAX) || 06641 ((f.subclass != IAX_COMMAND_TXACC) && 06642 (f.subclass != IAX_COMMAND_TXCNT)))) { 06643 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06644 ast_mutex_unlock(&iaxsl[fr.callno]); 06645 return 1; 06646 } 06647 06648 if (f.datalen) { 06649 if (f.frametype == AST_FRAME_IAX) { 06650 if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 06651 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06652 ast_mutex_unlock(&iaxsl[fr.callno]); 06653 return 1; 06654 } 06655 f.data = NULL; 06656 } else 06657 f.data = buf + sizeof(struct ast_iax2_full_hdr); 06658 } else { 06659 if (f.frametype == AST_FRAME_IAX) 06660 f.data = NULL; 06661 else 06662 f.data = empty; 06663 memset(&ies, 0, sizeof(ies)); 06664 } 06665 if (f.frametype == AST_FRAME_VOICE) { 06666 if (f.subclass != iaxs[fr.callno]->voiceformat) { 06667 iaxs[fr.callno]->voiceformat = f.subclass; 06668 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06669 if (iaxs[fr.callno]->owner) { 06670 int orignative; 06671 retryowner: 06672 if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { 06673 ast_mutex_unlock(&iaxsl[fr.callno]); 06674 usleep(1); 06675 ast_mutex_lock(&iaxsl[fr.callno]); 06676 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner; 06677 } 06678 if (iaxs[fr.callno]) { 06679 if (iaxs[fr.callno]->owner) { 06680 orignative = iaxs[fr.callno]->owner->nativeformats; 06681 iaxs[fr.callno]->owner->nativeformats = f.subclass; 06682 if (iaxs[fr.callno]->owner->readformat) 06683 ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); 06684 iaxs[fr.callno]->owner->nativeformats = orignative; 06685 ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); 06686 } 06687 } else { 06688 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06689 ast_mutex_unlock(&iaxsl[fr.callno]); 06690 return 1; 06691 } 06692 } 06693 } 06694 } 06695 if (f.frametype == AST_FRAME_VIDEO) { 06696 if (f.subclass != iaxs[fr.callno]->videoformat) { 06697 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06698 iaxs[fr.callno]->videoformat = f.subclass & ~0x1; 06699 } 06700 } 06701 if (f.frametype == AST_FRAME_IAX) { 06702 if (iaxs[fr.callno]->initid > -1) { 06703 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06704 ast_sched_del(sched, iaxs[fr.callno]->initid); 06705 iaxs[fr.callno]->initid = -1; 06706 } 06707 /* Handle the IAX pseudo frame itself */ 06708 if (option_debug && iaxdebug) 06709 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06710 06711 /* Update last ts unless the frame's timestamp originated with us. */ 06712 if (iaxs[fr.callno]->last < fr.ts && 06713 f.subclass != IAX_COMMAND_ACK && 06714 f.subclass != IAX_COMMAND_PONG && 06715 f.subclass != IAX_COMMAND_LAGRP) { 06716 iaxs[fr.callno]->last = fr.ts; 06717 if (option_debug && iaxdebug) 06718 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 06719 } 06720 06721 switch(f.subclass) { 06722 case IAX_COMMAND_ACK: 06723 /* Do nothing */ 06724 break; 06725 case IAX_COMMAND_QUELCH: 06726 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06727 /* Generate Manager Hold event, if necessary*/ 06728 if (iaxs[fr.callno]->owner) { 06729 manager_event(EVENT_FLAG_CALL, "Hold", 06730 "Channel: %s\r\n" 06731 "Uniqueid: %s\r\n", 06732 iaxs[fr.callno]->owner->name, 06733 iaxs[fr.callno]->owner->uniqueid); 06734 } 06735 06736 ast_set_flag(iaxs[fr.callno], IAX_QUELCH); 06737 if (ies.musiconhold) { 06738 if (iaxs[fr.callno]->owner && 06739 ast_bridged_channel(iaxs[fr.callno]->owner)) 06740 ast_moh_start(ast_bridged_channel(iaxs[fr.callno]->owner), NULL); 06741 } 06742 } 06743 break; 06744 case IAX_COMMAND_UNQUELCH: 06745 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 06746 /* Generate Manager Unhold event, if necessary*/ 06747 if (iaxs[fr.callno]->owner && ast_test_flag(iaxs[fr.callno], IAX_QUELCH)) { 06748 manager_event(EVENT_FLAG_CALL, "Unhold", 06749 "Channel: %s\r\n" 06750 "Uniqueid: %s\r\n", 06751 iaxs[fr.callno]->owner->name, 06752 iaxs[fr.callno]->owner->uniqueid); 06753 } 06754 06755 ast_clear_flag(iaxs[fr.callno], IAX_QUELCH); 06756 if (iaxs[fr.callno]->owner && 06757 ast_bridged_channel(iaxs[fr.callno]->owner)) 06758 ast_moh_stop(ast_bridged_channel(iaxs[fr.callno]->owner)); 06759 } 06760 break; 06761 case IAX_COMMAND_TXACC: 06762 if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { 06763 /* Ack the packet with the given timestamp */ 06764 ast_mutex_lock(&iaxq.lock); 06765 for (cur = iaxq.head; cur ; cur = cur->next) { 06766 /* Cancel any outstanding txcnt's */ 06767 if ((fr.callno == cur->callno) && (cur->transfer)) 06768 cur->retries = -1; 06769 } 06770 ast_mutex_unlock(&iaxq.lock); 06771 memset(&ied1, 0, sizeof(ied1)); 06772 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->callno); 06773 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06774 iaxs[fr.callno]->transferring = TRANSFER_READY; 06775 } 06776 break; 06777 case IAX_COMMAND_NEW: 06778 /* Ignore if it's already up */ 06779 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06780 break; 06781 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06782 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06783 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06784 if (ast_test_flag(iaxs[fr.callno], IAX_TRUNK)) { 06785 fr.callno = make_trunk(fr.callno, 1); 06786 } 06787 /* For security, always ack immediately */ 06788 if (delayreject) 06789 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06790 if (check_access(fr.callno, &sin, &ies)) { 06791 /* They're not allowed on */ 06792 auth_fail(fr.callno, IAX_COMMAND_REJECT); 06793 if (authdebug) 06794 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); 06795 break; 06796 } 06797 /* This might re-enter the IAX code and need the lock */ 06798 if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { 06799 ast_mutex_unlock(&iaxsl[fr.callno]); 06800 exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); 06801 ast_mutex_lock(&iaxsl[fr.callno]); 06802 } else 06803 exists = 0; 06804 if (ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) { 06805 if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { 06806 memset(&ied0, 0, sizeof(ied0)); 06807 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06808 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06809 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06810 if (authdebug) 06811 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); 06812 } else { 06813 /* Select an appropriate format */ 06814 06815 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 06816 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 06817 using_prefs = "reqonly"; 06818 } else { 06819 using_prefs = "disabled"; 06820 } 06821 format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; 06822 memset(&pref, 0, sizeof(pref)); 06823 strcpy(caller_pref_buf, "disabled"); 06824 strcpy(host_pref_buf, "disabled"); 06825 } else { 06826 using_prefs = "mine"; 06827 if(ies.codec_prefs) { 06828 ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); 06829 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06830 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 06831 pref = rpref; 06832 using_prefs = "caller"; 06833 } else { 06834 pref = iaxs[fr.callno]->prefs; 06835 } 06836 } else 06837 pref = iaxs[fr.callno]->prefs; 06838 06839 format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); 06840 ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06841 ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06842 } 06843 if (!format) { 06844 if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 06845 format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; 06846 if (!format) { 06847 memset(&ied0, 0, sizeof(ied0)); 06848 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06849 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06850 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06851 if (authdebug) { 06852 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 06853 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); 06854 else 06855 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); 06856 } 06857 } else { 06858 /* Pick one... */ 06859 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 06860 if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) 06861 format = 0; 06862 } else { 06863 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 06864 using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06865 memset(&pref, 0, sizeof(pref)); 06866 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06867 strcpy(caller_pref_buf,"disabled"); 06868 strcpy(host_pref_buf,"disabled"); 06869 } else { 06870 using_prefs = "mine"; 06871 if(ies.codec_prefs) { 06872 /* Do the opposite of what we tried above. */ 06873 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 06874 pref = iaxs[fr.callno]->prefs; 06875 } else { 06876 pref = rpref; 06877 using_prefs = "caller"; 06878 } 06879 format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); 06880 06881 } else /* if no codec_prefs IE do it the old way */ 06882 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06883 } 06884 } 06885 06886 if (!format) { 06887 memset(&ied0, 0, sizeof(ied0)); 06888 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06889 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06890 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 06891 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06892 if (authdebug) 06893 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); 06894 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 06895 break; 06896 } 06897 } 06898 } 06899 if (format) { 06900 /* No authentication required, let them in */ 06901 memset(&ied1, 0, sizeof(ied1)); 06902 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 06903 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 06904 if (strcmp(iaxs[fr.callno]->exten, "TBD")) { 06905 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 06906 if (option_verbose > 2) 06907 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 06908 "%srequested format = %s,\n" 06909 "%srequested prefs = %s,\n" 06910 "%sactual format = %s,\n" 06911 "%shost prefs = %s,\n" 06912 "%spriority = %s\n", 06913 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 06914 VERBOSE_PREFIX_4, 06915 ast_getformatname(iaxs[fr.callno]->peerformat), 06916 VERBOSE_PREFIX_4, 06917 caller_pref_buf, 06918 VERBOSE_PREFIX_4, 06919 ast_getformatname(format), 06920 VERBOSE_PREFIX_4, 06921 host_pref_buf, 06922 VERBOSE_PREFIX_4, 06923 using_prefs); 06924 06925 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) 06926 iax2_destroy_nolock(fr.callno); 06927 } else { 06928 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 06929 /* If this is a TBD call, we're ready but now what... */ 06930 if (option_verbose > 2) 06931 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06932 } 06933 } 06934 } 06935 break; 06936 } 06937 if (iaxs[fr.callno]->authmethods & IAX_AUTH_MD5) 06938 merge_encryption(iaxs[fr.callno],ies.encmethods); 06939 else 06940 iaxs[fr.callno]->encmethods = 0; 06941 authenticate_request(iaxs[fr.callno]); 06942 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED); 06943 break; 06944 case IAX_COMMAND_DPREQ: 06945 /* Request status in the dialplan */ 06946 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD) && 06947 !ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED) && ies.called_number) { 06948 if (iaxcompat) { 06949 /* Spawn a thread for the lookup */ 06950 spawn_dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num); 06951 } else { 06952 /* Just look it up */ 06953 dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num, 1); 06954 } 06955 } 06956 break; 06957 case IAX_COMMAND_HANGUP: 06958 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 06959 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno); 06960 /* Set hangup cause according to remote */ 06961 if (ies.causecode && iaxs[fr.callno]->owner) 06962 iaxs[fr.callno]->owner->hangupcause = ies.causecode; 06963 /* Send ack immediately, before we destroy */ 06964 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06965 iax2_destroy_nolock(fr.callno); 06966 break; 06967 case IAX_COMMAND_REJECT: 06968 memset(&f, 0, sizeof(f)); 06969 f.frametype = AST_FRAME_CONTROL; 06970 f.subclass = AST_CONTROL_CONGESTION; 06971 06972 /* Set hangup cause according to remote */ 06973 if (ies.causecode && iaxs[fr.callno]->owner) 06974 iaxs[fr.callno]->owner->hangupcause = ies.causecode; 06975 06976 iax2_queue_frame(fr.callno, &f); 06977 if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { 06978 /* Send ack immediately, before we destroy */ 06979 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06980 iax2_destroy_nolock(fr.callno); 06981 break; 06982 } 06983 if (iaxs[fr.callno]->owner) { 06984 if (authdebug) 06985 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>"); 06986 } 06987 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno); 06988 /* Send ack immediately, before we destroy */ 06989 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 06990 iaxs[fr.callno]->error = EPERM; 06991 iax2_destroy_nolock(fr.callno); 06992 break; 06993 case IAX_COMMAND_TRANSFER: 06994 if (iaxs[fr.callno]->owner && ast_bridged_channel(iaxs[fr.callno]->owner) && ies.called_number) { 06995 if (!strcmp(ies.called_number, ast_parking_ext())) { 06996 if (iax_park(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->owner)) { 06997 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); 06998 } else 06999 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); 07000 } else { 07001 if (ast_async_goto(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->context, ies.called_number, 1)) 07002 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 07003 ies.called_number, iaxs[fr.callno]->context); 07004 else 07005 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 07006 ies.called_number, iaxs[fr.callno]->context); 07007 } 07008 } else 07009 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr.callno); 07010 break; 07011 case IAX_COMMAND_ACCEPT: 07012 /* Ignore if call is already up or needs authentication or is a TBD */ 07013 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07014 break; 07015 if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { 07016 /* Send ack immediately, before we destroy */ 07017 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07018 iax2_destroy_nolock(fr.callno); 07019 break; 07020 } 07021 if (ies.format) { 07022 iaxs[fr.callno]->peerformat = ies.format; 07023 } else { 07024 if (iaxs[fr.callno]->owner) 07025 iaxs[fr.callno]->peerformat = iaxs[fr.callno]->owner->nativeformats; 07026 else 07027 iaxs[fr.callno]->peerformat = iaxs[fr.callno]->capability; 07028 } 07029 if (option_verbose > 2) 07030 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)); 07031 if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) { 07032 memset(&ied0, 0, sizeof(ied0)); 07033 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07034 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07035 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07036 if (authdebug) 07037 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); 07038 } else { 07039 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07040 if (iaxs[fr.callno]->owner) { 07041 /* Switch us to use a compatible format */ 07042 iaxs[fr.callno]->owner->nativeformats = iaxs[fr.callno]->peerformat; 07043 if (option_verbose > 2) 07044 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr.callno]->owner->nativeformats)); 07045 retryowner2: 07046 if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { 07047 ast_mutex_unlock(&iaxsl[fr.callno]); 07048 usleep(1); 07049 ast_mutex_lock(&iaxsl[fr.callno]); 07050 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner2; 07051 } 07052 07053 if (iaxs[fr.callno] && iaxs[fr.callno]->owner) { 07054 /* Setup read/write formats properly. */ 07055 if (iaxs[fr.callno]->owner->writeformat) 07056 ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat); 07057 if (iaxs[fr.callno]->owner->readformat) 07058 ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); 07059 ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); 07060 } 07061 } 07062 } 07063 ast_mutex_lock(&dpcache_lock); 07064 dp = iaxs[fr.callno]->dpentries; 07065 while(dp) { 07066 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07067 iax2_dprequest(dp, fr.callno); 07068 } 07069 dp = dp->peer; 07070 } 07071 ast_mutex_unlock(&dpcache_lock); 07072 break; 07073 case IAX_COMMAND_POKE: 07074 /* Send back a pong packet with the original timestamp */ 07075 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); 07076 break; 07077 case IAX_COMMAND_PING: 07078 #ifdef BRIDGE_OPTIMIZATION 07079 if (iaxs[fr.callno]->bridgecallno) { 07080 /* If we're in a bridged call, just forward this */ 07081 forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr.ts, NULL, 0, -1); 07082 } else { 07083 struct iax_ie_data pingied; 07084 construct_rr(iaxs[fr.callno], &pingied); 07085 /* Send back a pong packet with the original timestamp */ 07086 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); 07087 } 07088 #else 07089 { 07090 struct iax_ie_data pingied; 07091 construct_rr(iaxs[fr.callno], &pingied); 07092 /* Send back a pong packet with the original timestamp */ 07093 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); 07094 } 07095 #endif 07096 break; 07097 case IAX_COMMAND_PONG: 07098 #ifdef BRIDGE_OPTIMIZATION 07099 if (iaxs[fr.callno]->bridgecallno) { 07100 /* Forward to the other side of the bridge */ 07101 forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); 07102 } else { 07103 /* Calculate ping time */ 07104 iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; 07105 } 07106 #else 07107 /* Calculate ping time */ 07108 iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; 07109 #endif 07110 /* save RR info */ 07111 save_rr(&fr, &ies); 07112 07113 if (iaxs[fr.callno]->peerpoke) { 07114 peer = iaxs[fr.callno]->peerpoke; 07115 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07116 if (iaxs[fr.callno]->pingtime <= peer->maxms) { 07117 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr.callno]->pingtime); 07118 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 07119 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07120 } 07121 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07122 if (iaxs[fr.callno]->pingtime > peer->maxms) { 07123 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr.callno]->pingtime); 07124 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 07125 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07126 } 07127 } 07128 peer->lastms = iaxs[fr.callno]->pingtime; 07129 if (peer->smoothing && (peer->lastms > -1)) 07130 peer->historicms = (iaxs[fr.callno]->pingtime + peer->historicms) / 2; 07131 else if (peer->smoothing && peer->lastms < 0) 07132 peer->historicms = (0 + peer->historicms) / 2; 07133 else 07134 peer->historicms = iaxs[fr.callno]->pingtime; 07135 07136 if (peer->pokeexpire > -1) 07137 ast_sched_del(sched, peer->pokeexpire); 07138 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07139 iax2_destroy_nolock(fr.callno); 07140 peer->callno = 0; 07141 /* Try again eventually */ 07142 ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms); 07143 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07144 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07145 else 07146 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07147 } 07148 break; 07149 case IAX_COMMAND_LAGRQ: 07150 case IAX_COMMAND_LAGRP: 07151 #ifdef BRIDGE_OPTIMIZATION 07152 if (iaxs[fr.callno]->bridgecallno) { 07153 forward_command(iaxs[fr.callno], AST_FRAME_IAX, f.subclass, fr.ts, NULL, 0, -1); 07154 } else { 07155 #endif 07156 f.src = "LAGRQ"; 07157 f.mallocd = 0; 07158 f.offset = 0; 07159 f.samples = 0; 07160 iax_frame_wrap(&fr, &f); 07161 if(f.subclass == IAX_COMMAND_LAGRQ) { 07162 /* Received a LAGRQ - echo back a LAGRP */ 07163 fr.af.subclass = IAX_COMMAND_LAGRP; 07164 iax2_send(iaxs[fr.callno], &fr.af, fr.ts, -1, 0, 0, 0); 07165 } else { 07166 /* Received LAGRP in response to our LAGRQ */ 07167 unsigned int ts; 07168 /* This is a reply we've been given, actually measure the difference */ 07169 ts = calc_timestamp(iaxs[fr.callno], 0, &fr.af); 07170 iaxs[fr.callno]->lag = ts - fr.ts; 07171 if (option_debug && iaxdebug) 07172 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07173 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->lag); 07174 } 07175 #ifdef BRIDGE_OPTIMIZATION 07176 } 07177 #endif 07178 break; 07179 case IAX_COMMAND_AUTHREQ: 07180 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07181 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>"); 07182 break; 07183 } 07184 if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) { 07185 ast_log(LOG_WARNING, 07186 "I don't know how to authenticate %s to %s\n", 07187 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr)); 07188 } 07189 break; 07190 case IAX_COMMAND_AUTHREP: 07191 /* For security, always ack immediately */ 07192 if (delayreject) 07193 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07194 /* Ignore once we've started */ 07195 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07196 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>"); 07197 break; 07198 } 07199 if (authenticate_verify(iaxs[fr.callno], &ies)) { 07200 if (authdebug) 07201 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); 07202 memset(&ied0, 0, sizeof(ied0)); 07203 auth_fail(fr.callno, IAX_COMMAND_REJECT); 07204 break; 07205 } 07206 if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { 07207 /* This might re-enter the IAX code and need the lock */ 07208 exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); 07209 } else 07210 exists = 0; 07211 if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { 07212 if (authdebug) 07213 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); 07214 memset(&ied0, 0, sizeof(ied0)); 07215 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07216 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07217 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07218 } else { 07219 /* Select an appropriate format */ 07220 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 07221 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07222 using_prefs = "reqonly"; 07223 } else { 07224 using_prefs = "disabled"; 07225 } 07226 format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; 07227 memset(&pref, 0, sizeof(pref)); 07228 strcpy(caller_pref_buf, "disabled"); 07229 strcpy(host_pref_buf, "disabled"); 07230 } else { 07231 using_prefs = "mine"; 07232 if(ies.codec_prefs) { 07233 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07234 ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); 07235 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 07236 ast_codec_pref_convert(&pref, ies.codec_prefs, 32, 0); 07237 using_prefs = "caller"; 07238 } else { 07239 pref = iaxs[fr.callno]->prefs; 07240 } 07241 } else /* if no codec_prefs IE do it the old way */ 07242 pref = iaxs[fr.callno]->prefs; 07243 07244 format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); 07245 ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07246 ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07247 } 07248 if (!format) { 07249 if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07250 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); 07251 format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; 07252 } 07253 if (!format) { 07254 if (authdebug) { 07255 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 07256 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); 07257 else 07258 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); 07259 } 07260 memset(&ied0, 0, sizeof(ied0)); 07261 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07262 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07263 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07264 } else { 07265 /* Pick one... */ 07266 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { 07267 if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) 07268 format = 0; 07269 } else { 07270 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { 07271 using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07272 memset(&pref, 0, sizeof(pref)); 07273 format = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? 07274 iaxs[fr.callno]->peerformat : ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07275 strcpy(caller_pref_buf,"disabled"); 07276 strcpy(host_pref_buf,"disabled"); 07277 } else { 07278 using_prefs = "mine"; 07279 if(ies.codec_prefs) { 07280 /* Do the opposite of what we tried above. */ 07281 if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { 07282 pref = iaxs[fr.callno]->prefs; 07283 } else { 07284 pref = rpref; 07285 using_prefs = "caller"; 07286 } 07287 format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); 07288 } else /* if no codec_prefs IE do it the old way */ 07289 format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07290 } 07291 } 07292 if (!format) { 07293 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); 07294 if (authdebug) { 07295 if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 07296 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); 07297 else 07298 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); 07299 } 07300 memset(&ied0, 0, sizeof(ied0)); 07301 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07302 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07303 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07304 } 07305 } 07306 } 07307 if (format) { 07308 /* Authentication received */ 07309 memset(&ied1, 0, sizeof(ied1)); 07310 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07311 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07312 if (strcmp(iaxs[fr.callno]->exten, "TBD")) { 07313 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07314 if (option_verbose > 2) 07315 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07316 "%srequested format = %s,\n" 07317 "%srequested prefs = %s,\n" 07318 "%sactual format = %s,\n" 07319 "%shost prefs = %s,\n" 07320 "%spriority = %s\n", 07321 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07322 VERBOSE_PREFIX_4, 07323 ast_getformatname(iaxs[fr.callno]->peerformat), 07324 VERBOSE_PREFIX_4, 07325 caller_pref_buf, 07326 VERBOSE_PREFIX_4, 07327 ast_getformatname(format), 07328 VERBOSE_PREFIX_4, 07329 host_pref_buf, 07330 VERBOSE_PREFIX_4, 07331 using_prefs); 07332 07333 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07334 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) 07335 iax2_destroy_nolock(fr.callno); 07336 } else { 07337 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 07338 /* If this is a TBD call, we're ready but now what... */ 07339 if (option_verbose > 2) 07340 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07341 } 07342 } 07343 } 07344 break; 07345 case IAX_COMMAND_DIAL: 07346 if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD)) { 07347 ast_clear_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); 07348 ast_copy_string(iaxs[fr.callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr.callno]->exten)); 07349 if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num)) { 07350 if (authdebug) 07351 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); 07352 memset(&ied0, 0, sizeof(ied0)); 07353 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07354 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07355 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07356 } else { 07357 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07358 if (option_verbose > 2) 07359 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); 07360 ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); 07361 send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07362 if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat))) 07363 iax2_destroy_nolock(fr.callno); 07364 } 07365 } 07366 break; 07367 case IAX_COMMAND_INVAL: 07368 iaxs[fr.callno]->error = ENOTCONN; 07369 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno); 07370 iax2_destroy_nolock(fr.callno); 07371 if (option_debug) 07372 ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno); 07373 break; 07374 case IAX_COMMAND_VNAK: 07375 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07376 /* Force retransmission */ 07377 vnak_retransmit(fr.callno, fr.iseqno); 07378 break; 07379 case IAX_COMMAND_REGREQ: 07380 case IAX_COMMAND_REGREL: 07381 /* For security, always ack immediately */ 07382 if (delayreject) 07383 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07384 if (register_verify(fr.callno, &sin, &ies)) { 07385 /* Send delayed failure */ 07386 auth_fail(fr.callno, IAX_COMMAND_REGREJ); 07387 break; 07388 } 07389 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)) { 07390 if (f.subclass == IAX_COMMAND_REGREL) 07391 memset(&sin, 0, sizeof(sin)); 07392 if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd, ies.refresh)) 07393 ast_log(LOG_WARNING, "Registry error\n"); 07394 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07395 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07396 break; 07397 } 07398 registry_authrequest(iaxs[fr.callno]->peer, fr.callno); 07399 break; 07400 case IAX_COMMAND_REGACK: 07401 if (iax2_ack_registry(&ies, &sin, fr.callno)) 07402 ast_log(LOG_WARNING, "Registration failure\n"); 07403 /* Send ack immediately, before we destroy */ 07404 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07405 iax2_destroy_nolock(fr.callno); 07406 break; 07407 case IAX_COMMAND_REGREJ: 07408 if (iaxs[fr.callno]->reg) { 07409 if (authdebug) { 07410 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)); 07411 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>"); 07412 } 07413 iaxs[fr.callno]->reg->regstate = REG_STATE_REJECTED; 07414 } 07415 /* Send ack immediately, before we destroy */ 07416 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07417 iax2_destroy_nolock(fr.callno); 07418 break; 07419 case IAX_COMMAND_REGAUTH: 07420 /* Authentication request */ 07421 if (registry_rerequest(&ies, fr.callno, &sin)) { 07422 memset(&ied0, 0, sizeof(ied0)); 07423 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07424 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07425 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07426 } 07427 break; 07428 case IAX_COMMAND_TXREJ: 07429 iaxs[fr.callno]->transferring = 0; 07430 if (option_verbose > 2) 07431 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>"); 07432 memset(&iaxs[fr.callno]->transfer, 0, sizeof(iaxs[fr.callno]->transfer)); 07433 if (iaxs[fr.callno]->bridgecallno) { 07434 if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring) { 07435 iaxs[iaxs[fr.callno]->bridgecallno]->transferring = 0; 07436 send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07437 } 07438 } 07439 break; 07440 case IAX_COMMAND_TXREADY: 07441 if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { 07442 iaxs[fr.callno]->transferring = TRANSFER_READY; 07443 if (option_verbose > 2) 07444 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>"); 07445 if (iaxs[fr.callno]->bridgecallno) { 07446 if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring == TRANSFER_READY) { 07447 if (option_verbose > 2) 07448 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>", 07449 iaxs[iaxs[fr.callno]->bridgecallno]->owner ? iaxs[iaxs[fr.callno]->bridgecallno]->owner->name : "<Unknown>"); 07450 07451 /* They're both ready, now release them. */ 07452 iaxs[iaxs[fr.callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07453 iaxs[fr.callno]->transferring = TRANSFER_RELEASED; 07454 ast_set_flag(iaxs[iaxs[fr.callno]->bridgecallno], IAX_ALREADYGONE); 07455 ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 07456 07457 /* Stop doing lag & ping requests */ 07458 stop_stuff(fr.callno); 07459 stop_stuff(iaxs[fr.callno]->bridgecallno); 07460 07461 memset(&ied0, 0, sizeof(ied0)); 07462 memset(&ied1, 0, sizeof(ied1)); 07463 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr.callno]->bridgecallno]->peercallno); 07464 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->peercallno); 07465 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07466 send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07467 07468 } 07469 } 07470 } 07471 break; 07472 case IAX_COMMAND_TXREQ: 07473 try_transfer(iaxs[fr.callno], &ies); 07474 break; 07475 case IAX_COMMAND_TXCNT: 07476 if (iaxs[fr.callno]->transferring) 07477 send_command_transfer(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07478 break; 07479 case IAX_COMMAND_TXREL: 07480 /* Send ack immediately, rather than waiting until we've changed addresses */ 07481 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07482 complete_transfer(fr.callno, &ies); 07483 stop_stuff(fr.callno); /* for attended transfer to work with libiax */ 07484 break; 07485 case IAX_COMMAND_DPREP: 07486 complete_dpreply(iaxs[fr.callno], &ies); 07487 break; 07488 case IAX_COMMAND_UNSUPPORT: 07489 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07490 break; 07491 case IAX_COMMAND_FWDOWNL: 07492 /* Firmware download */ 07493 memset(&ied0, 0, sizeof(ied0)); 07494 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07495 if (res < 0) 07496 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07497 else if (res > 0) 07498 send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07499 else 07500 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07501 break; 07502 default: 07503 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno); 07504 memset(&ied0, 0, sizeof(ied0)); 07505 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07506 send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07507 } 07508 /* Don't actually pass these frames along */ 07509 if ((f.subclass != IAX_COMMAND_ACK) && 07510 (f.subclass != IAX_COMMAND_TXCNT) && 07511 (f.subclass != IAX_COMMAND_TXACC) && 07512 (f.subclass != IAX_COMMAND_INVAL) && 07513 (f.subclass != IAX_COMMAND_VNAK)) { 07514 if (iaxs[fr.callno] && iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) 07515 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07516 } 07517 ast_mutex_unlock(&iaxsl[fr.callno]); 07518 return 1; 07519 } 07520 /* Unless this is an ACK or INVAL frame, ack it */ 07521 if (iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) 07522 send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); 07523 } else if (minivid) { 07524 f.frametype = AST_FRAME_VIDEO; 07525 if (iaxs[fr.callno]->videoformat > 0) 07526 f.subclass = iaxs[fr.callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07527 else { 07528 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07529 iax2_vnak(fr.callno); 07530 ast_mutex_unlock(&iaxsl[fr.callno]); 07531 return 1; 07532 } 07533 f.datalen = res - sizeof(struct ast_iax2_video_hdr); 07534 if (f.datalen) 07535 f.data = buf + sizeof(struct ast_iax2_video_hdr); 07536 else 07537 f.data = NULL; 07538 #ifdef IAXTESTS 07539 if (test_resync) { 07540 fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); 07541 } else 07542 #endif /* IAXTESTS */ 07543 fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); 07544 } else { 07545 /* A mini frame */ 07546 f.frametype = AST_FRAME_VOICE; 07547 if (iaxs[fr.callno]->voiceformat > 0) 07548 f.subclass = iaxs[fr.callno]->voiceformat; 07549 else { 07550 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07551 iax2_vnak(fr.callno); 07552 ast_mutex_unlock(&iaxsl[fr.callno]); 07553 return 1; 07554 } 07555 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07556 if (f.datalen < 0) { 07557 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07558 ast_mutex_unlock(&iaxsl[fr.callno]); 07559 return 1; 07560 } 07561 if (f.datalen) 07562 f.data = buf + sizeof(struct ast_iax2_mini_hdr); 07563 else 07564 f.data = NULL; 07565 #ifdef IAXTESTS 07566 if (test_resync) { 07567 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07568 } else 07569 #endif /* IAXTESTS */ 07570 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07571 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07572 } 07573 /* Don't pass any packets until we're started */ 07574 if (!ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { 07575 ast_mutex_unlock(&iaxsl[fr.callno]); 07576 return 1; 07577 } 07578 /* Common things */ 07579 f.src = "IAX2"; 07580 f.mallocd = 0; 07581 f.offset = 0; 07582 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07583 f.samples = ast_codec_get_samples(&f); 07584 /* We need to byteswap incoming slinear samples from network byte order */ 07585 if (f.subclass == AST_FORMAT_SLINEAR) 07586 ast_frame_byteswap_be(&f); 07587 } else 07588 f.samples = 0; 07589 iax_frame_wrap(&fr, &f); 07590 07591 /* If this is our most recent packet, use it as our basis for timestamping */ 07592 if (iaxs[fr.callno]->last < fr.ts) { 07593 /*iaxs[fr.callno]->last = fr.ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07594 fr.outoforder = 0; 07595 } else { 07596 if (option_debug && iaxdebug) 07597 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); 07598 fr.outoforder = -1; 07599 } 07600 #ifdef BRIDGE_OPTIMIZATION 07601 if (iaxs[fr.callno]->bridgecallno) { 07602 forward_delivery(&fr); 07603 } else { 07604 duped_fr = iaxfrdup2(&fr); 07605 if (duped_fr) { 07606 schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); 07607 } 07608 } 07609 #else 07610 duped_fr = iaxfrdup2(&fr); 07611 if (duped_fr) { 07612 schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); 07613 } 07614 #endif 07615 07616 if (iaxs[fr.callno]->last < fr.ts) { 07617 iaxs[fr.callno]->last = fr.ts; 07618 #if 1 07619 if (option_debug && iaxdebug) 07620 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); 07621 #endif 07622 } 07623 07624 /* Always run again */ 07625 ast_mutex_unlock(&iaxsl[fr.callno]); 07626 return 1; 07627 }
|
|
Definition at line 6109 of file chan_iax2.c. References ast_log(), ast_pthread_create, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, context, dpreq_data::context, dp_lookup_thread(), LOG_WARNING, malloc, and strdup. Referenced by socket_read(). 06110 { 06111 pthread_t newthread; 06112 struct dpreq_data *dpr; 06113 dpr = malloc(sizeof(struct dpreq_data)); 06114 if (dpr) { 06115 memset(dpr, 0, sizeof(struct dpreq_data)); 06116 dpr->callno = callno; 06117 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06118 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06119 if (callerid) 06120 dpr->callerid = strdup(callerid); 06121 if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) { 06122 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06123 } 06124 } else 06125 ast_log(LOG_WARNING, "Out of memory!\n"); 06126 }
|
|
Definition at line 7993 of file chan_iax2.c. References ast_pthread_create, netthreadid, and network_thread(). Referenced by load_module(). 07994 { 07995 return ast_pthread_create(&netthreadid, NULL, network_thread, NULL); 07996 }
|
|
Definition at line 5807 of file chan_iax2.c. References ast_sched_del(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iaxs, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, chan_iax2_pvt::pingid, and sched. Referenced by socket_read(). 05808 { 05809 if (iaxs[callno]->lagid > -1) 05810 ast_sched_del(sched, iaxs[callno]->lagid); 05811 iaxs[callno]->lagid = -1; 05812 if (iaxs[callno]->pingid > -1) 05813 ast_sched_del(sched, iaxs[callno]->pingid); 05814 iaxs[callno]->pingid = -1; 05815 if (iaxs[callno]->autoid > -1) 05816 ast_sched_del(sched, iaxs[callno]->autoid); 05817 iaxs[callno]->autoid = -1; 05818 if (iaxs[callno]->initid > -1) 05819 ast_sched_del(sched, iaxs[callno]->initid); 05820 iaxs[callno]->initid = -1; 05821 if (iaxs[callno]->authid > -1) 05822 ast_sched_del(sched, iaxs[callno]->authid); 05823 iaxs[callno]->authid = -1; 05824 #ifdef NEWJB 05825 if (iaxs[callno]->jbid > -1) 05826 ast_sched_del(sched, iaxs[callno]->jbid); 05827 iaxs[callno]->jbid = -1; 05828 #endif 05829 return 0; 05830 }
|
|
Definition at line 5982 of file chan_iax2.c. References iax2_trunk_peer::addr, ast_inet_ntoa(), 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_DEBUG, 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(). 05983 { 05984 char buf[1024]; 05985 int res; 05986 char iabuf[INET_ADDRSTRLEN]; 05987 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 05988 int processed = 0; 05989 int totalcalls = 0; 05990 #ifdef ZT_TIMERACK 05991 int x = 1; 05992 #endif 05993 struct timeval now; 05994 if (iaxtrunkdebug) 05995 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 05996 gettimeofday(&now, NULL); 05997 if (events & AST_IO_PRI) { 05998 #ifdef ZT_TIMERACK 05999 /* Great, this is a timing interface, just call the ioctl */ 06000 if (ioctl(fd, ZT_TIMERACK, &x)) 06001 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06002 res = 0; 06003 #endif 06004 } else { 06005 /* Read and ignore from the pseudo channel for timing */ 06006 res = read(fd, buf, sizeof(buf)); 06007 if (res < 1) { 06008 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06009 ast_mutex_unlock(&peerl.lock); 06010 return 1; 06011 } 06012 } 06013 /* For each peer that supports trunking... */ 06014 ast_mutex_lock(&tpeerlock); 06015 tpeer = tpeers; 06016 while(tpeer) { 06017 processed++; 06018 res = 0; 06019 ast_mutex_lock(&tpeer->lock); 06020 /* We can drop a single tpeer per pass. That makes all this logic 06021 substantially easier */ 06022 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06023 /* Take it out of the list, but don't free it yet, because it 06024 could be in use */ 06025 if (prev) 06026 prev->next = tpeer->next; 06027 else 06028 tpeers = tpeer->next; 06029 drop = tpeer; 06030 } else { 06031 res = send_trunk(tpeer, &now); 06032 if (iaxtrunkdebug) 06033 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); 06034 } 06035 totalcalls += res; 06036 res = 0; 06037 ast_mutex_unlock(&tpeer->lock); 06038 prev = tpeer; 06039 tpeer = tpeer->next; 06040 } 06041 ast_mutex_unlock(&tpeerlock); 06042 if (drop) { 06043 ast_mutex_lock(&drop->lock); 06044 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06045 because by the time they could get tpeerlock, we've already grabbed it */ 06046 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)); 06047 free(drop->trunkdata); 06048 ast_mutex_unlock(&drop->lock); 06049 ast_mutex_destroy(&drop->lock); 06050 free(drop); 06051 06052 } 06053 if (iaxtrunkdebug) 06054 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06055 iaxtrunkdebug =0; 06056 return 1; 06057 }
|
|
Definition at line 1469 of file chan_iax2.c. References ast_log(), iax_frame::data, iax_frame::datalen, handle_error(), and LOG_DEBUG. Referenced by send_trunk(). 01470 { 01471 int res; 01472 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01473 sizeof(*sin)); 01474 if (res < 0) { 01475 if (option_debug) 01476 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01477 handle_error(); 01478 } else 01479 res = 0; 01480 return res; 01481 }
|
|
Definition at line 1151 of file chan_iax2.c. References ast_log(), ast_strlen_zero(), 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, LOG_WARNING, malloc, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, s, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl. Referenced by reload_firmware(). 01152 { 01153 struct stat stbuf; 01154 struct iax_firmware *cur; 01155 int ifd; 01156 int fd; 01157 int res; 01158 01159 struct ast_iax2_firmware_header *fwh, fwh2; 01160 struct MD5Context md5; 01161 unsigned char sum[16]; 01162 unsigned char buf[1024]; 01163 int len, chunk; 01164 char *s2; 01165 char *last; 01166 s2 = alloca(strlen(s) + 100); 01167 if (!s2) { 01168 ast_log(LOG_WARNING, "Alloca failed!\n"); 01169 return -1; 01170 } 01171 last = strrchr(s, '/'); 01172 if (last) 01173 last++; 01174 else 01175 last = s; 01176 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand()); 01177 res = stat(s, &stbuf); 01178 if (res < 0) { 01179 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01180 return -1; 01181 } 01182 /* Make sure it's not a directory */ 01183 if (S_ISDIR(stbuf.st_mode)) 01184 return -1; 01185 ifd = open(s, O_RDONLY); 01186 if (ifd < 0) { 01187 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01188 return -1; 01189 } 01190 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01191 if (fd < 0) { 01192 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01193 close(ifd); 01194 return -1; 01195 } 01196 /* Unlink our newly created file */ 01197 unlink(s2); 01198 01199 /* Now copy the firmware into it */ 01200 len = stbuf.st_size; 01201 while(len) { 01202 chunk = len; 01203 if (chunk > sizeof(buf)) 01204 chunk = sizeof(buf); 01205 res = read(ifd, buf, chunk); 01206 if (res != chunk) { 01207 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01208 close(ifd); 01209 close(fd); 01210 return -1; 01211 } 01212 res = write(fd, buf, chunk); 01213 if (res != chunk) { 01214 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01215 close(ifd); 01216 close(fd); 01217 return -1; 01218 } 01219 len -= chunk; 01220 } 01221 close(ifd); 01222 /* Return to the beginning */ 01223 lseek(fd, 0, SEEK_SET); 01224 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01225 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01226 close(fd); 01227 return -1; 01228 } 01229 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01230 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01231 close(fd); 01232 return -1; 01233 } 01234 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01235 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01236 close(fd); 01237 return -1; 01238 } 01239 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01240 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01241 close(fd); 01242 return -1; 01243 } 01244 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01245 if (!fwh) { 01246 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01247 close(fd); 01248 return -1; 01249 } 01250 MD5Init(&md5); 01251 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01252 MD5Final(sum, &md5); 01253 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01254 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01255 munmap(fwh, stbuf.st_size); 01256 close(fd); 01257 return -1; 01258 } 01259 cur = waresl.wares; 01260 while(cur) { 01261 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01262 /* Found a candidate */ 01263 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01264 /* The version we have on loaded is older, load this one instead */ 01265 break; 01266 /* This version is no newer than what we have. Don't worry about it. 01267 We'll consider it a proper load anyhow though */ 01268 munmap(fwh, stbuf.st_size); 01269 close(fd); 01270 return 0; 01271 } 01272 cur = cur->next; 01273 } 01274 if (!cur) { 01275 /* Allocate a new one and link it */ 01276 cur = malloc(sizeof(struct iax_firmware)); 01277 if (cur) { 01278 memset(cur, 0, sizeof(struct iax_firmware)); 01279 cur->fd = -1; 01280 cur->next = waresl.wares; 01281 waresl.wares = cur; 01282 } 01283 } 01284 if (cur) { 01285 if (cur->fwh) { 01286 munmap(cur->fwh, cur->mmaplen); 01287 } 01288 if (cur->fd > -1) 01289 close(cur->fd); 01290 cur->fwh = fwh; 01291 cur->fd = fd; 01292 cur->mmaplen = stbuf.st_size; 01293 cur->dead = 0; 01294 } 01295 return 0; 01296 }
|
|
Definition at line 5286 of file chan_iax2.c. References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, iax_ies::transferid, and chan_iax2_pvt::transferid. Referenced by socket_read(). 05287 { 05288 int newcall = 0; 05289 char newip[256]; 05290 struct iax_ie_data ied; 05291 struct sockaddr_in new; 05292 05293 05294 memset(&ied, 0, sizeof(ied)); 05295 if (ies->apparent_addr) 05296 memcpy(&new, ies->apparent_addr, sizeof(new)); 05297 if (ies->callno) 05298 newcall = ies->callno; 05299 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05300 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05301 return -1; 05302 } 05303 pvt->transfercallno = newcall; 05304 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05305 inet_aton(newip, &pvt->transfer.sin_addr); 05306 pvt->transfer.sin_family = AF_INET; 05307 pvt->transferring = TRANSFER_BEGIN; 05308 pvt->transferid = ies->transferid; 05309 if (ies->transferid) 05310 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05311 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05312 return 0; 05313 }
|
|
Definition at line 829 of file chan_iax2.c. References IAX_FLAG_SC_LOG. Referenced by decode_frame(), and socket_read(). 00830 { 00831 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 00832 if (csub & IAX_FLAG_SC_LOG) { 00833 /* special case for 'compressed' -1 */ 00834 if (csub == 0xff) 00835 return -1; 00836 else 00837 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 00838 } 00839 else 00840 return csub; 00841 }
|
|
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 9523 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. 09524 { 09525 ast_mutex_destroy(&iaxq.lock); 09526 ast_mutex_destroy(&userl.lock); 09527 ast_mutex_destroy(&peerl.lock); 09528 ast_mutex_destroy(&waresl.lock); 09529 ast_custom_function_unregister(&iaxpeer_function); 09530 return __unload_module(); 09531 }
|
|
Definition at line 3160 of file chan_iax2.c. References ast_mutex_unlock(), and iaxsl. Referenced by iax2_bridge(). 03161 { 03162 ast_mutex_unlock(&iaxsl[callno1]); 03163 ast_mutex_unlock(&iaxsl[callno0]); 03164 }
|
|
Definition at line 2117 of file chan_iax2.c. References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts. Referenced by schedule_delivery(). 02118 { 02119 int x; 02120 02121 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02122 x = fr->ts - iaxs[fr->callno]->last; 02123 if (x < -50000) { 02124 /* Sudden big jump backwards in timestamp: 02125 What likely happened here is that miniframe timestamp has circled but we haven't 02126 gotten the update from the main packet. We'll just pretend that we did, and 02127 update the timestamp appropriately. */ 02128 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02129 if (option_debug && iaxdebug) 02130 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02131 } 02132 if (x > 50000) { 02133 /* Sudden apparent big jump forwards in timestamp: 02134 What's likely happened is this is an old miniframe belonging to the previous 02135 top-16-bit timestamp that has turned up out of order. 02136 Adjust the timestamp appropriately. */ 02137 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02138 if (option_debug && iaxdebug) 02139 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02140 } 02141 } 02142 }
|
|
Definition at line 2147 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, chan_iax2_pvt::rxcore, and sched. Referenced by get_from_jb(), and schedule_delivery(). 02147 { 02148 int when; 02149 02150 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02151 02152 /* fprintf(stderr, "now = %d, next=%d\n", when, jb_next(pvt->jb)); */ 02153 02154 when = jb_next(pvt->jb) - when; 02155 /* fprintf(stderr, "when = %d\n", when); */ 02156 02157 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02158 02159 if(when <= 0) { 02160 /* XXX should really just empty until when > 0.. */ 02161 when = 1; 02162 } 02163 02164 pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt); 02165 }
|
|
Definition at line 978 of file chan_iax2.c. References ast_log(), iaxs, LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START. Referenced by find_callno(), and make_trunk(). 00979 { 00980 int max = 1; 00981 int x; 00982 /* XXX Prolly don't need locks here XXX */ 00983 for (x=1;x<TRUNK_CALL_START - 1; x++) { 00984 if (iaxs[x]) 00985 max = x + 1; 00986 } 00987 maxnontrunkcall = max; 00988 if (option_debug && iaxdebug) 00989 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 00990 }
|
|
Definition at line 964 of file chan_iax2.c. References ast_log(), IAX_MAX_CALLS, iaxs, LOG_DEBUG, maxtrunkcall, and option_debug. Referenced by iax2_destroy(), and make_trunk(). 00965 { 00966 int max = TRUNK_CALL_START; 00967 int x; 00968 /* XXX Prolly don't need locks here XXX */ 00969 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 00970 if (iaxs[x]) 00971 max = x + 1; 00972 } 00973 maxtrunkcall = max; 00974 if (option_debug && iaxdebug) 00975 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 00976 }
|
|
Definition at line 1681 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(). 01682 { 01683 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 01684 struct ast_iax2_full_hdr *fh = f->data; 01685 /* Mark this as a retransmission */ 01686 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 01687 /* Update iseqno */ 01688 f->iseqno = iaxs[f->callno]->iseqno; 01689 fh->iseqno = f->iseqno; 01690 return 0; 01691 }
|
|
Definition at line 5634 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, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), max_reg_expire, min_reg_expire, iax2_peer::name, name, option_verbose, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3. Referenced by socket_read(). 05635 { 05636 /* Called from IAX thread only, with proper iaxsl lock */ 05637 struct iax_ie_data ied; 05638 struct iax2_peer *p; 05639 int msgcount; 05640 char data[80]; 05641 char iabuf[INET_ADDRSTRLEN]; 05642 int version; 05643 05644 memset(&ied, 0, sizeof(ied)); 05645 05646 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05647 if (!(p = find_peer(name, 1))) { 05648 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05649 return -1; 05650 } 05651 05652 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05653 realtime_update_peer(name, sin); 05654 if (inaddrcmp(&p->addr, sin)) { 05655 if (iax2_regfunk) 05656 iax2_regfunk(p->name, 1); 05657 /* Stash the IP address from which they registered */ 05658 memcpy(&p->addr, sin, sizeof(p->addr)); 05659 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05660 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05661 ast_db_put("IAX/Registry", p->name, data); 05662 if (option_verbose > 2) 05663 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05664 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 05665 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05666 register_peer_exten(p, 1); 05667 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05668 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05669 if (option_verbose > 2) 05670 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05671 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05672 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05673 register_peer_exten(p, 0); 05674 ast_db_del("IAX/Registry", p->name); 05675 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05676 } 05677 /* Update the host */ 05678 /* Verify that the host is really there */ 05679 iax2_poke_peer(p, callno); 05680 } 05681 /* Store socket fd */ 05682 p->sockfd = fd; 05683 /* Setup the expiry */ 05684 if (p->expire > -1) 05685 ast_sched_del(sched, p->expire); 05686 /* treat an unspecified refresh interval as the minimum */ 05687 if (!refresh) 05688 refresh = min_reg_expire; 05689 if (refresh > max_reg_expire) { 05690 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05691 p->name, max_reg_expire, refresh); 05692 p->expiry = max_reg_expire; 05693 } else if (refresh < min_reg_expire) { 05694 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05695 p->name, min_reg_expire, refresh); 05696 p->expiry = min_reg_expire; 05697 } else { 05698 p->expiry = refresh; 05699 } 05700 if (p->expiry && sin->sin_addr.s_addr) 05701 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05702 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05703 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05704 if (sin->sin_addr.s_addr) { 05705 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05706 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05707 if (!ast_strlen_zero(p->mailbox)) { 05708 if (ast_test_flag(p, IAX_MESSAGEDETAIL)) { 05709 int new, old; 05710 ast_app_messagecount(p->mailbox, &new, &old); 05711 if (new > 255) 05712 new = 255; 05713 if (old > 255) 05714 old = 255; 05715 msgcount = (old << 8) | new; 05716 } else { 05717 msgcount = ast_app_has_voicemail(p->mailbox, NULL); 05718 if (msgcount) 05719 msgcount = 65535; 05720 } 05721 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05722 } 05723 if (ast_test_flag(p, IAX_HASCALLERID)) { 05724 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05725 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05726 } 05727 } 05728 version = iax_check_version(devtype); 05729 if (version) 05730 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05731 if (ast_test_flag(p, IAX_TEMPONLY)) 05732 destroy_peer(p); 05733 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05734 }
|
|
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 9651 of file chan_iax2.c. 09652 {
09653 return usecnt;
09654 }
|
|
Definition at line 5907 of file chan_iax2.c. References ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, ast_iax2_queue::head, iaxq, iaxs, ast_iax2_queue::lock, iax_frame::next, iax_frame::oseqno, and send_packet(). Referenced by socket_read(). 05908 { 05909 struct iax_frame *f; 05910 ast_mutex_lock(&iaxq.lock); 05911 f = iaxq.head; 05912 while(f) { 05913 /* Send a copy immediately */ 05914 if ((f->callno == callno) && iaxs[f->callno] && 05915 (f->oseqno >= last)) { 05916 send_packet(f); 05917 } 05918 f = f->next; 05919 } 05920 ast_mutex_unlock(&iaxq.lock); 05921 }
|
|
Definition at line 223 of file chan_iax2.c. Referenced by check_access(), find_callno(), and set_config(). |
|
Definition at line 224 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 161 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 162 of file chan_iax2.c. Referenced by iax2_call(), and set_config(). |
|
Definition at line 142 of file chan_iax2.c. Referenced by load_module(), register_peer_exten(), and set_config(). |
|
Definition at line 144 of file chan_iax2.c. Referenced by apply_context(), build_context(), check_access(), dp_lookup(), iax2_call(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_users(), iax2_transfer(), and spawn_dp_lookup(). |
|
Initial value: "Usage: iax2 jb debug\n" " Enables jitterbuffer debugging information\n" Definition at line 9422 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9414 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 debug\n" " Enables dumping of IAX packets for debugging purposes\n" Definition at line 9406 of file chan_iax2.c. |
|
Definition at line 177 of file chan_iax2.c. Referenced by iax2_do_register(), load_module(), and set_config(). |
|
Definition at line 225 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 140 of file chan_iax2.c. Referenced by iax_firmware_append(). |
|
Referenced by find_cache(). |
|
Definition at line 269 of file chan_iax2.c. Referenced by realtime_peer(), and set_config(). |
|
Definition at line 228 of file chan_iax2.c. Referenced by build_peer(), build_user(), find_callno(), iax2_request(), iax2_trunk_queue(), realtime_peer(), realtime_user(), send_trunk(), set_config(), and update_registry(). |
|
Definition at line 207 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 9448 of file chan_iax2.c. Referenced by __unload_module(), and load_module(). |
|
Definition at line 209 of file chan_iax2.c. Referenced by schedule_delivery(), and set_config(). |
|
Definition at line 226 of file chan_iax2.c. Referenced by set_config(). |
|
|
|
Definition at line 182 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 9368 of file chan_iax2.c. |
|
|
|
Definition at line 9342 of file chan_iax2.c. Referenced by __unload_module(), and load_module(). |
|
Definition at line 745 of file chan_iax2.c. Referenced by __unload_module(), and load_module(). |
|
Initial value: "Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n" Definition at line 9430 of file chan_iax2.c. |
|
Definition at line 163 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 211 of file chan_iax2.c. Referenced by calc_timestamp(), iax2_bridge(), iax2_do_debug(), iax2_no_debug(), and socket_read(). |
|
Definition at line 165 of file chan_iax2.c. Referenced by dp_lookup(). |
|
Definition at line 167 of file chan_iax2.c. Referenced by find_cache(). |
|
Definition at line 9269 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 213 of file chan_iax2.c. Referenced by iax2_do_trunk_debug(), iax2_no_trunk_debug(), and timing_read(). |
|
Definition at line 204 of file chan_iax2.c. Referenced by load_module(), network_thread(), and set_config(). |
|
Definition at line 1812 of file chan_iax2.c. |
|
Definition at line 159 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 151 of file chan_iax2.c. Referenced by find_callno(), make_trunk(), and set_config(). |
|
Definition at line 146 of file chan_iax2.c. Referenced by build_user(), check_access(), and set_config(). |
|
Definition at line 711 of file chan_iax2.c. Referenced by find_callno(), iax2_destroy(), and make_trunk(). |
|
Definition at line 425 of file chan_iax2.c. Referenced by iax2_set_jitter(), and set_config(). |
|
Definition at line 172 of file chan_iax2.c. Referenced by set_config(), and update_registry(). |
|
Definition at line 149 of file chan_iax2.c. |
|
Definition at line 154 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 157 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 153 of file chan_iax2.c. Referenced by update_max_nontrunk(). |
|
Definition at line 152 of file chan_iax2.c. Referenced by update_max_trunk(). |
|
Definition at line 427 of file chan_iax2.c. Referenced by set_config(). |
|
Definition at line 171 of file chan_iax2.c. Referenced by set_config(), and update_registry(). |
|
Definition at line 176 of file chan_iax2.c. Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config(). |
|
Definition at line 230 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 9426 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no trunk debug\n" " Requests current status of IAX trunking\n" Definition at line 9418 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 no debug\n" " Disables dumping of IAX packets for debugging purposes\n" Definition at line 9410 of file chan_iax2.c. |
|
Definition at line 7716 of file chan_iax2.c. Referenced by __unload_module(), and load_module(). |
|
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 7718 of file chan_iax2.c. Referenced by load_module(). |
|
|
Definition at line 150 of file chan_iax2.c. Referenced by find_callno(), make_trunk(), and set_config(). |
|
Definition at line 138 of file chan_iax2.c. Referenced by check_access(), create_addr(), and set_config(). |
|
Initial value: "Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n" Definition at line 9364 of file chan_iax2.c. |
|
Definition at line 7717 of file chan_iax2.c. Referenced by load_module(). |
|
Definition at line 147 of file chan_iax2.c. Referenced by register_peer_exten(), and set_config(). |
|
Definition at line 407 of file chan_iax2.c. Referenced by delete_users(), and iax2_register(). |
|
Definition at line 156 of file chan_iax2.c. Referenced by set_config(). |
|
|
Initial value: "Usage: iax show cache\n" " Display currently cached IAX Dialplan results.\n" Definition at line 9356 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show channels\n" " Lists all currently active IAX channels.\n" Definition at line 9384 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show firmware\n" " Lists all known IAX firmware images.\n" Definition at line 9398 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 9388 of file chan_iax2.c. |
|
Initial value: "Usage: iax show peer <name>\n" " Display details on specific IAX peer\n" Definition at line 9360 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 9392 of file chan_iax2.c. |
|
Definition at line 9372 of file chan_iax2.c. |
|
Initial value: "Usage: iax2 show registry\n" " Lists all registration requests and status.\n" Definition at line 9402 of file chan_iax2.c. |
|
Initial value: "Usage: iax show stats\n" " Display statistics on IAX channel driver.\n" Definition at line 9352 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 9379 of file chan_iax2.c. |
|
Definition at line 141 of file chan_iax2.c. |
|
Definition at line 215 of file chan_iax2.c. Referenced by iax2_test_losspct(). |
|
Definition at line 174 of file chan_iax2.c. Referenced by build_peer(), build_user(), load_module(), network_thread(), and set_timing(). |
|
Definition at line 169 of file chan_iax2.c. Referenced by load_module(), and set_config(). |
|
Referenced by find_tpeer(), and timing_read(). |
|
Definition at line 160 of file chan_iax2.c. Referenced by send_trunk(), set_config(), and set_timing(). |
|
Definition at line 179 of file chan_iax2.c. Referenced by ast_iax2_new(), and iax2_predestroy(). |
|
Referenced by build_user(), check_access(), delete_users(), iax2_show_users(), load_module(), prune_users(), realtime_user(), set_config(), and unload_module(). |
|
Referenced by iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), try_firmware(), and unload_module(). |