#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "../jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | ast_peer_list |
The peer list: Peers and Friends ---. More... | |
struct | ast_user_list |
The user list: Users and friends ---. More... | |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_registry |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | FREE free |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | NEWJB |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | TRUNK_CALL_START 0x4000 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_MESSAGEDETAIL = (1 << 8), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_MAXAUTHREQ = (1 << 23) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH } |
Functions | |
static int | __do_deliver (void *data) |
static int | __iax2_show_peers (int manager, int fd, int argc, char *argv[]) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static int | __unload_module (void) |
static int | apply_context (struct iax2_context *con, char *context) |
static int | ast_cli_netstats (int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static int | attempt_transmit (void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (void *nothing) |
static int | authenticate (char *challenge, char *secret, char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey) |
static int | authenticate_request (struct chan_iax2_pvt *p) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (void *nothing) |
static int | auto_hangup (void *nothing) |
static struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, int temponly) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, int temponly) |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (char *line, char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | delete_users (void) |
char * | description () |
Provides a description of the module. | |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | destroy_peer (struct iax2_peer *peer) |
static void | destroy_user (struct iax2_user *user) |
static void | dp_lookup (int callno, char *context, char *callednum, char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static char * | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (void *p) |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static unsigned int | iax2_datetime (char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_nolock (int callno) |
static int | iax2_devicestate (void *data) |
static int | iax2_digit (struct ast_channel *c, char digit) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data) |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_s (void *data) |
static int | iax2_predestroy (int callno) |
static int | iax2_predestroy_nolock (int callno) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (char *line, char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_set_jitter (int fd, int argc, char *argv[]) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, int lockpeer, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (char *name, int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
static void | reload_firmware (void) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
static void | set_timing (void) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid) |
static int | start_network_thread (void) |
static int | stop_stuff (int callno) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
int | usecount () |
Provides a usecount. | |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static const char | channeltype [] = "IAX2" |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static const char | desc [] = "Inter Asterisk eXchange (Ver 2)" |
static struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static struct ast_cli_entry | iax2_cli [] |
static int | iax2_dropcount = DEFAULT_DROP |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(*) | iax2_regfunk (char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static char | jitter_usage [] |
static int | jittershrinkrate = 2 |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static struct timeval | lastused [IAX_MAX_CALLS] |
static int | max_jitter_buffer = MAX_JITTER_BUFFER |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 0 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_jitter_buffer = MIN_JITTER_BUFFER |
static int | min_reg_expire |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ast_peer_list | peerl |
static int | ping_time = 20 |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static struct iax2_registry * | registrations |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static char | show_cache_usage [] |
static char | show_channels_usage [] |
static char | show_firmware_usage [] |
static char | show_netstats_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_prov_usage [] |
static char | show_reg_usage [] |
static char | show_stats_usage [] |
static char | show_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static int | tos = 0 |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static int | usecnt |
static struct ast_user_list | userl |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 634 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache().
#define CACHE_FLAG_EXISTS (1 << 0) |
Extension exists
Definition at line 630 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache().
#define CACHE_FLAG_MATCHMORE (1 << 7) |
Matchmore
Definition at line 644 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache().
#define CACHE_FLAG_NONEXISTENT (1 << 1) |
Extension is nonexistent
Definition at line 632 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CACHE_FLAG_PENDING (1 << 3) |
Waiting to hear back response
Definition at line 636 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TIMEOUT (1 << 4) |
Timed out
Definition at line 638 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 640 of file chan_iax2.c.
Referenced by iax2_dprequest(), iax2_show_cache(), and socket_read().
#define CACHE_FLAG_UNKNOWN (1 << 6) |
Timeout
Definition at line 642 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
#define DEBUG_SUPPORT |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 127 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 204 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 203 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAXMS 2000 |
Definition at line 202 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 421 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#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" |
Referenced by iax2_show_channels().
#define FREE free |
Definition at line 672 of file chan_iax2.c.
Referenced by __build_step(), ast_park_call(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), pbx_load_module(), and register_peer_exten().
#define GAMMA (0.01) |
Definition at line 137 of file chan_iax2.c.
#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 |
Definition at line 187 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 198 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW)
Definition at line 189 of file chan_iax2.c.
Referenced by set_config().
#define IPTOS_MINCOST 0x02 |
Definition at line 106 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 418 of file chan_iax2.c.
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 424 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 422 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MEMORY_SIZE 100 |
#define MIN_JITTER_BUFFER 10 |
Definition at line 419 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define NEW_ALLOW 1 |
#define NEW_FORCE 2 |
Definition at line 959 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request().
#define NEW_PREVENT 0 |
#define NEWJB |
Definition at line 99 of file chan_iax2.c.
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 122 of file chan_iax2.c.
Referenced by auto_congest(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().
#define TRUNK_CALL_START 0x4000 |
Definition at line 130 of file chan_iax2.c.
Referenced by find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
anonymous enum |
Definition at line 234 of file chan_iax2.c.
00234 { 00235 IAX_STATE_STARTED = (1 << 0), 00236 IAX_STATE_AUTHENTICATED = (1 << 1), 00237 IAX_STATE_TBD = (1 << 2) 00238 } iax2_state;
anonymous enum |
Definition at line 245 of file chan_iax2.c.
00245 { 00246 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00247 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00248 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00249 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00250 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00251 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00252 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00253 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00254 IAX_MESSAGEDETAIL = (1 << 8), /*!< Show exact numbers */ 00255 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00256 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00257 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00258 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00259 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00260 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00261 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00262 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00263 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00264 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00265 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00266 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00267 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00268 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00269 IAX_MAXAUTHREQ = (1 << 23) /*!< Maximum outstanding AUTHREQ restriction is in place */ 00270 } iax2_flags;
enum iax_reg_state |
REG_STATE_UNREGISTERED | |
REG_STATE_REGSENT | |
REG_STATE_AUTHSENT | |
REG_STATE_REGISTERED | |
REG_STATE_REJECTED | |
REG_STATE_TIMEOUT | |
REG_STATE_NOAUTH |
Definition at line 380 of file chan_iax2.c.
00380 { 00381 REG_STATE_UNREGISTERED = 0, 00382 REG_STATE_REGSENT, 00383 REG_STATE_AUTHSENT, 00384 REG_STATE_REGISTERED, 00385 REG_STATE_REJECTED, 00386 REG_STATE_TIMEOUT, 00387 REG_STATE_NOAUTH 00388 };
enum iax_transfer_state |
Definition at line 390 of file chan_iax2.c.
00390 { 00391 TRANSFER_NONE = 0, 00392 TRANSFER_BEGIN, 00393 TRANSFER_READY, 00394 TRANSFER_RELEASED, 00395 TRANSFER_PASSTHROUGH 00396 };
static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 1424 of file chan_iax2.c.
References iax_frame::af, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by get_from_jb().
01425 { 01426 /* Just deliver the packet by using queueing. This is called by 01427 the IAX thread with the iaxsl lock held. */ 01428 struct iax_frame *fr = data; 01429 fr->retrans = -1; 01430 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01431 iax2_queue_frame(fr->callno, &fr->af); 01432 /* Free our iax frame */ 01433 iax2_frame_free(fr); 01434 /* And don't run again */ 01435 return 0; 01436 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4209 of file chan_iax2.c.
References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, ast_peer_list::lock, iax2_peer::mask, iax2_peer::name, name, iax2_peer::next, peer_status(), peerl, ast_peer_list::peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::username.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04210 { 04211 regex_t regexbuf; 04212 int havepattern = 0; 04213 int total_peers = 0; 04214 int online_peers = 0; 04215 int offline_peers = 0; 04216 int unmonitored_peers = 0; 04217 04218 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04219 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04220 04221 struct iax2_peer *peer; 04222 char name[256]; 04223 char iabuf[INET_ADDRSTRLEN]; 04224 int registeredonly=0; 04225 char *term = manager ? "\r\n" : "\n"; 04226 04227 switch (argc) { 04228 case 6: 04229 if (!strcasecmp(argv[3], "registered")) 04230 registeredonly = 1; 04231 else 04232 return RESULT_SHOWUSAGE; 04233 if (!strcasecmp(argv[4], "like")) { 04234 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04235 return RESULT_SHOWUSAGE; 04236 havepattern = 1; 04237 } else 04238 return RESULT_SHOWUSAGE; 04239 break; 04240 case 5: 04241 if (!strcasecmp(argv[3], "like")) { 04242 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04243 return RESULT_SHOWUSAGE; 04244 havepattern = 1; 04245 } else 04246 return RESULT_SHOWUSAGE; 04247 break; 04248 case 4: 04249 if (!strcasecmp(argv[3], "registered")) 04250 registeredonly = 1; 04251 else 04252 return RESULT_SHOWUSAGE; 04253 break; 04254 case 3: 04255 break; 04256 default: 04257 return RESULT_SHOWUSAGE; 04258 } 04259 04260 ast_mutex_lock(&peerl.lock); 04261 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04262 for (peer = peerl.peers;peer;peer = peer->next) { 04263 char nm[20]; 04264 char status[20]; 04265 char srch[2000]; 04266 int retstatus; 04267 04268 if (registeredonly && !peer->addr.sin_addr.s_addr) 04269 continue; 04270 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04271 continue; 04272 04273 if (!ast_strlen_zero(peer->username)) 04274 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04275 else 04276 ast_copy_string(name, peer->name, sizeof(name)); 04277 04278 retstatus = peer_status(peer, status, sizeof(status)); 04279 if (retstatus > 0) 04280 online_peers++; 04281 else if (!retstatus) 04282 offline_peers++; 04283 else 04284 unmonitored_peers++; 04285 04286 ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)); 04287 04288 snprintf(srch, sizeof(srch), FORMAT, name, 04289 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04290 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04291 nm, 04292 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04293 peer->encmethods ? "(E)" : " ", status, term); 04294 04295 ast_cli(fd, FORMAT, name, 04296 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 04297 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04298 nm, 04299 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04300 peer->encmethods ? "(E)" : " ", status, term); 04301 total_peers++; 04302 } 04303 ast_mutex_unlock(&peerl.lock); 04304 04305 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04306 04307 if (havepattern) 04308 regfree(®exbuf); 04309 04310 return RESULT_SUCCESS; 04311 #undef FORMAT 04312 #undef FORMAT2 04313 }
static int __send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 4675 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().
04677 { 04678 struct ast_frame f; 04679 f.frametype = type; 04680 f.subclass = command; 04681 f.datalen = datalen; 04682 f.samples = 0; 04683 f.mallocd = 0; 04684 f.offset = 0; 04685 f.src = (char *)__FUNCTION__; 04686 f.data = (char *)data; 04687 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04688 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 9621 of file chan_iax2.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_cli, iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), netsock, papp, sched, and sched_context_destroy().
Referenced by load_module(), and unload_module().
09622 { 09623 int x; 09624 /* Cancel the network thread, close the net socket */ 09625 if (netthreadid != AST_PTHREADT_NULL) { 09626 pthread_cancel(netthreadid); 09627 pthread_join(netthreadid, NULL); 09628 } 09629 ast_netsock_release(netsock); 09630 for (x=0;x<IAX_MAX_CALLS;x++) 09631 if (iaxs[x]) 09632 iax2_destroy(x); 09633 ast_manager_unregister( "IAXpeers" ); 09634 ast_manager_unregister( "IAXnetstats" ); 09635 ast_unregister_application(papp); 09636 ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0])); 09637 ast_unregister_switch(&iax2_switch); 09638 ast_channel_unregister(&iax2_tech); 09639 delete_users(); 09640 iax_provision_unload(); 09641 sched_context_destroy(sched); 09642 return 0; 09643 }
static int apply_context | ( | struct iax2_context * | con, | |
char * | context | |||
) | [static] |
Definition at line 4728 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04729 { 04730 while(con) { 04731 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04732 return -1; 04733 con = con->next; 04734 } 04735 return 0; 04736 }
static int ast_cli_netstats | ( | int | fd, | |
int | limit_fmt | |||
) | [static] |
Definition at line 4495 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, jb_info::current, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04496 { 04497 int x; 04498 int numchans = 0; 04499 for (x=0;x<IAX_MAX_CALLS;x++) { 04500 ast_mutex_lock(&iaxsl[x]); 04501 if (iaxs[x]) { 04502 #ifdef BRIDGE_OPTIMIZATION 04503 if (iaxs[x]->bridgecallno) { 04504 if (limit_fmt) 04505 ast_cli(fd, "%-25.25s <NATIVE BRIDGED>", 04506 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04507 else 04508 ast_cli(fd, "%s <NATIVE BRIDGED>", 04509 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)"); 04510 } else 04511 #endif 04512 { 04513 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04514 char *fmt; 04515 #ifdef NEWJB 04516 jb_info jbinfo; 04517 04518 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04519 jb_getinfo(iaxs[x]->jb, &jbinfo); 04520 localjitter = jbinfo.jitter; 04521 localdelay = jbinfo.current - jbinfo.min; 04522 locallost = jbinfo.frames_lost; 04523 locallosspct = jbinfo.losspct/1000; 04524 localdropped = jbinfo.frames_dropped; 04525 localooo = jbinfo.frames_ooo; 04526 } else { 04527 localjitter = -1; 04528 localdelay = 0; 04529 locallost = -1; 04530 locallosspct = -1; 04531 localdropped = 0; 04532 localooo = -1; 04533 } 04534 #else 04535 localjitter = iaxs[x]->jitter; 04536 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) 04537 { 04538 localdelay = jitterbufsize(iaxs[x]); 04539 localdropped = iaxs[x]->frames_dropped; 04540 } else { 04541 localdelay = localdropped = 0; 04542 } 04543 locallost = locallosspct = localooo = -1; 04544 #endif 04545 if (limit_fmt) 04546 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04547 else 04548 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04549 ast_cli(fd, fmt, 04550 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04551 iaxs[x]->pingtime, 04552 localjitter, 04553 localdelay, 04554 locallost, 04555 locallosspct, 04556 localdropped, 04557 localooo, 04558 iaxs[x]->frames_received/1000, 04559 iaxs[x]->remote_rr.jitter, 04560 iaxs[x]->remote_rr.delay, 04561 iaxs[x]->remote_rr.losscnt, 04562 iaxs[x]->remote_rr.losspct, 04563 iaxs[x]->remote_rr.dropped, 04564 iaxs[x]->remote_rr.ooo, 04565 iaxs[x]->remote_rr.packets/1000 04566 ); 04567 } 04568 numchans++; 04569 } 04570 ast_mutex_unlock(&iaxsl[x]); 04571 } 04572 return numchans; 04573 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static] |
Definition at line 3422 of file chan_iax2.c.
References ast_channel::accountcode, chan_iax2_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_iax2_pvt::cid_name, ast_callerid::cid_num, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, ast_channel::context, chan_iax2_pvt::dnid, chan_iax2_pvt::exten, ast_channel::exten, chan_iax2_pvt::host, iax2_tech, iaxsl, ast_channel::language, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_read().
03423 { 03424 struct ast_channel *tmp; 03425 struct chan_iax2_pvt *i; 03426 struct ast_variable *v = NULL; 03427 03428 /* Don't hold call lock */ 03429 ast_mutex_unlock(&iaxsl[callno]); 03430 tmp = ast_channel_alloc(1); 03431 ast_mutex_lock(&iaxsl[callno]); 03432 i = iaxs[callno]; 03433 if (i && tmp) { 03434 tmp->tech = &iax2_tech; 03435 snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s-%d", i->host, i->callno); 03436 tmp->type = channeltype; 03437 /* We can support any format by default, until we get restricted */ 03438 tmp->nativeformats = capability; 03439 tmp->readformat = ast_best_codec(capability); 03440 tmp->writeformat = ast_best_codec(capability); 03441 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03442 03443 if (!ast_strlen_zero(i->cid_num)) 03444 tmp->cid.cid_num = strdup(i->cid_num); 03445 if (!ast_strlen_zero(i->cid_name)) 03446 tmp->cid.cid_name = strdup(i->cid_name); 03447 if (!ast_strlen_zero(i->ani)) 03448 tmp->cid.cid_ani = strdup(i->ani); 03449 tmp->cid.cid_pres = i->calling_pres; 03450 tmp->cid.cid_ton = i->calling_ton; 03451 tmp->cid.cid_tns = i->calling_tns; 03452 03453 if (!ast_strlen_zero(i->language)) 03454 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 03455 if (!ast_strlen_zero(i->dnid)) 03456 tmp->cid.cid_dnid = strdup(i->dnid); 03457 if (!ast_strlen_zero(i->accountcode)) 03458 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 03459 if (i->amaflags) 03460 tmp->amaflags = i->amaflags; 03461 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03462 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03463 tmp->adsicpe = i->peeradsicpe; 03464 i->owner = tmp; 03465 i->capability = capability; 03466 ast_setstate(tmp, state); 03467 if (state != AST_STATE_DOWN) { 03468 if (ast_pbx_start(tmp)) { 03469 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03470 ast_hangup(tmp); 03471 tmp = NULL; 03472 } 03473 } 03474 for (v = i->vars ; v ; v = v->next) 03475 pbx_builtin_setvar_helper(tmp,v->name,v->value); 03476 03477 ast_mutex_lock(&usecnt_lock); 03478 usecnt++; 03479 ast_mutex_unlock(&usecnt_lock); 03480 ast_update_use_count(); 03481 } 03482 return tmp; 03483 }
AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock | ) |
static int attempt_transmit | ( | void * | data | ) | [static] |
Definition at line 1736 of file chan_iax2.c.
References iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax_frame::callno, ast_iax2_queue::count, chan_iax2_pvt::error, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, ast_iax2_queue::head, iax2_destroy_nolock(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, ast_iax2_queue::lock, LOG_WARNING, MAX_RETRY_TIME, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, REG_STATE_TIMEOUT, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, and update_packet().
01737 { 01738 /* Attempt to transmit the frame to the remote peer... 01739 Called without iaxsl held. */ 01740 struct iax_frame *f = data; 01741 int freeme=0; 01742 int callno = f->callno; 01743 char iabuf[INET_ADDRSTRLEN]; 01744 /* Make sure this call is still active */ 01745 if (callno) 01746 ast_mutex_lock(&iaxsl[callno]); 01747 if ((f->callno) && iaxs[f->callno]) { 01748 if ((f->retries < 0) /* Already ACK'd */ || 01749 (f->retries >= max_retries) /* Too many attempts */) { 01750 /* Record an error if we've transmitted too many times */ 01751 if (f->retries >= max_retries) { 01752 if (f->transfer) { 01753 /* Transfer timeout */ 01754 send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 01755 } else if (f->final) { 01756 if (f->final) 01757 iax2_destroy_nolock(f->callno); 01758 } else { 01759 if (iaxs[f->callno]->owner) 01760 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); 01761 iaxs[f->callno]->error = ETIMEDOUT; 01762 if (iaxs[f->callno]->owner) { 01763 struct ast_frame fr = { 0, }; 01764 /* Hangup the fd */ 01765 fr.frametype = AST_FRAME_CONTROL; 01766 fr.subclass = AST_CONTROL_HANGUP; 01767 iax2_queue_frame(f->callno, &fr); 01768 /* Remember, owner could disappear */ 01769 if (iaxs[f->callno]->owner) 01770 iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01771 } else { 01772 if (iaxs[f->callno]->reg) { 01773 memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us)); 01774 iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT; 01775 iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 01776 } 01777 iax2_destroy_nolock(f->callno); 01778 } 01779 } 01780 01781 } 01782 freeme++; 01783 } else { 01784 /* Update it if it needs it */ 01785 update_packet(f); 01786 /* Attempt transmission */ 01787 send_packet(f); 01788 f->retries++; 01789 /* Try again later after 10 times as long */ 01790 f->retrytime *= 10; 01791 if (f->retrytime > MAX_RETRY_TIME) 01792 f->retrytime = MAX_RETRY_TIME; 01793 /* Transfer messages max out at one second */ 01794 if (f->transfer && (f->retrytime > 1000)) 01795 f->retrytime = 1000; 01796 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 01797 } 01798 } else { 01799 /* Make sure it gets freed */ 01800 f->retries = -1; 01801 freeme++; 01802 } 01803 if (callno) 01804 ast_mutex_unlock(&iaxsl[callno]); 01805 /* Do not try again */ 01806 if (freeme) { 01807 /* Don't attempt delivery, just remove it from the queue */ 01808 ast_mutex_lock(&iaxq.lock); 01809 if (f->prev) 01810 f->prev->next = f->next; 01811 else 01812 iaxq.head = f->next; 01813 if (f->next) 01814 f->next->prev = f->prev; 01815 else 01816 iaxq.tail = f->prev; 01817 iaxq.count--; 01818 ast_mutex_unlock(&iaxq.lock); 01819 f->retrans = -1; 01820 /* Free the IAX frame */ 01821 iax2_frame_free(f); 01822 } 01823 return 0; 01824 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 5946 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), iaxsl, and sched.
Referenced by socket_read().
05947 { 05948 /* Schedule sending the authentication failure in one second, to prevent 05949 guessing */ 05950 ast_mutex_lock(&iaxsl[callno]); 05951 iaxs[callno]->authfail = failcode; 05952 if (delayreject) { 05953 if (iaxs[callno]->authid > -1) 05954 ast_sched_del(sched, iaxs[callno]->authid); 05955 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 05956 } else 05957 auth_reject((void *)(long)callno); 05958 ast_mutex_unlock(&iaxsl[callno]); 05959 return 0; 05960 }
static int auth_reject | ( | void * | nothing | ) | [static] |
Definition at line 5924 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxsl, and send_command_final().
Referenced by auth_fail().
05925 { 05926 /* Called from IAX thread only, without iaxs lock */ 05927 int callno = (int)(long)(nothing); 05928 struct iax_ie_data ied; 05929 ast_mutex_lock(&iaxsl[callno]); 05930 if (iaxs[callno]) { 05931 iaxs[callno]->authid = -1; 05932 memset(&ied, 0, sizeof(ied)); 05933 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 05934 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 05935 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 05936 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 05937 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 05938 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 05939 } 05940 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 05941 } 05942 ast_mutex_unlock(&iaxsl[callno]); 05943 return 0; 05944 }
static int authenticate | ( | char * | challenge, | |
char * | secret, | |||
char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 5246 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
05247 { 05248 int res = -1; 05249 int x; 05250 char iabuf[INET_ADDRSTRLEN]; 05251 if (!ast_strlen_zero(keyn)) { 05252 if (!(authmethods & IAX_AUTH_RSA)) { 05253 if (ast_strlen_zero(secret)) 05254 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)); 05255 } else if (ast_strlen_zero(challenge)) { 05256 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05257 } else { 05258 char sig[256]; 05259 struct ast_key *key; 05260 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05261 if (!key) { 05262 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05263 } else { 05264 if (ast_sign(key, challenge, sig)) { 05265 ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n"); 05266 res = -1; 05267 } else { 05268 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05269 res = 0; 05270 } 05271 } 05272 } 05273 } 05274 /* Fall back */ 05275 if (res && !ast_strlen_zero(secret)) { 05276 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05277 struct MD5Context md5; 05278 unsigned char digest[16]; 05279 char digres[128]; 05280 MD5Init(&md5); 05281 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05282 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05283 MD5Final(digest, &md5); 05284 /* If they support md5, authenticate with it. */ 05285 for (x=0;x<16;x++) 05286 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05287 if (ecx && dcx) 05288 build_enc_keys(digest, ecx, dcx); 05289 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05290 res = 0; 05291 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05292 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05293 res = 0; 05294 } else 05295 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); 05296 } 05297 return res; 05298 }
static int authenticate_reply | ( | struct chan_iax2_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies, | |||
char * | override, | |||
char * | okey | |||
) | [static] |
Definition at line 5300 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, authenticate(), iax2_peer::authmethods, chan_iax2_pvt::challenge, destroy_peer(), IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ies, ast_peer_list::lock, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::next, iax2_peer::outkey, peerl, ast_peer_list::peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, and chan_iax2_pvt::username.
Referenced by socket_read().
05301 { 05302 struct iax2_peer *peer; 05303 /* Start pessimistic */ 05304 int res = -1; 05305 int authmethods = 0; 05306 struct iax_ie_data ied; 05307 05308 memset(&ied, 0, sizeof(ied)); 05309 05310 if (ies->username) 05311 ast_copy_string(p->username, ies->username, sizeof(p->username)); 05312 if (ies->challenge) 05313 ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge)); 05314 if (ies->authmethods) 05315 authmethods = ies->authmethods; 05316 if (authmethods & IAX_AUTH_MD5) 05317 merge_encryption(p, ies->encmethods); 05318 else 05319 p->encmethods = 0; 05320 05321 /* Check for override RSA authentication first */ 05322 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05323 /* Normal password authentication */ 05324 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05325 } else { 05326 ast_mutex_lock(&peerl.lock); 05327 peer = peerl.peers; 05328 while(peer) { 05329 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05330 /* No peer specified at our end, or this is the peer */ 05331 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05332 /* No username specified in peer rule, or this is the right username */ 05333 && (!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))) 05334 /* No specified host, or this is our host */ 05335 ) { 05336 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05337 if (!res) 05338 break; 05339 } 05340 peer = peer->next; 05341 } 05342 ast_mutex_unlock(&peerl.lock); 05343 if (!peer) { 05344 /* We checked our list and didn't find one. It's unlikely, but possible, 05345 that we're trying to authenticate *to* a realtime peer */ 05346 if ((peer = realtime_peer(p->peer, NULL))) { 05347 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05348 if (ast_test_flag(peer, IAX_TEMPONLY)) 05349 destroy_peer(peer); 05350 } 05351 } 05352 } 05353 if (ies->encmethods) 05354 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05355 if (!res) 05356 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05357 return res; 05358 }
static int authenticate_request | ( | struct chan_iax2_pvt * | p | ) | [static] |
Definition at line 4970 of file chan_iax2.c.
References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, ast_user_list::lock, send_command(), send_command_final(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.
Referenced by socket_read().
04971 { 04972 struct iax2_user *user = NULL; 04973 struct iax_ie_data ied; 04974 int res = -1, authreq_restrict = 0; 04975 04976 memset(&ied, 0, sizeof(ied)); 04977 04978 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 04979 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04980 ast_mutex_lock(&userl.lock); 04981 user = userl.users; 04982 while (user) { 04983 if (!strcmp(user->name, p->username)) { 04984 if (user->curauthreq == user->maxauthreq) 04985 authreq_restrict = 1; 04986 else 04987 user->curauthreq++; 04988 break; 04989 } 04990 user = user->next; 04991 } 04992 ast_mutex_unlock(&userl.lock); 04993 } 04994 04995 /* If the AUTHREQ limit test failed, send back an error */ 04996 if (authreq_restrict) { 04997 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 04998 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 04999 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05000 return 0; 05001 } 05002 05003 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05004 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05005 snprintf(p->challenge, sizeof(p->challenge), "%d", rand()); 05006 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05007 } 05008 if (p->encmethods) 05009 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05010 05011 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05012 05013 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05014 05015 if (p->encmethods) 05016 ast_set_flag(p, IAX_ENCRYPTED); 05017 05018 return res; 05019 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5021 of file chan_iax2.c.
References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, key(), ast_user_list::lock, LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.
Referenced by socket_read().
05022 { 05023 char requeststr[256]; 05024 char md5secret[256] = ""; 05025 char secret[256] = ""; 05026 char rsasecret[256] = ""; 05027 int res = -1; 05028 int x; 05029 struct iax2_user *user = NULL; 05030 05031 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05032 ast_mutex_lock(&userl.lock); 05033 user = userl.users; 05034 while (user) { 05035 if (!strcmp(user->name, p->username)) { 05036 user->curauthreq--; 05037 break; 05038 } 05039 user = user->next; 05040 } 05041 ast_mutex_unlock(&userl.lock); 05042 ast_clear_flag(p, IAX_MAXAUTHREQ); 05043 } 05044 05045 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05046 return res; 05047 if (ies->password) 05048 ast_copy_string(secret, ies->password, sizeof(secret)); 05049 if (ies->md5_result) 05050 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05051 if (ies->rsa_result) 05052 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05053 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05054 struct ast_key *key; 05055 char *keyn; 05056 char tmpkey[256]; 05057 char *stringp=NULL; 05058 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05059 stringp=tmpkey; 05060 keyn = strsep(&stringp, ":"); 05061 while(keyn) { 05062 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05063 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05064 res = 0; 05065 break; 05066 } else if (!key) 05067 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05068 keyn = strsep(&stringp, ":"); 05069 } 05070 } else if (p->authmethods & IAX_AUTH_MD5) { 05071 struct MD5Context md5; 05072 unsigned char digest[16]; 05073 char *tmppw, *stringp; 05074 05075 tmppw = ast_strdupa(p->secret); 05076 stringp = tmppw; 05077 while((tmppw = strsep(&stringp, ";"))) { 05078 MD5Init(&md5); 05079 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05080 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05081 MD5Final(digest, &md5); 05082 /* If they support md5, authenticate with it. */ 05083 for (x=0;x<16;x++) 05084 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05085 if (!strcasecmp(requeststr, md5secret)) { 05086 res = 0; 05087 break; 05088 } 05089 } 05090 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05091 if (!strcmp(secret, p->secret)) 05092 res = 0; 05093 } 05094 return res; 05095 }
static int auto_congest | ( | void * | nothing | ) | [static] |
Definition at line 2859 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, iax2_queue_frame(), iaxsl, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by iax2_call(), and sip_call().
02860 { 02861 int callno = PTR_TO_CALLNO(nothing); 02862 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02863 ast_mutex_lock(&iaxsl[callno]); 02864 if (iaxs[callno]) { 02865 iaxs[callno]->initid = -1; 02866 iax2_queue_frame(callno, &f); 02867 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02868 } 02869 ast_mutex_unlock(&iaxsl[callno]); 02870 return 0; 02871 }
static int auto_hangup | ( | void * | nothing | ) | [static] |
Definition at line 5962 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxsl, and send_command_final().
Referenced by iax2_dprequest(), and iax2_provision().
05963 { 05964 /* Called from IAX thread only, without iaxs lock */ 05965 int callno = (int)(long)(nothing); 05966 struct iax_ie_data ied; 05967 ast_mutex_lock(&iaxsl[callno]); 05968 if (iaxs[callno]) { 05969 iaxs[callno]->autoid = -1; 05970 memset(&ied, 0, sizeof(ied)); 05971 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 05972 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 05973 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 05974 } 05975 ast_mutex_unlock(&iaxsl[callno]); 05976 return 0; 05977 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 8108 of file chan_iax2.c.
References iax2_context::context, malloc, and iax2_context::next.
Referenced by build_user().
08109 { 08110 struct iax2_context *con = malloc(sizeof(struct iax2_context)); 08111 if (con) { 08112 ast_copy_string(con->context, context, sizeof(con->context)); 08113 con->next = NULL; 08114 } 08115 return con; 08116 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3810 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03811 { 03812 aes_encrypt_key128(digest, ecx); 03813 aes_decrypt_key128(digest, dcx); 03814 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | temponly | |||
) | [static] |
Definition at line 8219 of file chan_iax2.c.
References ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_true(), DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, free, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, malloc, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::next, peer_set_srcaddr(), peerl, ast_peer_list::peers, prefs, sched, and ast_variable::value.
08220 { 08221 struct iax2_peer *peer; 08222 struct iax2_peer *prev; 08223 struct ast_ha *oldha = NULL; 08224 int maskfound=0; 08225 int found=0; 08226 prev = NULL; 08227 ast_mutex_lock(&peerl.lock); 08228 if (!temponly) { 08229 peer = peerl.peers; 08230 while(peer) { 08231 if (!strcmp(peer->name, name)) { 08232 break; 08233 } 08234 prev = peer; 08235 peer = peer->next; 08236 } 08237 } else 08238 peer = NULL; 08239 if (peer) { 08240 found++; 08241 oldha = peer->ha; 08242 peer->ha = NULL; 08243 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08244 if (prev) { 08245 prev->next = peer->next; 08246 } else { 08247 peerl.peers = peer->next; 08248 } 08249 ast_mutex_unlock(&peerl.lock); 08250 } else { 08251 ast_mutex_unlock(&peerl.lock); 08252 peer = malloc(sizeof(struct iax2_peer)); 08253 if (peer) { 08254 memset(peer, 0, sizeof(struct iax2_peer)); 08255 peer->expire = -1; 08256 peer->pokeexpire = -1; 08257 peer->sockfd = defaultsockfd; 08258 } 08259 } 08260 if (peer) { 08261 ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08262 peer->encmethods = iax2_encryption; 08263 peer->secret[0] = '\0'; 08264 if (!found) { 08265 ast_copy_string(peer->name, name, sizeof(peer->name)); 08266 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08267 peer->expiry = min_reg_expire; 08268 } 08269 peer->prefs = prefs; 08270 peer->capability = iax2_capability; 08271 peer->smoothing = 0; 08272 peer->pokefreqok = DEFAULT_FREQ_OK; 08273 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08274 peer->context[0] = '\0'; 08275 peer->peercontext[0] = '\0'; 08276 while(v) { 08277 if (!strcasecmp(v->name, "secret")) { 08278 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 08279 } else if (!strcasecmp(v->name, "mailbox")) { 08280 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 08281 } else if (!strcasecmp(v->name, "dbsecret")) { 08282 ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret)); 08283 } else if (!strcasecmp(v->name, "mailboxdetail")) { 08284 ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 08285 } else if (!strcasecmp(v->name, "trunk")) { 08286 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08287 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08288 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08289 ast_clear_flag(peer, IAX_TRUNK); 08290 } 08291 } else if (!strcasecmp(v->name, "auth")) { 08292 peer->authmethods = get_auth_methods(v->value); 08293 } else if (!strcasecmp(v->name, "encryption")) { 08294 peer->encmethods = get_encrypt_methods(v->value); 08295 } else if (!strcasecmp(v->name, "notransfer")) { 08296 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08297 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08298 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08299 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08300 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08301 } else if (!strcasecmp(v->name, "host")) { 08302 if (!strcasecmp(v->value, "dynamic")) { 08303 /* They'll register with us */ 08304 ast_set_flag(peer, IAX_DYNAMIC); 08305 if (!found) { 08306 /* Initialize stuff iff we're not found, otherwise 08307 we keep going with what we had */ 08308 memset(&peer->addr.sin_addr, 0, 4); 08309 if (peer->addr.sin_port) { 08310 /* If we've already got a port, make it the default rather than absolute */ 08311 peer->defaddr.sin_port = peer->addr.sin_port; 08312 peer->addr.sin_port = 0; 08313 } 08314 } 08315 } else { 08316 /* Non-dynamic. Make sure we become that way if we're not */ 08317 if (peer->expire > -1) 08318 ast_sched_del(sched, peer->expire); 08319 peer->expire = -1; 08320 ast_clear_flag(peer, IAX_DYNAMIC); 08321 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08322 free(peer); 08323 return NULL; 08324 } 08325 if (!peer->addr.sin_port) 08326 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08327 } 08328 if (!maskfound) 08329 inet_aton("255.255.255.255", &peer->mask); 08330 } else if (!strcasecmp(v->name, "defaultip")) { 08331 if (ast_get_ip(&peer->defaddr, v->value)) { 08332 free(peer); 08333 return NULL; 08334 } 08335 } else if (!strcasecmp(v->name, "sourceaddress")) { 08336 peer_set_srcaddr(peer, v->value); 08337 } else if (!strcasecmp(v->name, "permit") || 08338 !strcasecmp(v->name, "deny")) { 08339 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08340 } else if (!strcasecmp(v->name, "mask")) { 08341 maskfound++; 08342 inet_aton(v->value, &peer->mask); 08343 } else if (!strcasecmp(v->name, "context")) { 08344 if (ast_strlen_zero(peer->context)) 08345 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 08346 } else if (!strcasecmp(v->name, "regexten")) { 08347 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 08348 } else if (!strcasecmp(v->name, "peercontext")) { 08349 if (ast_strlen_zero(peer->peercontext)) 08350 ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext)); 08351 } else if (!strcasecmp(v->name, "port")) { 08352 if (ast_test_flag(peer, IAX_DYNAMIC)) 08353 peer->defaddr.sin_port = htons(atoi(v->value)); 08354 else 08355 peer->addr.sin_port = htons(atoi(v->value)); 08356 } else if (!strcasecmp(v->name, "username")) { 08357 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 08358 } else if (!strcasecmp(v->name, "allow")) { 08359 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08360 } else if (!strcasecmp(v->name, "disallow")) { 08361 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08362 } else if (!strcasecmp(v->name, "callerid")) { 08363 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), 08364 peer->cid_num, sizeof(peer->cid_num)); 08365 ast_set_flag(peer, IAX_HASCALLERID); 08366 } else if (!strcasecmp(v->name, "sendani")) { 08367 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08368 } else if (!strcasecmp(v->name, "inkeys")) { 08369 ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys)); 08370 } else if (!strcasecmp(v->name, "outkey")) { 08371 ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey)); 08372 } else if (!strcasecmp(v->name, "qualify")) { 08373 if (!strcasecmp(v->value, "no")) { 08374 peer->maxms = 0; 08375 } else if (!strcasecmp(v->value, "yes")) { 08376 peer->maxms = DEFAULT_MAXMS; 08377 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08378 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); 08379 peer->maxms = 0; 08380 } 08381 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08382 peer->smoothing = ast_true(v->value); 08383 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08384 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08385 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); 08386 } 08387 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08388 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08389 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); 08390 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08391 } else if (!strcasecmp(v->name, "timezone")) { 08392 ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag)); 08393 }/* else if (strcasecmp(v->name,"type")) */ 08394 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08395 v=v->next; 08396 } 08397 if (!peer->authmethods) 08398 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08399 ast_clear_flag(peer, IAX_DELME); 08400 /* Make sure these are IPv4 addresses */ 08401 peer->addr.sin_family = AF_INET; 08402 } 08403 if (oldha) 08404 ast_free_ha(oldha); 08405 return peer; 08406 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | temponly | |||
) | [static] |
Definition at line 8409 of file chan_iax2.c.
References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), build_context(), format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, iax2_user::next, prefs, user, userl, ast_user_list::users, and ast_variable::value.
08410 { 08411 struct iax2_user *prev, *user; 08412 struct iax2_context *con, *conl = NULL; 08413 struct ast_ha *oldha = NULL; 08414 struct iax2_context *oldcon = NULL; 08415 int format; 08416 int oldcurauthreq = 0; 08417 char *varname = NULL, *varval = NULL; 08418 struct ast_variable *tmpvar = NULL; 08419 08420 prev = NULL; 08421 ast_mutex_lock(&userl.lock); 08422 if (!temponly) { 08423 user = userl.users; 08424 while(user) { 08425 if (!strcmp(user->name, name)) { 08426 break; 08427 } 08428 prev = user; 08429 user = user->next; 08430 } 08431 } else 08432 user = NULL; 08433 08434 if (user) { 08435 oldcurauthreq = user->curauthreq; 08436 oldha = user->ha; 08437 oldcon = user->contexts; 08438 user->ha = NULL; 08439 user->contexts = NULL; 08440 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08441 if (prev) { 08442 prev->next = user->next; 08443 } else { 08444 userl.users = user->next; 08445 } 08446 ast_mutex_unlock(&userl.lock); 08447 } else { 08448 ast_mutex_unlock(&userl.lock); 08449 user = malloc(sizeof(struct iax2_user)); 08450 if (user) 08451 memset(user, 0, sizeof(struct iax2_user)); 08452 } 08453 08454 if (user) { 08455 memset(user, 0, sizeof(struct iax2_user)); 08456 user->maxauthreq = maxauthreq; 08457 user->curauthreq = oldcurauthreq; 08458 user->prefs = prefs; 08459 user->capability = iax2_capability; 08460 user->encmethods = iax2_encryption; 08461 ast_copy_string(user->name, name, sizeof(user->name)); 08462 ast_copy_string(user->language, language, sizeof(user->language)); 08463 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08464 while(v) { 08465 if (!strcasecmp(v->name, "context")) { 08466 con = build_context(v->value); 08467 if (con) { 08468 if (conl) 08469 conl->next = con; 08470 else 08471 user->contexts = con; 08472 conl = con; 08473 } 08474 } else if (!strcasecmp(v->name, "permit") || 08475 !strcasecmp(v->name, "deny")) { 08476 user->ha = ast_append_ha(v->name, v->value, user->ha); 08477 } else if (!strcasecmp(v->name, "setvar")) { 08478 varname = ast_strdupa(v->value); 08479 if (varname && (varval = strchr(varname,'='))) { 08480 *varval = '\0'; 08481 varval++; 08482 if((tmpvar = ast_variable_new(varname, varval))) { 08483 tmpvar->next = user->vars; 08484 user->vars = tmpvar; 08485 } 08486 } 08487 } else if (!strcasecmp(v->name, "allow")) { 08488 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08489 } else if (!strcasecmp(v->name, "disallow")) { 08490 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08491 } else if (!strcasecmp(v->name, "trunk")) { 08492 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08493 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08494 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08495 ast_clear_flag(user, IAX_TRUNK); 08496 } 08497 } else if (!strcasecmp(v->name, "auth")) { 08498 user->authmethods = get_auth_methods(v->value); 08499 } else if (!strcasecmp(v->name, "encryption")) { 08500 user->encmethods = get_encrypt_methods(v->value); 08501 } else if (!strcasecmp(v->name, "notransfer")) { 08502 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08503 } else if (!strcasecmp(v->name, "codecpriority")) { 08504 if(!strcasecmp(v->value, "caller")) 08505 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08506 else if(!strcasecmp(v->value, "disabled")) 08507 ast_set_flag(user, IAX_CODEC_NOPREFS); 08508 else if(!strcasecmp(v->value, "reqonly")) { 08509 ast_set_flag(user, IAX_CODEC_NOCAP); 08510 ast_set_flag(user, IAX_CODEC_NOPREFS); 08511 } 08512 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08513 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08514 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08515 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08516 } else if (!strcasecmp(v->name, "dbsecret")) { 08517 ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret)); 08518 } else if (!strcasecmp(v->name, "secret")) { 08519 if (!ast_strlen_zero(user->secret)) { 08520 strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1); 08521 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); 08522 } else 08523 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 08524 } else if (!strcasecmp(v->name, "callerid")) { 08525 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 08526 ast_set_flag(user, IAX_HASCALLERID); 08527 } else if (!strcasecmp(v->name, "accountcode")) { 08528 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 08529 } else if (!strcasecmp(v->name, "language")) { 08530 ast_copy_string(user->language, v->value, sizeof(user->language)); 08531 } else if (!strcasecmp(v->name, "amaflags")) { 08532 format = ast_cdr_amaflags2int(v->value); 08533 if (format < 0) { 08534 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08535 } else { 08536 user->amaflags = format; 08537 } 08538 } else if (!strcasecmp(v->name, "inkeys")) { 08539 ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys)); 08540 } else if (!strcasecmp(v->name, "maxauthreq")) { 08541 user->maxauthreq = atoi(v->value); 08542 if (user->maxauthreq < 0) 08543 user->maxauthreq = 0; 08544 }/* else if (strcasecmp(v->name,"type")) */ 08545 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08546 v = v->next; 08547 } 08548 if (!user->authmethods) { 08549 if (!ast_strlen_zero(user->secret)) { 08550 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08551 if (!ast_strlen_zero(user->inkeys)) 08552 user->authmethods |= IAX_AUTH_RSA; 08553 } else if (!ast_strlen_zero(user->inkeys)) { 08554 user->authmethods = IAX_AUTH_RSA; 08555 } else { 08556 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08557 } 08558 } 08559 ast_clear_flag(user, IAX_DELME); 08560 } 08561 if (oldha) 08562 ast_free_ha(oldha); 08563 if (oldcon) 08564 free_context(oldcon); 08565 return user; 08566 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 8996 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_MAX_CALLS, IAX_PROTO_VERSION, iaxsl, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
08997 { 08998 struct sockaddr_in sin; 08999 int x; 09000 int callno; 09001 struct iax_ie_data ied; 09002 struct create_addr_info cai; 09003 struct parsed_dial_string pds; 09004 char *tmpstr; 09005 09006 for (x=0; x<IAX_MAX_CALLS; x++) { 09007 /* Look for an *exact match* call. Once a call is negotiated, it can only 09008 look up entries for a single context */ 09009 if (!ast_mutex_trylock(&iaxsl[x])) { 09010 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 09011 return x; 09012 ast_mutex_unlock(&iaxsl[x]); 09013 } 09014 } 09015 09016 /* No match found, we need to create a new one */ 09017 09018 memset(&cai, 0, sizeof(cai)); 09019 memset(&ied, 0, sizeof(ied)); 09020 memset(&pds, 0, sizeof(pds)); 09021 09022 tmpstr = ast_strdupa(data); 09023 parse_dial_string(tmpstr, &pds); 09024 09025 /* Populate our address from the given */ 09026 if (create_addr(pds.peer, &sin, &cai)) 09027 return -1; 09028 09029 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 09030 pds.peer, pds.username, pds.password, pds.context); 09031 09032 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 09033 if (callno < 1) { 09034 ast_log(LOG_WARNING, "Unable to create call\n"); 09035 return -1; 09036 } 09037 09038 ast_mutex_lock(&iaxsl[callno]); 09039 ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot)); 09040 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 09041 09042 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 09043 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 09044 /* the string format is slightly different from a standard dial string, 09045 because the context appears in the 'exten' position 09046 */ 09047 if (pds.exten) 09048 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 09049 if (pds.username) 09050 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 09051 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 09052 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 09053 /* Keep password handy */ 09054 if (pds.password) 09055 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 09056 if (pds.key) 09057 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 09058 /* Start the call going */ 09059 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 09060 09061 return callno; 09062 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3673 of file chan_iax2.c.
References ast_log(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03674 { 03675 /* Returns where in "receive time" we are. That is, how many ms 03676 since we received (or would have received) the frame with timestamp 0 */ 03677 int ms; 03678 #ifdef IAXTESTS 03679 int jit; 03680 #endif /* IAXTESTS */ 03681 /* Setup rxcore if necessary */ 03682 if (ast_tvzero(p->rxcore)) { 03683 p->rxcore = ast_tvnow(); 03684 if (option_debug && iaxdebug) 03685 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03686 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03687 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03688 #if 1 03689 if (option_debug && iaxdebug) 03690 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03691 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03692 #endif 03693 } 03694 03695 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03696 #ifdef IAXTESTS 03697 if (test_jit) { 03698 if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) { 03699 jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0)); 03700 if ((int)(2.0 * rand() / (RAND_MAX + 1.0))) 03701 jit = -jit; 03702 ms += jit; 03703 } 03704 } 03705 if (test_late) { 03706 ms += test_late; 03707 test_late = 0; 03708 } 03709 #endif /* IAXTESTS */ 03710 return ms; 03711 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3529 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, and ast_frame::samples.
Referenced by iax2_send(), and socket_read().
03530 { 03531 int ms; 03532 int voice = 0; 03533 int genuine = 0; 03534 int adjust; 03535 struct timeval *delivery = NULL; 03536 03537 03538 /* What sort of frame do we have?: voice is self-explanatory 03539 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03540 non-genuine frames are CONTROL frames [ringing etc], DTMF 03541 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03542 the others need a timestamp slaved to the voice frames so that they go in sequence 03543 */ 03544 if (f) { 03545 if (f->frametype == AST_FRAME_VOICE) { 03546 voice = 1; 03547 delivery = &f->delivery; 03548 } else if (f->frametype == AST_FRAME_IAX) { 03549 genuine = 1; 03550 } else if (f->frametype == AST_FRAME_CNG) { 03551 p->notsilenttx = 0; 03552 } 03553 } 03554 if (ast_tvzero(p->offset)) { 03555 gettimeofday(&p->offset, NULL); 03556 /* Round to nearest 20ms for nice looking traces */ 03557 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03558 } 03559 /* If the timestamp is specified, just send it as is */ 03560 if (ts) 03561 return ts; 03562 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03563 if (delivery && !ast_tvzero(*delivery)) { 03564 ms = ast_tvdiff_ms(*delivery, p->offset); 03565 if (option_debug > 2 && iaxdebug) 03566 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03567 } else { 03568 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03569 if (ms < 0) 03570 ms = 0; 03571 if (voice) { 03572 /* On a voice frame, use predicted values if appropriate */ 03573 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03574 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03575 /* AN EXPLANATION: 03576 When we send voice, we usually send "calculated" timestamps worked out 03577 on the basis of the number of samples sent. When we send other frames, 03578 we usually send timestamps worked out from the real clock. 03579 The problem is that they can tend to drift out of step because the 03580 source channel's clock and our clock may not be exactly at the same rate. 03581 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03582 for this call. Moving it adjusts timestamps for non-voice frames. 03583 We make the adjustment in the style of a moving average. Each time we 03584 adjust p->offset by 10% of the difference between our clock-derived 03585 timestamp and the predicted timestamp. That's why you see "10000" 03586 below even though IAX2 timestamps are in milliseconds. 03587 The use of a moving average avoids offset moving too radically. 03588 Generally, "adjust" roams back and forth around 0, with offset hardly 03589 changing at all. But if a consistent different starts to develop it 03590 will be eliminated over the course of 10 frames (200-300msecs) 03591 */ 03592 adjust = (ms - p->nextpred); 03593 if (adjust < 0) 03594 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03595 else if (adjust > 0) 03596 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03597 03598 if (!p->nextpred) { 03599 p->nextpred = ms; /*f->samples / 8;*/ 03600 if (p->nextpred <= p->lastsent) 03601 p->nextpred = p->lastsent + 3; 03602 } 03603 ms = p->nextpred; 03604 } else { 03605 /* in this case, just use the actual 03606 * time, since we're either way off 03607 * (shouldn't happen), or we're ending a 03608 * silent period -- and seed the next 03609 * predicted time. Also, round ms to the 03610 * next multiple of frame size (so our 03611 * silent periods are multiples of 03612 * frame size too) */ 03613 03614 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03615 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03616 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03617 03618 if (f->samples >= 8) /* check to make sure we dont core dump */ 03619 { 03620 int diff = ms % (f->samples / 8); 03621 if (diff) 03622 ms += f->samples/8 - diff; 03623 } 03624 03625 p->nextpred = ms; 03626 p->notsilenttx = 1; 03627 } 03628 } else { 03629 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03630 it's a genuine frame */ 03631 if (genuine) { 03632 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03633 if (ms <= p->lastsent) 03634 ms = p->lastsent + 3; 03635 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03636 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03637 ms = p->lastsent + 3; 03638 } 03639 } 03640 } 03641 p->lastsent = ms; 03642 if (voice) 03643 p->nextpred = p->nextpred + f->samples / 8; 03644 return ms; 03645 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3485 of file chan_iax2.c.
References iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
03486 { 03487 unsigned long int mssincetx; /* unsigned to handle overflows */ 03488 long int ms, pred; 03489 03490 tpeer->trunkact = *tv; 03491 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03492 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03493 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03494 tpeer->txtrunktime = *tv; 03495 tpeer->lastsent = 999999; 03496 } 03497 /* Update last transmit time now */ 03498 tpeer->lasttxtime = *tv; 03499 03500 /* Calculate ms offset */ 03501 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03502 /* Predict from last value */ 03503 pred = tpeer->lastsent + sampms; 03504 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03505 ms = pred; 03506 03507 /* We never send the same timestamp twice, so fudge a little if we must */ 03508 if (ms == tpeer->lastsent) 03509 ms = tpeer->lastsent + 1; 03510 tpeer->lastsent = ms; 03511 return ms; 03512 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4739 of file chan_iax2.c.
References apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_new(), cid_name, cid_num, destroy_user(), exten, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, ies, key(), ast_user_list::lock, LOG_WARNING, ast_variable::name, ast_variable::next, prefs, realtime_user(), secret, user, userl, ast_user_list::users, and ast_variable::value.
Referenced by socket_read().
04740 { 04741 /* Start pessimistic */ 04742 int res = -1; 04743 int version = 2; 04744 struct iax2_user *user, *best = NULL; 04745 int bestscore = 0; 04746 int gotcapability = 0; 04747 char iabuf[INET_ADDRSTRLEN]; 04748 struct ast_variable *v = NULL, *tmpvar = NULL; 04749 04750 if (!iaxs[callno]) 04751 return res; 04752 if (ies->called_number) 04753 ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten)); 04754 if (ies->calling_number) { 04755 ast_shrink_phone_number(ies->calling_number); 04756 ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num)); 04757 } 04758 if (ies->calling_name) 04759 ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name)); 04760 if (ies->calling_ani) 04761 ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani)); 04762 if (ies->dnid) 04763 ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid)); 04764 if (ies->called_context) 04765 ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context)); 04766 if (ies->language) 04767 ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language)); 04768 if (ies->username) 04769 ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username)); 04770 if (ies->calling_ton > -1) 04771 iaxs[callno]->calling_ton = ies->calling_ton; 04772 if (ies->calling_tns > -1) 04773 iaxs[callno]->calling_tns = ies->calling_tns; 04774 if (ies->calling_pres > -1) 04775 iaxs[callno]->calling_pres = ies->calling_pres; 04776 if (ies->format) 04777 iaxs[callno]->peerformat = ies->format; 04778 if (ies->adsicpe) 04779 iaxs[callno]->peeradsicpe = ies->adsicpe; 04780 if (ies->capability) { 04781 gotcapability = 1; 04782 iaxs[callno]->peercapability = ies->capability; 04783 } 04784 if (ies->version) 04785 version = ies->version; 04786 04787 /* Use provided preferences until told otherwise for actual preferences */ 04788 if(ies->codec_prefs) { 04789 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04790 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04791 } 04792 04793 if (!gotcapability) 04794 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04795 if (version > IAX_PROTO_VERSION) { 04796 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04797 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version); 04798 return res; 04799 } 04800 ast_mutex_lock(&userl.lock); 04801 /* Search the userlist for a compatible entry, and fill in the rest */ 04802 user = userl.users; 04803 while(user) { 04804 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04805 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04806 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04807 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04808 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04809 if (!ast_strlen_zero(iaxs[callno]->username)) { 04810 /* Exact match, stop right now. */ 04811 best = user; 04812 break; 04813 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04814 /* No required authentication */ 04815 if (user->ha) { 04816 /* There was host authentication and we passed, bonus! */ 04817 if (bestscore < 4) { 04818 bestscore = 4; 04819 best = user; 04820 } 04821 } else { 04822 /* No host access, but no secret, either, not bad */ 04823 if (bestscore < 3) { 04824 bestscore = 3; 04825 best = user; 04826 } 04827 } 04828 } else { 04829 if (user->ha) { 04830 /* Authentication, but host access too, eh, it's something.. */ 04831 if (bestscore < 2) { 04832 bestscore = 2; 04833 best = user; 04834 } 04835 } else { 04836 /* Authentication and no host access... This is our baseline */ 04837 if (bestscore < 1) { 04838 bestscore = 1; 04839 best = user; 04840 } 04841 } 04842 } 04843 } 04844 user = user->next; 04845 } 04846 ast_mutex_unlock(&userl.lock); 04847 user = best; 04848 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 04849 user = realtime_user(iaxs[callno]->username); 04850 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04851 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04852 destroy_user(user); 04853 user = NULL; 04854 } 04855 } 04856 if (user) { 04857 /* We found our match (use the first) */ 04858 /* copy vars */ 04859 for (v = user->vars ; v ; v = v->next) { 04860 if((tmpvar = ast_variable_new(v->name, v->value))) { 04861 tmpvar->next = iaxs[callno]->vars; 04862 iaxs[callno]->vars = tmpvar; 04863 } 04864 } 04865 /* If a max AUTHREQ restriction is in place, activate it */ 04866 if (user->maxauthreq > 0) 04867 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 04868 iaxs[callno]->prefs = user->prefs; 04869 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04870 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04871 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04872 iaxs[callno]->encmethods = user->encmethods; 04873 /* Store the requested username if not specified */ 04874 if (ast_strlen_zero(iaxs[callno]->username)) 04875 ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username)); 04876 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04877 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04878 iaxs[callno]->capability = user->capability; 04879 /* And use the default context */ 04880 if (ast_strlen_zero(iaxs[callno]->context)) { 04881 if (user->contexts) 04882 ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context)); 04883 else 04884 ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context)); 04885 } 04886 /* And any input keys */ 04887 ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys)); 04888 /* And the permitted authentication methods */ 04889 iaxs[callno]->authmethods = user->authmethods; 04890 /* If they have callerid, override the given caller id. Always store the ANI */ 04891 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 04892 if (ast_test_flag(user, IAX_HASCALLERID)) { 04893 iaxs[callno]->calling_tns = 0; 04894 iaxs[callno]->calling_ton = 0; 04895 ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num)); 04896 ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name)); 04897 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 04898 } 04899 if (ast_strlen_zero(iaxs[callno]->ani)) 04900 ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani)); 04901 } else { 04902 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 04903 } 04904 if (!ast_strlen_zero(user->accountcode)) 04905 ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode)); 04906 if (user->amaflags) 04907 iaxs[callno]->amaflags = user->amaflags; 04908 if (!ast_strlen_zero(user->language)) 04909 ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language)); 04910 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04911 /* Keep this check last */ 04912 if (!ast_strlen_zero(user->dbsecret)) { 04913 char *family, *key=NULL; 04914 family = ast_strdupa(user->dbsecret); 04915 if (family) { 04916 key = strchr(family, '/'); 04917 if (key) { 04918 *key = '\0'; 04919 key++; 04920 } 04921 } 04922 if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret))) { 04923 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 04924 if (ast_test_flag(user, IAX_TEMPONLY)) { 04925 destroy_user(user); 04926 user = NULL; 04927 } 04928 } 04929 } else 04930 ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)); 04931 res = 0; 04932 } 04933 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 04934 return res; 04935 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6299 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_read().
06300 { 06301 unsigned int ourver; 06302 char rsi[80]; 06303 snprintf(rsi, sizeof(rsi), "si-%s", si); 06304 if (iax_provision_version(&ourver, rsi, 1)) 06305 return 0; 06306 if (option_debug) 06307 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06308 if (ourver != ver) 06309 iax2_provision(sin, sockfd, NULL, rsi, 1); 06310 return 0; 06311 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Definition at line 8137 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by peer_set_srcaddr().
08138 { 08139 int sd; 08140 int res; 08141 08142 sd = socket(AF_INET, SOCK_DGRAM, 0); 08143 if (sd < 0) { 08144 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08145 return -1; 08146 } 08147 08148 res = bind(sd, sa, salen); 08149 if (res < 0) { 08150 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08151 close(sd); 08152 return 1; 08153 } 08154 08155 close(sd); 08156 return 0; 08157 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5399 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_read().
05400 { 05401 char exten[256] = ""; 05402 int status = CACHE_FLAG_UNKNOWN; 05403 int expiry = iaxdefaultdpcache; 05404 int x; 05405 int matchmore = 0; 05406 struct iax2_dpcache *dp, *prev; 05407 05408 if (ies->called_number) 05409 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05410 05411 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05412 status = CACHE_FLAG_EXISTS; 05413 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05414 status = CACHE_FLAG_CANEXIST; 05415 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05416 status = CACHE_FLAG_NONEXISTENT; 05417 05418 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05419 /* Don't really do anything with this */ 05420 } 05421 if (ies->refresh) 05422 expiry = ies->refresh; 05423 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05424 matchmore = CACHE_FLAG_MATCHMORE; 05425 ast_mutex_lock(&dpcache_lock); 05426 prev = NULL; 05427 dp = pvt->dpentries; 05428 while(dp) { 05429 if (!strcmp(dp->exten, exten)) { 05430 /* Let them go */ 05431 if (prev) 05432 prev->peer = dp->peer; 05433 else 05434 pvt->dpentries = dp->peer; 05435 dp->peer = NULL; 05436 dp->callno = 0; 05437 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05438 if (dp->flags & CACHE_FLAG_PENDING) { 05439 dp->flags &= ~CACHE_FLAG_PENDING; 05440 dp->flags |= status; 05441 dp->flags |= matchmore; 05442 } 05443 /* Wake up waiters */ 05444 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05445 if (dp->waiters[x] > -1) 05446 write(dp->waiters[x], "asdf", 4); 05447 } 05448 prev = dp; 05449 dp = dp->peer; 05450 } 05451 ast_mutex_unlock(&dpcache_lock); 05452 return 0; 05453 }
static char* complete_iax2_show_peer | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2016 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and strdup.
02017 { 02018 int which = 0; 02019 struct iax2_peer *p; 02020 char *res = NULL; 02021 02022 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02023 if(pos == 3) { 02024 ast_mutex_lock(&peerl.lock); 02025 for(p = peerl.peers ; p ; p = p->next) { 02026 if(!strncasecmp(p->name, word, strlen(word))) { 02027 if(++which > state) { 02028 res = strdup(p->name); 02029 break; 02030 } 02031 } 02032 } 02033 ast_mutex_unlock(&peerl.lock); 02034 } 02035 02036 return res; 02037 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5455 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, ast_iax2_queue::head, iax2_frame_free(), iaxq, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_read().
05456 { 05457 int peercallno = 0; 05458 struct chan_iax2_pvt *pvt = iaxs[callno]; 05459 struct iax_frame *cur; 05460 05461 if (ies->callno) 05462 peercallno = ies->callno; 05463 05464 if (peercallno < 1) { 05465 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05466 return -1; 05467 } 05468 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05469 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05470 /* Reset sequence numbers */ 05471 pvt->oseqno = 0; 05472 pvt->rseqno = 0; 05473 pvt->iseqno = 0; 05474 pvt->aseqno = 0; 05475 pvt->peercallno = peercallno; 05476 pvt->transferring = TRANSFER_NONE; 05477 pvt->svoiceformat = -1; 05478 pvt->voiceformat = 0; 05479 pvt->svideoformat = -1; 05480 pvt->videoformat = 0; 05481 pvt->transfercallno = -1; 05482 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05483 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05484 #ifdef NEWJB 05485 { /* reset jitterbuffer */ 05486 jb_frame frame; 05487 while(jb_getall(pvt->jb,&frame) == JB_OK) 05488 iax2_frame_free(frame.data); 05489 05490 jb_reset(pvt->jb); 05491 } 05492 #else 05493 memset(&pvt->history, 0, sizeof(pvt->history)); 05494 pvt->jitterbuffer = 0; 05495 pvt->jitter = 0; 05496 pvt->historicjitter = 0; 05497 #endif 05498 pvt->lag = 0; 05499 pvt->last = 0; 05500 pvt->lastsent = 0; 05501 pvt->nextpred = 0; 05502 pvt->pingtime = DEFAULT_RETRY_TIME; 05503 ast_mutex_lock(&iaxq.lock); 05504 for (cur = iaxq.head; cur ; cur = cur->next) { 05505 /* We must cancel any packets that would have been transmitted 05506 because now we're talking to someone new. It's okay, they 05507 were transmitted to someone that didn't care anyway. */ 05508 if (callno == cur->callno) 05509 cur->retries = -1; 05510 } 05511 ast_mutex_unlock(&iaxq.lock); 05512 return 0; 05513 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 826 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), and raw_hangup().
00827 { 00828 int x; 00829 int power=-1; 00830 /* If it's 128 or smaller, just return it */ 00831 if (subclass < IAX_FLAG_SC_LOG) 00832 return subclass; 00833 /* Otherwise find its power */ 00834 for (x = 0; x < IAX_MAX_SHIFT; x++) { 00835 if (subclass & (1 << x)) { 00836 if (power > -1) { 00837 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 00838 return 0; 00839 } else 00840 power = x; 00841 } 00842 } 00843 return power | IAX_FLAG_SC_LOG; 00844 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6313 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().
06314 { 06315 #ifdef NEWJB 06316 jb_info stats; 06317 jb_getinfo(pvt->jb, &stats); 06318 06319 memset(iep, 0, sizeof(*iep)); 06320 06321 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06322 if(stats.frames_in == 0) stats.frames_in = 1; 06323 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06324 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06325 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06326 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06327 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06328 #else 06329 memset(iep, 0, sizeof(*iep)); 06330 iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter); 06331 iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received); 06332 if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 06333 iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0); 06334 else 06335 iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min); 06336 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped); 06337 /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */ 06338 /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */ 06339 #endif 06340 }
static int create_addr | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2771 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.
02772 { 02773 struct ast_hostent ahp; 02774 struct hostent *hp; 02775 struct iax2_peer *peer; 02776 02777 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02778 cai->sockfd = defaultsockfd; 02779 cai->maxtime = 0; 02780 sin->sin_family = AF_INET; 02781 02782 if (!(peer = find_peer(peername, 1))) { 02783 cai->found = 0; 02784 02785 hp = ast_gethostbyname(peername, &ahp); 02786 if (hp) { 02787 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02788 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02789 /* use global iax prefs for unknown peer/user */ 02790 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02791 return 0; 02792 } else { 02793 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02794 return -1; 02795 } 02796 } 02797 02798 cai->found = 1; 02799 02800 /* if the peer has no address (current or default), return failure */ 02801 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 02802 if (ast_test_flag(peer, IAX_TEMPONLY)) 02803 destroy_peer(peer); 02804 return -1; 02805 } 02806 02807 /* if the peer is being monitored and is currently unreachable, return failure */ 02808 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) { 02809 if (ast_test_flag(peer, IAX_TEMPONLY)) 02810 destroy_peer(peer); 02811 return -1; 02812 } 02813 02814 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02815 cai->maxtime = peer->maxms; 02816 cai->capability = peer->capability; 02817 cai->encmethods = peer->encmethods; 02818 cai->sockfd = peer->sockfd; 02819 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02820 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02821 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02822 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02823 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02824 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02825 if (ast_strlen_zero(peer->dbsecret)) { 02826 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02827 } else { 02828 char *family; 02829 char *key = NULL; 02830 02831 family = ast_strdupa(peer->dbsecret); 02832 if (family) { 02833 key = strchr(family, '/'); 02834 if (key) 02835 *key++ = '\0'; 02836 } 02837 if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02838 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02839 if (ast_test_flag(peer, IAX_TEMPONLY)) 02840 destroy_peer(peer); 02841 return -1; 02842 } 02843 } 02844 02845 if (peer->addr.sin_addr.s_addr) { 02846 sin->sin_addr = peer->addr.sin_addr; 02847 sin->sin_port = peer->addr.sin_port; 02848 } else { 02849 sin->sin_addr = peer->defaddr.sin_addr; 02850 sin->sin_port = peer->defaddr.sin_port; 02851 } 02852 02853 if (ast_test_flag(peer, IAX_TEMPONLY)) 02854 destroy_peer(peer); 02855 02856 return 0; 02857 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3864 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
03865 { 03866 int padding; 03867 unsigned char *workspace; 03868 workspace = alloca(*datalen); 03869 if (!workspace) 03870 return -1; 03871 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03872 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03873 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03874 return -1; 03875 /* Decrypt */ 03876 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03877 03878 padding = 16 + (workspace[15] & 0xf); 03879 if (option_debug && iaxdebug) 03880 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03881 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03882 return -1; 03883 03884 *datalen -= padding; 03885 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03886 f->frametype = fh->type; 03887 if (f->frametype == AST_FRAME_VIDEO) { 03888 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03889 } else { 03890 f->subclass = uncompress_subclass(fh->csub); 03891 } 03892 } else { 03893 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03894 if (option_debug && iaxdebug) 03895 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03896 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03897 return -1; 03898 /* Decrypt */ 03899 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03900 padding = 16 + (workspace[15] & 0x0f); 03901 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03902 return -1; 03903 *datalen -= padding; 03904 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03905 } 03906 return 0; 03907 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3950 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_read().
03951 { 03952 int res=-1; 03953 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 03954 /* Search for possible keys, given secrets */ 03955 struct MD5Context md5; 03956 unsigned char digest[16]; 03957 char *tmppw, *stringp; 03958 03959 tmppw = ast_strdupa(iaxs[callno]->secret); 03960 stringp = tmppw; 03961 while((tmppw = strsep(&stringp, ";"))) { 03962 MD5Init(&md5); 03963 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 03964 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 03965 MD5Final(digest, &md5); 03966 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 03967 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03968 if (!res) { 03969 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 03970 break; 03971 } 03972 } 03973 } else 03974 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03975 return res; 03976 }
static void delete_users | ( | void | ) | [static] |
Definition at line 8568 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_destroy_nolock(), IAX_DELME, iaxsl, ast_user_list::lock, iax2_registry::next, registrations, regl, sched, user, userl, and ast_user_list::users.
08569 { 08570 struct iax2_user *user; 08571 struct iax2_peer *peer; 08572 struct iax2_registry *reg, *regl; 08573 08574 ast_mutex_lock(&userl.lock); 08575 for (user=userl.users;user;) { 08576 ast_set_flag(user, IAX_DELME); 08577 user = user->next; 08578 } 08579 ast_mutex_unlock(&userl.lock); 08580 for (reg = registrations;reg;) { 08581 regl = reg; 08582 reg = reg->next; 08583 if (regl->expire > -1) { 08584 ast_sched_del(sched, regl->expire); 08585 } 08586 if (regl->callno) { 08587 /* XXX Is this a potential lock? I don't think so, but you never know */ 08588 ast_mutex_lock(&iaxsl[regl->callno]); 08589 if (iaxs[regl->callno]) { 08590 iaxs[regl->callno]->reg = NULL; 08591 iax2_destroy_nolock(regl->callno); 08592 } 08593 ast_mutex_unlock(&iaxsl[regl->callno]); 08594 } 08595 free(regl); 08596 } 08597 registrations = NULL; 08598 ast_mutex_lock(&peerl.lock); 08599 for (peer=peerl.peers;peer;) { 08600 /* Assume all will be deleted, and we'll find out for sure later */ 08601 ast_set_flag(peer, IAX_DELME); 08602 peer = peer->next; 08603 } 08604 ast_mutex_unlock(&peerl.lock); 08605 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 9749 of file chan_iax2.c.
09750 { 09751 return (char *) desc; 09752 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1158 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01159 { 01160 /* Close firmware */ 01161 if (cur->fwh) { 01162 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01163 } 01164 close(cur->fd); 01165 free(cur); 01166 }
static void destroy_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8637 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(), IAX_MAX_CALLS, iaxsl, iax2_peer::pokeexpire, register_peer_exten(), and sched.
Referenced by authenticate_reply(), create_addr(), iax2_devicestate(), iax2_getpeername(), iax2_show_peer(), prune_peers(), realtime_peer(), register_verify(), registry_authrequest(), and update_registry().
08638 { 08639 int x; 08640 ast_free_ha(peer->ha); 08641 for (x=0;x<IAX_MAX_CALLS;x++) { 08642 ast_mutex_lock(&iaxsl[x]); 08643 if (iaxs[x] && (iaxs[x]->peerpoke == peer)) { 08644 iax2_destroy(x); 08645 } 08646 ast_mutex_unlock(&iaxsl[x]); 08647 } 08648 /* Delete it, it needs to disappear */ 08649 if (peer->expire > -1) 08650 ast_sched_del(sched, peer->expire); 08651 if (peer->pokeexpire > -1) 08652 ast_sched_del(sched, peer->pokeexpire); 08653 if (peer->callno > 0) 08654 iax2_destroy(peer->callno); 08655 register_peer_exten(peer, 0); 08656 if (peer->dnsmgr) 08657 ast_dnsmgr_release(peer->dnsmgr); 08658 free(peer); 08659 }
static void destroy_user | ( | struct iax2_user * | user | ) | [static] |
Definition at line 8607 of file chan_iax2.c.
References ast_free_ha(), ast_variables_destroy(), free, free_context(), and user.
Referenced by check_access(), and prune_users().
08608 { 08609 ast_free_ha(user->ha); 08610 free_context(user->contexts); 08611 if(user->vars) { 08612 ast_variables_destroy(user->vars); 08613 user->vars = NULL; 08614 } 08615 free(user); 08616 }
static void dp_lookup | ( | int | callno, | |
char * | context, | |||
char * | callednum, | |||
char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6156 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(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_read().
06157 { 06158 unsigned short dpstatus = 0; 06159 struct iax_ie_data ied1; 06160 int mm; 06161 06162 memset(&ied1, 0, sizeof(ied1)); 06163 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06164 /* Must be started */ 06165 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06166 dpstatus = IAX_DPSTATUS_EXISTS; 06167 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06168 dpstatus = IAX_DPSTATUS_CANEXIST; 06169 } else { 06170 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06171 } 06172 if (ast_ignore_pattern(context, callednum)) 06173 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06174 if (mm) 06175 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06176 if (!skiplock) 06177 ast_mutex_lock(&iaxsl[callno]); 06178 if (iaxs[callno]) { 06179 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06180 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06181 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06182 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06183 } 06184 if (!skiplock) 06185 ast_mutex_unlock(&iaxsl[callno]); 06186 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6188 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().
06189 { 06190 /* Look up for dpreq */ 06191 struct dpreq_data *dpr = data; 06192 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06193 if (dpr->callerid) 06194 free(dpr->callerid); 06195 free(dpr); 06196 return NULL; 06197 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 3909 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
03910 { 03911 int padding; 03912 unsigned char *workspace; 03913 workspace = alloca(*datalen + 32); 03914 if (!workspace) 03915 return -1; 03916 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03917 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03918 if (option_debug && iaxdebug) 03919 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03920 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03921 padding = 16 + (padding & 0xf); 03922 memcpy(workspace, poo, padding); 03923 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03924 workspace[15] &= 0xf0; 03925 workspace[15] |= (padding & 0xf); 03926 if (option_debug && iaxdebug) 03927 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]); 03928 *datalen += padding; 03929 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03930 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03931 memcpy(poo, workspace + *datalen - 32, 32); 03932 } else { 03933 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03934 if (option_debug && iaxdebug) 03935 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03936 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03937 padding = 16 + (padding & 0xf); 03938 memcpy(workspace, poo, padding); 03939 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03940 workspace[15] &= 0xf0; 03941 workspace[15] |= (padding & 0x0f); 03942 *datalen += padding; 03943 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 03944 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 03945 memcpy(poo, workspace + *datalen - 32, 32); 03946 } 03947 return 0; 03948 }
static int expire_registry | ( | void * | data | ) | [static] |
Definition at line 5650 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, globalflags, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, iax2_peer::name, prune_peers(), realtime_update_peer(), and register_peer_exten().
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
05651 { 05652 struct iax2_peer *p = data; 05653 05654 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name); 05655 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05656 realtime_update_peer(p->name, &p->addr, 0); 05657 /* Reset the address */ 05658 memset(&p->addr, 0, sizeof(p->addr)); 05659 /* Reset expire notice */ 05660 p->expire = -1; 05661 /* Reset expiry value */ 05662 p->expiry = min_reg_expire; 05663 if (!ast_test_flag(p, IAX_TEMPONLY)) 05664 ast_db_del("IAX/Registry", p->name); 05665 register_peer_exten(p, 0); 05666 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05667 if (iax2_regfunk) 05668 iax2_regfunk(p->name, 0); 05669 05670 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) { 05671 ast_set_flag(p, IAX_DELME); 05672 prune_peers(); 05673 } 05674 05675 return 0; 05676 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 9064 of file chan_iax2.c.
References ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxsl, LOG_WARNING, malloc, ast_frame::next, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, ast_frame::prev, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
09065 { 09066 struct iax2_dpcache *dp, *prev = NULL, *next; 09067 struct timeval tv; 09068 int x; 09069 int com[2]; 09070 int timeout; 09071 int old=0; 09072 int outfd; 09073 int abort; 09074 int callno; 09075 struct ast_channel *c; 09076 struct ast_frame *f; 09077 gettimeofday(&tv, NULL); 09078 dp = dpcache; 09079 while(dp) { 09080 next = dp->next; 09081 /* Expire old caches */ 09082 if (ast_tvcmp(tv, dp->expiry) > 0) { 09083 /* It's expired, let it disappear */ 09084 if (prev) 09085 prev->next = dp->next; 09086 else 09087 dpcache = dp->next; 09088 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 09089 /* Free memory and go again */ 09090 free(dp); 09091 } else { 09092 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); 09093 } 09094 dp = next; 09095 continue; 09096 } 09097 /* We found an entry that matches us! */ 09098 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 09099 break; 09100 prev = dp; 09101 dp = next; 09102 } 09103 if (!dp) { 09104 /* No matching entry. Create a new one. */ 09105 /* First, can we make a callno? */ 09106 callno = cache_get_callno_locked(data); 09107 if (callno < 0) { 09108 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09109 return NULL; 09110 } 09111 dp = malloc(sizeof(struct iax2_dpcache)); 09112 if (!dp) { 09113 ast_mutex_unlock(&iaxsl[callno]); 09114 return NULL; 09115 } 09116 memset(dp, 0, sizeof(struct iax2_dpcache)); 09117 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09118 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09119 gettimeofday(&dp->expiry, NULL); 09120 dp->orig = dp->expiry; 09121 /* Expires in 30 mins by default */ 09122 dp->expiry.tv_sec += iaxdefaultdpcache; 09123 dp->next = dpcache; 09124 dp->flags = CACHE_FLAG_PENDING; 09125 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09126 dp->waiters[x] = -1; 09127 dpcache = dp; 09128 dp->peer = iaxs[callno]->dpentries; 09129 iaxs[callno]->dpentries = dp; 09130 /* Send the request if we're already up */ 09131 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 09132 iax2_dprequest(dp, callno); 09133 ast_mutex_unlock(&iaxsl[callno]); 09134 } 09135 /* By here we must have a dp */ 09136 if (dp->flags & CACHE_FLAG_PENDING) { 09137 /* Okay, here it starts to get nasty. We need a pipe now to wait 09138 for a reply to come back so long as it's pending */ 09139 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09140 /* Find an empty slot */ 09141 if (dp->waiters[x] < 0) 09142 break; 09143 } 09144 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09145 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09146 return NULL; 09147 } 09148 if (pipe(com)) { 09149 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09150 return NULL; 09151 } 09152 dp->waiters[x] = com[1]; 09153 /* Okay, now we wait */ 09154 timeout = iaxdefaulttimeout * 1000; 09155 /* Temporarily unlock */ 09156 ast_mutex_unlock(&dpcache_lock); 09157 /* Defer any dtmf */ 09158 if (chan) 09159 old = ast_channel_defer_dtmf(chan); 09160 abort = 0; 09161 while(timeout) { 09162 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09163 if (outfd > -1) { 09164 break; 09165 } 09166 if (c) { 09167 f = ast_read(c); 09168 if (f) 09169 ast_frfree(f); 09170 else { 09171 /* Got hung up on, abort! */ 09172 break; 09173 abort = 1; 09174 } 09175 } 09176 } 09177 if (!timeout) { 09178 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09179 } 09180 ast_mutex_lock(&dpcache_lock); 09181 dp->waiters[x] = -1; 09182 close(com[1]); 09183 close(com[0]); 09184 if (abort) { 09185 /* Don't interpret anything, just abort. Not sure what th epoint 09186 of undeferring dtmf on a hung up channel is but hey whatever */ 09187 if (!old && chan) 09188 ast_channel_undefer_dtmf(chan); 09189 return NULL; 09190 } 09191 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09192 /* Now to do non-independent analysis the results of our wait */ 09193 if (dp->flags & CACHE_FLAG_PENDING) { 09194 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09195 pending. Don't let it take as long to timeout. */ 09196 dp->flags &= ~CACHE_FLAG_PENDING; 09197 dp->flags |= CACHE_FLAG_TIMEOUT; 09198 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09199 systems without leaving it unavailable once the server comes back online */ 09200 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09201 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09202 if (dp->waiters[x] > -1) 09203 write(dp->waiters[x], "asdf", 4); 09204 } 09205 } 09206 /* Our caller will obtain the rest */ 09207 if (!old && chan) 09208 ast_channel_undefer_dtmf(chan); 09209 } 09210 return dp; 09211 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | lockpeer, | |||
int | sockfd | |||
) | [static] |
Definition at line 1056 of file chan_iax2.c.
References 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, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, globalflags, host, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_read().
01057 { 01058 int res = 0; 01059 int x; 01060 struct timeval now; 01061 char iabuf[INET_ADDRSTRLEN]; 01062 char host[80]; 01063 if (new <= NEW_ALLOW) { 01064 /* Look for an existing connection first */ 01065 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01066 ast_mutex_lock(&iaxsl[x]); 01067 if (iaxs[x]) { 01068 /* Look for an exact match */ 01069 if (match(sin, callno, dcallno, iaxs[x])) { 01070 res = x; 01071 } 01072 } 01073 ast_mutex_unlock(&iaxsl[x]); 01074 } 01075 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01076 ast_mutex_lock(&iaxsl[x]); 01077 if (iaxs[x]) { 01078 /* Look for an exact match */ 01079 if (match(sin, callno, dcallno, iaxs[x])) { 01080 res = x; 01081 } 01082 } 01083 ast_mutex_unlock(&iaxsl[x]); 01084 } 01085 } 01086 if ((res < 1) && (new >= NEW_ALLOW)) { 01087 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) 01088 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 01089 gettimeofday(&now, NULL); 01090 for (x=1;x<TRUNK_CALL_START;x++) { 01091 /* Find first unused call number that hasn't been used in a while */ 01092 ast_mutex_lock(&iaxsl[x]); 01093 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01094 ast_mutex_unlock(&iaxsl[x]); 01095 } 01096 /* We've still got lock held if we found a spot */ 01097 if (x >= TRUNK_CALL_START) { 01098 ast_log(LOG_WARNING, "No more space\n"); 01099 return 0; 01100 } 01101 iaxs[x] = new_iax(sin, lockpeer, host); 01102 update_max_nontrunk(); 01103 if (iaxs[x]) { 01104 if (option_debug && iaxdebug) 01105 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01106 iaxs[x]->sockfd = sockfd; 01107 iaxs[x]->addr.sin_port = sin->sin_port; 01108 iaxs[x]->addr.sin_family = sin->sin_family; 01109 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01110 iaxs[x]->peercallno = callno; 01111 iaxs[x]->callno = x; 01112 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01113 iaxs[x]->expiry = min_reg_expire; 01114 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01115 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01116 iaxs[x]->amaflags = amaflags; 01117 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01118 ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode)); 01119 } else { 01120 ast_log(LOG_WARNING, "Out of resources\n"); 01121 ast_mutex_unlock(&iaxsl[x]); 01122 return 0; 01123 } 01124 ast_mutex_unlock(&iaxsl[x]); 01125 res = x; 01126 } 01127 return res; 01128 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 860 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer().
00861 { 00862 struct iax2_peer *peer; 00863 ast_mutex_lock(&peerl.lock); 00864 for(peer = peerl.peers; peer; peer = peer->next) { 00865 if (!strcasecmp(peer->name, name)) { 00866 break; 00867 } 00868 } 00869 ast_mutex_unlock(&peerl.lock); 00870 if(!peer && realtime) 00871 peer = realtime_peer(name, NULL); 00872 return peer; 00873 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 3713 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lock, malloc, iax2_trunk_peer::next, iax2_trunk_peer::sockfd, and tpeers.
Referenced by iax2_trunk_queue(), and socket_read().
03714 { 03715 struct iax2_trunk_peer *tpeer; 03716 char iabuf[INET_ADDRSTRLEN]; 03717 /* Finds and locks trunk peer */ 03718 ast_mutex_lock(&tpeerlock); 03719 tpeer = tpeers; 03720 while(tpeer) { 03721 /* We don't lock here because tpeer->addr *never* changes */ 03722 if (!inaddrcmp(&tpeer->addr, sin)) { 03723 ast_mutex_lock(&tpeer->lock); 03724 break; 03725 } 03726 tpeer = tpeer->next; 03727 } 03728 if (!tpeer) { 03729 tpeer = malloc(sizeof(struct iax2_trunk_peer)); 03730 if (tpeer) { 03731 memset(tpeer, 0, sizeof(struct iax2_trunk_peer)); 03732 ast_mutex_init(&tpeer->lock); 03733 tpeer->lastsent = 9999; 03734 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03735 tpeer->trunkact = ast_tvnow(); 03736 ast_mutex_lock(&tpeer->lock); 03737 tpeer->next = tpeers; 03738 tpeer->sockfd = fd; 03739 tpeers = tpeer; 03740 #ifdef SO_NO_CHECK 03741 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03742 #endif 03743 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)); 03744 } 03745 } 03746 ast_mutex_unlock(&tpeerlock); 03747 return tpeer; 03748 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3514 of file chan_iax2.c.
Referenced by socket_read().
03515 { 03516 long ms; /* NOT unsigned */ 03517 if (ast_tvzero(iaxs[callno]->rxcore)) { 03518 /* Initialize rxcore time if appropriate */ 03519 gettimeofday(&iaxs[callno]->rxcore, NULL); 03520 /* Round to nearest 20ms so traces look pretty */ 03521 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03522 } 03523 /* Calculate difference between trunk and channel */ 03524 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03525 /* Return as the sum of trunk time and the difference between trunk and real time */ 03526 return ms + ts; 03527 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 7948 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and destroy_user().
07949 { 07950 struct iax2_context *conl; 07951 while(con) { 07952 conl = con; 07953 con = con->next; 07954 free(conl); 07955 } 07956 }
static char* function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9336 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, LOG_ERROR, iax2_peer::mailbox, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, and ast_channel::tech_pvt.
09337 { 09338 char *ret = NULL; 09339 struct iax2_peer *peer; 09340 char *peername, *colname; 09341 char iabuf[INET_ADDRSTRLEN]; 09342 09343 if (!(peername = ast_strdupa(data))) { 09344 ast_log(LOG_ERROR, "Memory Error!\n"); 09345 return ret; 09346 } 09347 09348 /* if our channel, return the IP address of the endpoint of current channel */ 09349 if (!strcmp(peername,"CURRENTCHANNEL")) { 09350 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt); 09351 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len); 09352 return buf; 09353 } 09354 09355 if ((colname = strchr(peername, ':'))) { 09356 *colname = '\0'; 09357 colname++; 09358 } else { 09359 colname = "ip"; 09360 } 09361 if (!(peer = find_peer(peername, 1))) 09362 return ret; 09363 09364 if (!strcasecmp(colname, "ip")) { 09365 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09366 } else if (!strcasecmp(colname, "status")) { 09367 peer_status(peer, buf, len); 09368 } else if (!strcasecmp(colname, "mailbox")) { 09369 ast_copy_string(buf, peer->mailbox, len); 09370 } else if (!strcasecmp(colname, "context")) { 09371 ast_copy_string(buf, peer->context, len); 09372 } else if (!strcasecmp(colname, "expire")) { 09373 snprintf(buf, len, "%d", peer->expire); 09374 } else if (!strcasecmp(colname, "dynamic")) { 09375 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09376 } else if (!strcasecmp(colname, "callerid_name")) { 09377 ast_copy_string(buf, peer->cid_name, len); 09378 } else if (!strcasecmp(colname, "callerid_num")) { 09379 ast_copy_string(buf, peer->cid_num, len); 09380 } else if (!strcasecmp(colname, "codecs")) { 09381 ast_getformatname_multiple(buf, len -1, peer->capability); 09382 } else if (!strncasecmp(colname, "codec[", 6)) { 09383 char *codecnum, *ptr; 09384 int index = 0, codec = 0; 09385 09386 codecnum = strchr(colname, '['); 09387 *codecnum = '\0'; 09388 codecnum++; 09389 if ((ptr = strchr(codecnum, ']'))) { 09390 *ptr = '\0'; 09391 } 09392 index = atoi(codecnum); 09393 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09394 ast_copy_string(buf, ast_getformatname(codec), len); 09395 } 09396 } 09397 ret = buf; 09398 09399 return ret; 09400 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8118 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08119 { 08120 int methods = 0; 08121 if (strstr(value, "rsa")) 08122 methods |= IAX_AUTH_RSA; 08123 if (strstr(value, "md5")) 08124 methods |= IAX_AUTH_MD5; 08125 if (strstr(value, "plaintext")) 08126 methods |= IAX_AUTH_PLAINTEXT; 08127 return methods; 08128 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 800 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
00801 { 00802 int e; 00803 if (!strcasecmp(s, "aes128")) 00804 e = IAX_ENCRYPT_AES128; 00805 else if (ast_true(s)) 00806 e = IAX_ENCRYPT_AES128; 00807 else 00808 e = 0; 00809 return e; 00810 }
static int get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2207 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), chan_iax2_pvt::callno, ast_frame::data, jb_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, ast_frame::mallocd, jb_frame::ms, iax_frame::next, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by update_jbsched().
02208 { 02209 /* make sure pvt is valid! */ 02210 struct chan_iax2_pvt *pvt = p; 02211 struct iax_frame *fr; 02212 jb_frame frame; 02213 int ret; 02214 long now; 02215 long next; 02216 struct timeval tv; 02217 02218 ast_mutex_lock(&iaxsl[pvt->callno]); 02219 pvt->jbid = -1; 02220 02221 gettimeofday(&tv,NULL); 02222 /* round up a millisecond since ast_sched_runq does; */ 02223 /* prevents us from spinning while waiting for our now */ 02224 /* to catch up with runq's now */ 02225 tv.tv_usec += 1000; 02226 02227 now = ast_tvdiff_ms(tv, pvt->rxcore); 02228 02229 if(now >= (next = jb_next(pvt->jb))) { 02230 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02231 switch(ret) { 02232 case JB_OK: 02233 fr = frame.data; 02234 __do_deliver(fr); 02235 break; 02236 case JB_INTERP: 02237 { 02238 struct ast_frame af; 02239 02240 /* create an interpolation frame */ 02241 af.frametype = AST_FRAME_VOICE; 02242 af.subclass = pvt->voiceformat; 02243 af.datalen = 0; 02244 af.samples = frame.ms * 8; 02245 af.mallocd = 0; 02246 af.src = "IAX2 JB interpolation"; 02247 af.data = NULL; 02248 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02249 af.offset=AST_FRIENDLY_OFFSET; 02250 02251 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02252 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02253 if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE)) 02254 iax2_queue_frame(pvt->callno, &af); 02255 } 02256 break; 02257 case JB_DROP: 02258 iax2_frame_free(frame.data); 02259 break; 02260 case JB_NOFRAME: 02261 case JB_EMPTY: 02262 /* do nothing */ 02263 break; 02264 default: 02265 /* shouldn't happen */ 02266 break; 02267 } 02268 } 02269 update_jbsched(pvt); 02270 ast_mutex_unlock(&iaxsl[pvt->callno]); 02271 return 0; 02272 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1452 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
01453 { 01454 /* XXX Ideally we should figure out why an error occured and then abort those 01455 rather than continuing to try. Unfortunately, the published interface does 01456 not seem to work XXX */ 01457 #if 0 01458 struct sockaddr_in *sin; 01459 int res; 01460 struct msghdr m; 01461 struct sock_extended_err e; 01462 m.msg_name = NULL; 01463 m.msg_namelen = 0; 01464 m.msg_iov = NULL; 01465 m.msg_control = &e; 01466 m.msg_controllen = sizeof(e); 01467 m.msg_flags = 0; 01468 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01469 if (res < 0) 01470 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01471 else { 01472 if (m.msg_controllen) { 01473 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01474 if (sin) 01475 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 01476 else 01477 ast_log(LOG_WARNING, "No address detected??\n"); 01478 } else { 01479 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01480 } 01481 } 01482 #endif 01483 return 0; 01484 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5516 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_read().
05517 { 05518 struct iax2_registry *reg; 05519 /* Start pessimistic */ 05520 char peer[256] = ""; 05521 char msgstatus[40]; 05522 int refresh = 0; 05523 char ourip[256] = "<Unspecified>"; 05524 struct sockaddr_in oldus; 05525 struct sockaddr_in us; 05526 char iabuf[INET_ADDRSTRLEN]; 05527 int oldmsgs; 05528 05529 memset(&us, 0, sizeof(us)); 05530 if (ies->apparent_addr) 05531 bcopy(ies->apparent_addr, &us, sizeof(us)); 05532 if (ies->username) 05533 ast_copy_string(peer, ies->username, sizeof(peer)); 05534 if (ies->refresh) 05535 refresh = ies->refresh; 05536 if (ies->calling_number) { 05537 /* We don't do anything with it really, but maybe we should */ 05538 } 05539 reg = iaxs[callno]->reg; 05540 if (!reg) { 05541 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05542 return -1; 05543 } 05544 memcpy(&oldus, ®->us, sizeof(oldus)); 05545 oldmsgs = reg->messages; 05546 if (inaddrcmp(®->addr, sin)) { 05547 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05548 return -1; 05549 } 05550 memcpy(®->us, &us, sizeof(reg->us)); 05551 reg->messages = ies->msgcount; 05552 /* always refresh the registration at the interval requested by the server 05553 we are registering to 05554 */ 05555 reg->refresh = refresh; 05556 if (reg->expire > -1) 05557 ast_sched_del(sched, reg->expire); 05558 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05559 if ((inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) { 05560 if (reg->messages > 65534) 05561 snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n"); 05562 else if (reg->messages > 1) 05563 snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages); 05564 else if (reg->messages > 0) 05565 snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n"); 05566 else 05567 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05568 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 05569 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); 05570 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)); 05571 } 05572 reg->regstate = REG_STATE_REGISTERED; 05573 return 0; 05574 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3364 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03365 { 03366 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03367 if (option_debug) 03368 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03369 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03370 }
static enum ast_bridge_result iax2_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 3198 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3.
03199 { 03200 struct ast_channel *cs[3]; 03201 struct ast_channel *who; 03202 int to = -1; 03203 int res = -1; 03204 int transferstarted=0; 03205 struct ast_frame *f; 03206 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03207 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03208 struct timeval waittimer = {0, 0}, tv; 03209 03210 lock_both(callno0, callno1); 03211 /* Put them in native bridge mode */ 03212 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03213 iaxs[callno0]->bridgecallno = callno1; 03214 iaxs[callno1]->bridgecallno = callno0; 03215 } 03216 unlock_both(callno0, callno1); 03217 03218 /* If not, try to bridge until we can execute a transfer, if we can */ 03219 cs[0] = c0; 03220 cs[1] = c1; 03221 for (/* ever */;;) { 03222 /* Check in case we got masqueraded into */ 03223 if ((c0->type != channeltype) || (c1->type != channeltype)) { 03224 if (option_verbose > 2) 03225 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03226 /* Remove from native mode */ 03227 if (c0->type == channeltype) { 03228 ast_mutex_lock(&iaxsl[callno0]); 03229 iaxs[callno0]->bridgecallno = 0; 03230 ast_mutex_unlock(&iaxsl[callno0]); 03231 } 03232 if (c1->type == channeltype) { 03233 ast_mutex_lock(&iaxsl[callno1]); 03234 iaxs[callno1]->bridgecallno = 0; 03235 ast_mutex_unlock(&iaxsl[callno1]); 03236 } 03237 return AST_BRIDGE_FAILED_NOWARN; 03238 } 03239 if (c0->nativeformats != c1->nativeformats) { 03240 if (option_verbose > 2) { 03241 char buf0[255]; 03242 char buf1[255]; 03243 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03244 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03245 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03246 } 03247 /* Remove from native mode */ 03248 lock_both(callno0, callno1); 03249 iaxs[callno0]->bridgecallno = 0; 03250 iaxs[callno1]->bridgecallno = 0; 03251 unlock_both(callno0, callno1); 03252 return AST_BRIDGE_FAILED_NOWARN; 03253 } 03254 /* check if transfered and if we really want native bridging */ 03255 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) && 03256 !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03257 /* Try the transfer */ 03258 if (iax2_start_transfer(callno0, callno1)) 03259 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03260 transferstarted = 1; 03261 } 03262 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03263 /* Call has been transferred. We're no longer involved */ 03264 gettimeofday(&tv, NULL); 03265 if (ast_tvzero(waittimer)) { 03266 waittimer = tv; 03267 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03268 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03269 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03270 *fo = NULL; 03271 *rc = c0; 03272 res = AST_BRIDGE_COMPLETE; 03273 break; 03274 } 03275 } 03276 to = 1000; 03277 who = ast_waitfor_n(cs, 2, &to); 03278 if (timeoutms > -1) { 03279 timeoutms -= (1000 - to); 03280 if (timeoutms < 0) 03281 timeoutms = 0; 03282 } 03283 if (!who) { 03284 if (!timeoutms) { 03285 res = AST_BRIDGE_RETRY; 03286 break; 03287 } 03288 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03289 res = AST_BRIDGE_FAILED; 03290 break; 03291 } 03292 continue; 03293 } 03294 f = ast_read(who); 03295 if (!f) { 03296 *fo = NULL; 03297 *rc = who; 03298 res = AST_BRIDGE_COMPLETE; 03299 break; 03300 } 03301 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03302 *fo = f; 03303 *rc = who; 03304 res = AST_BRIDGE_COMPLETE; 03305 break; 03306 } 03307 if ((f->frametype == AST_FRAME_VOICE) || 03308 (f->frametype == AST_FRAME_TEXT) || 03309 (f->frametype == AST_FRAME_VIDEO) || 03310 (f->frametype == AST_FRAME_IMAGE) || 03311 (f->frametype == AST_FRAME_DTMF)) { 03312 if ((f->frametype == AST_FRAME_DTMF) && 03313 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 03314 if ((who == c0)) { 03315 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 03316 *rc = c0; 03317 *fo = f; 03318 res = AST_BRIDGE_COMPLETE; 03319 /* Remove from native mode */ 03320 break; 03321 } else 03322 goto tackygoto; 03323 } else 03324 if ((who == c1)) { 03325 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 03326 *rc = c1; 03327 *fo = f; 03328 res = AST_BRIDGE_COMPLETE; 03329 break; 03330 } else 03331 goto tackygoto; 03332 } 03333 } else { 03334 #if 0 03335 if (iaxdebug && option_debug) 03336 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03337 if (who == last) 03338 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03339 last = who; 03340 #endif 03341 tackygoto: 03342 if (who == c0) 03343 ast_write(c1, f); 03344 else 03345 ast_write(c0, f); 03346 } 03347 ast_frfree(f); 03348 } else 03349 ast_frfree(f); 03350 /* Swap who gets priority */ 03351 cs[2] = cs[0]; 03352 cs[0] = cs[1]; 03353 cs[1] = cs[2]; 03354 } 03355 lock_both(callno0, callno1); 03356 if(iaxs[callno0]) 03357 iaxs[callno0]->bridgecallno = 0; 03358 if(iaxs[callno1]) 03359 iaxs[callno1]->bridgecallno = 0; 03360 unlock_both(callno0, callno1); 03361 return res; 03362 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 2960 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_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_strlen_zero(), ast_test_flag, auto_congest(), CALLNO_TO_PTR, capability, 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, ast_channel::context, create_addr(), 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, iaxsl, ast_channel::language, LOG_WARNING, create_addr_info::maxtime, n, ast_channel::name, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), PTR_TO_CALLNO, sched, secret, send_command(), and ast_channel::tech_pvt.
02961 { 02962 struct sockaddr_in sin; 02963 char *l=NULL, *n=NULL, *tmpstr; 02964 struct iax_ie_data ied; 02965 char *defaultrdest = "s"; 02966 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02967 struct parsed_dial_string pds; 02968 struct create_addr_info cai; 02969 02970 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 02971 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 02972 return -1; 02973 } 02974 02975 memset(&cai, 0, sizeof(cai)); 02976 cai.encmethods = iax2_encryption; 02977 02978 memset(&pds, 0, sizeof(pds)); 02979 tmpstr = ast_strdupa(dest); 02980 parse_dial_string(tmpstr, &pds); 02981 02982 if (!pds.exten) 02983 pds.exten = defaultrdest; 02984 02985 if (create_addr(pds.peer, &sin, &cai)) { 02986 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 02987 return -1; 02988 } 02989 02990 if (!pds.username && !ast_strlen_zero(cai.username)) 02991 pds.username = cai.username; 02992 if (!pds.password && !ast_strlen_zero(cai.secret)) 02993 pds.password = cai.secret; 02994 if (!pds.key && !ast_strlen_zero(cai.outkey)) 02995 pds.key = cai.outkey; 02996 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 02997 pds.context = cai.peercontext; 02998 02999 /* Keep track of the context for outgoing calls too */ 03000 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03001 03002 if (pds.port) 03003 sin.sin_port = htons(atoi(pds.port)); 03004 03005 l = c->cid.cid_num; 03006 n = c->cid.cid_name; 03007 03008 /* Now build request */ 03009 memset(&ied, 0, sizeof(ied)); 03010 03011 /* On new call, first IE MUST be IAX version of caller */ 03012 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03013 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03014 if (pds.options && strchr(pds.options, 'a')) { 03015 /* Request auto answer */ 03016 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03017 } 03018 03019 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03020 03021 if (l) { 03022 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03023 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03024 } else { 03025 if (n) 03026 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03027 else 03028 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03029 } 03030 03031 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03032 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03033 03034 if (n) 03035 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03036 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03037 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03038 03039 if (!ast_strlen_zero(c->language)) 03040 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03041 if (!ast_strlen_zero(c->cid.cid_dnid)) 03042 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03043 03044 if (pds.context) 03045 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03046 03047 if (pds.username) 03048 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03049 03050 if (cai.encmethods) 03051 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03052 03053 ast_mutex_lock(&iaxsl[callno]); 03054 03055 if (!ast_strlen_zero(c->context)) 03056 ast_copy_string(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context)); 03057 03058 if (pds.username) 03059 ast_copy_string(iaxs[callno]->username, pds.username, sizeof(iaxs[callno]->username)); 03060 03061 iaxs[callno]->encmethods = cai.encmethods; 03062 03063 if (pds.key) 03064 ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey)); 03065 if (pds.password) 03066 ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret)); 03067 03068 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03069 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03070 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03071 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03072 03073 if (iaxs[callno]->maxtime) { 03074 /* Initialize pingtime and auto-congest time */ 03075 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03076 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03077 } else if (autokill) { 03078 iaxs[callno]->pingtime = autokill / 2; 03079 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03080 } 03081 03082 /* Transmit the string in a "NEW" request */ 03083 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03084 03085 ast_mutex_unlock(&iaxsl[callno]); 03086 ast_setstate(c, AST_STATE_RINGING); 03087 03088 return 0; 03089 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 9237 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
09238 { 09239 int res = 0; 09240 struct iax2_dpcache *dp; 09241 #if 0 09242 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09243 #endif 09244 if ((priority != 1) && (priority != 2)) 09245 return 0; 09246 ast_mutex_lock(&dpcache_lock); 09247 dp = find_cache(chan, data, context, exten, priority); 09248 if (dp) { 09249 if (dp->flags & CACHE_FLAG_CANEXIST) 09250 res= 1; 09251 } 09252 ast_mutex_unlock(&dpcache_lock); 09253 if (!dp) { 09254 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09255 } 09256 return res; 09257 }
static unsigned int iax2_datetime | ( | char * | tz | ) | [static] |
Definition at line 2873 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
02874 { 02875 time_t t; 02876 struct tm tm; 02877 unsigned int tmp; 02878 time(&t); 02879 localtime_r(&t, &tm); 02880 if (!ast_strlen_zero(tz)) 02881 ast_localtime(&t, &tm, tz); 02882 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02883 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02884 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02885 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02886 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02887 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02888 return tmp; 02889 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1610 of file chan_iax2.c.
References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_translator_free_path(), ast_variables_destroy(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgetrans, iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, ast_iax2_queue::head, iax2_frame_free(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxq, iaxs, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, lastused, ast_user_list::lock, ast_channel::lock, LOG_NOTICE, iax_frame::next, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, chan_iax2_pvt::reg, iax_frame::retries, sched, update_max_trunk(), user, userl, chan_iax2_pvt::username, ast_user_list::users, and chan_iax2_pvt::vars.
Referenced by __unload_module(), destroy_peer(), iax2_destroy_nolock(), iax2_poke_noanswer(), and iax2_poke_peer().
01611 { 01612 struct chan_iax2_pvt *pvt; 01613 struct iax_frame *cur; 01614 struct ast_channel *owner; 01615 struct iax2_user *user; 01616 01617 retry: 01618 ast_mutex_lock(&iaxsl[callno]); 01619 pvt = iaxs[callno]; 01620 gettimeofday(&lastused[callno], NULL); 01621 01622 if (pvt) 01623 owner = pvt->owner; 01624 else 01625 owner = NULL; 01626 if (owner) { 01627 if (ast_mutex_trylock(&owner->lock)) { 01628 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01629 ast_mutex_unlock(&iaxsl[callno]); 01630 usleep(1); 01631 goto retry; 01632 } 01633 } 01634 if (!owner) 01635 iaxs[callno] = NULL; 01636 if (pvt) { 01637 if (!owner) 01638 pvt->owner = NULL; 01639 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01640 ast_mutex_lock(&userl.lock); 01641 user = userl.users; 01642 while (user) { 01643 if (!strcmp(user->name, pvt->username)) { 01644 user->curauthreq--; 01645 break; 01646 } 01647 user = user->next; 01648 } 01649 ast_mutex_unlock(&userl.lock); 01650 } 01651 /* No more pings or lagrq's */ 01652 if (pvt->pingid > -1) 01653 ast_sched_del(sched, pvt->pingid); 01654 if (pvt->lagid > -1) 01655 ast_sched_del(sched, pvt->lagid); 01656 if (pvt->autoid > -1) 01657 ast_sched_del(sched, pvt->autoid); 01658 if (pvt->authid > -1) 01659 ast_sched_del(sched, pvt->authid); 01660 if (pvt->initid > -1) 01661 ast_sched_del(sched, pvt->initid); 01662 #ifdef NEWJB 01663 if (pvt->jbid > -1) 01664 ast_sched_del(sched, pvt->jbid); 01665 pvt->jbid = -1; 01666 #endif 01667 pvt->pingid = -1; 01668 pvt->lagid = -1; 01669 pvt->autoid = -1; 01670 pvt->authid = -1; 01671 pvt->initid = -1; 01672 if (pvt->bridgetrans) 01673 ast_translator_free_path(pvt->bridgetrans); 01674 pvt->bridgetrans = NULL; 01675 01676 /* Already gone */ 01677 ast_set_flag(pvt, IAX_ALREADYGONE); 01678 01679 if (owner) { 01680 /* If there's an owner, prod it to give up */ 01681 owner->_softhangup |= AST_SOFTHANGUP_DEV; 01682 ast_queue_hangup(owner); 01683 } 01684 01685 for (cur = iaxq.head; cur ; cur = cur->next) { 01686 /* Cancel any pending transmissions */ 01687 if (cur->callno == pvt->callno) 01688 cur->retries = -1; 01689 } 01690 if (pvt->reg) { 01691 pvt->reg->callno = 0; 01692 } 01693 if (!owner) { 01694 if (pvt->vars) { 01695 ast_variables_destroy(pvt->vars); 01696 pvt->vars = NULL; 01697 } 01698 #ifdef NEWJB 01699 { 01700 jb_frame frame; 01701 while(jb_getall(pvt->jb,&frame) == JB_OK) 01702 iax2_frame_free(frame.data); 01703 jb_destroy(pvt->jb); 01704 } 01705 #endif 01706 free(pvt); 01707 } 01708 } 01709 if (owner) { 01710 ast_mutex_unlock(&owner->lock); 01711 } 01712 ast_mutex_unlock(&iaxsl[callno]); 01713 if (callno & 0x4000) 01714 update_max_trunk(); 01715 }
static void iax2_destroy_nolock | ( | int | callno | ) | [static] |
Definition at line 1716 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().
01717 { 01718 /* Actually it's easier to unlock, kill it, and relock */ 01719 ast_mutex_unlock(&iaxsl[callno]); 01720 iax2_destroy(callno); 01721 ast_mutex_lock(&iaxsl[callno]); 01722 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Definition at line 9425 of file chan_iax2.c.
References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, iax2_peer::maxms, option_debug, and parse_dial_string().
09426 { 09427 struct parsed_dial_string pds; 09428 char *tmp = ast_strdupa(data); 09429 struct iax2_peer *p; 09430 int res = AST_DEVICE_INVALID; 09431 09432 memset(&pds, 0, sizeof(pds)); 09433 parse_dial_string(tmp, &pds); 09434 if (!pds.peer || ast_strlen_zero(pds.peer)) 09435 return res; 09436 09437 if (option_debug > 2) 09438 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 09439 09440 /* SLD: FIXME: second call to find_peer during registration */ 09441 if (!(p = find_peer(pds.peer, 1))) 09442 return res; 09443 09444 res = AST_DEVICE_UNAVAILABLE; 09445 if (option_debug > 2) 09446 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09447 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09448 09449 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09450 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09451 /* Peer is registered, or have default IP address 09452 and a valid registration */ 09453 if (p->historicms == 0 || p->historicms <= p->maxms) 09454 /* let the core figure out whether it is in use or not */ 09455 res = AST_DEVICE_UNKNOWN; 09456 } 09457 09458 if (ast_test_flag(p, IAX_TEMPONLY)) 09459 destroy_peer(p); 09460 09461 return res; 09462 }
static int iax2_digit | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2564 of file chan_iax2.c.
References AST_FRAME_DTMF, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02565 { 02566 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1); 02567 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4587 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04588 { 04589 if (argc != 2) 04590 return RESULT_SHOWUSAGE; 04591 iaxdebug = 1; 04592 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04593 return RESULT_SUCCESS; 04594 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4605 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04606 { 04607 if (argc != 3) 04608 return RESULT_SHOWUSAGE; 04609 #ifdef NEWJB 04610 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04611 #endif 04612 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04613 return RESULT_SUCCESS; 04614 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 7739 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_log(), ast_sched_add(), ast_sched_del(), iax2_registry::callno, 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, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, REG_STATE_REGSENT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by iax2_do_register_s(), and load_module().
07740 { 07741 struct iax_ie_data ied; 07742 if (option_debug && iaxdebug) 07743 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07744 if (!reg->callno) { 07745 if (option_debug) 07746 ast_log(LOG_DEBUG, "Allocate call number\n"); 07747 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07748 if (reg->callno < 1) { 07749 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07750 return -1; 07751 } else if (option_debug) 07752 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07753 iaxs[reg->callno]->reg = reg; 07754 } 07755 /* Schedule the next registration attempt */ 07756 if (reg->expire > -1) 07757 ast_sched_del(sched, reg->expire); 07758 /* Setup the next registration a little early */ 07759 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07760 /* Send the request */ 07761 memset(&ied, 0, sizeof(ied)); 07762 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07763 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07764 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07765 reg->regstate = REG_STATE_REGSENT; 07766 return 0; 07767 }
static int iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5362 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_ack_registry(), and iax2_do_register().
05363 { 05364 struct iax2_registry *reg = data; 05365 reg->expire = -1; 05366 iax2_do_register(reg); 05367 return 0; 05368 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4596 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04597 { 04598 if (argc != 3) 04599 return RESULT_SHOWUSAGE; 04600 iaxtrunkdebug = 1; 04601 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04602 return RESULT_SUCCESS; 04603 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 5979 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, sched, and send_command().
Referenced by find_cache(), and socket_read().
05980 { 05981 struct iax_ie_data ied; 05982 /* Auto-hangup with 30 seconds of inactivity */ 05983 if (iaxs[callno]->autoid > -1) 05984 ast_sched_del(sched, iaxs[callno]->autoid); 05985 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 05986 memset(&ied, 0, sizeof(ied)); 05987 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 05988 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 05989 dp->flags |= CACHE_FLAG_TRANSMITTED; 05990 }
static int iax2_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
int | newstack, | |||
const char * | data | |||
) | [static] |
Definition at line 9283 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
09284 { 09285 char odata[256]; 09286 char req[256]; 09287 char *ncontext; 09288 char *dialstatus; 09289 struct iax2_dpcache *dp; 09290 struct ast_app *dial; 09291 #if 0 09292 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); 09293 #endif 09294 if (priority == 2) { 09295 /* Indicate status, can be overridden in dialplan */ 09296 dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09297 if (dialstatus) { 09298 dial = pbx_findapp(dialstatus); 09299 if (dial) 09300 pbx_exec(chan, dial, "", newstack); 09301 } 09302 return -1; 09303 } else if (priority != 1) 09304 return -1; 09305 ast_mutex_lock(&dpcache_lock); 09306 dp = find_cache(chan, data, context, exten, priority); 09307 if (dp) { 09308 if (dp->flags & CACHE_FLAG_EXISTS) { 09309 ast_copy_string(odata, data, sizeof(odata)); 09310 ncontext = strchr(odata, '/'); 09311 if (ncontext) { 09312 *ncontext = '\0'; 09313 ncontext++; 09314 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09315 } else { 09316 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09317 } 09318 if (option_verbose > 2) 09319 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09320 } else { 09321 ast_mutex_unlock(&dpcache_lock); 09322 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09323 return -1; 09324 } 09325 } 09326 ast_mutex_unlock(&dpcache_lock); 09327 dial = pbx_findapp("Dial"); 09328 if (dial) { 09329 return pbx_exec(chan, dial, req, newstack); 09330 } else { 09331 ast_log(LOG_WARNING, "No dial application registered\n"); 09332 } 09333 return -1; 09334 }
static int iax2_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 9214 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
09215 { 09216 struct iax2_dpcache *dp; 09217 int res = 0; 09218 #if 0 09219 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09220 #endif 09221 if ((priority != 1) && (priority != 2)) 09222 return 0; 09223 ast_mutex_lock(&dpcache_lock); 09224 dp = find_cache(chan, data, context, exten, priority); 09225 if (dp) { 09226 if (dp->flags & CACHE_FLAG_EXISTS) 09227 res= 1; 09228 } 09229 ast_mutex_unlock(&dpcache_lock); 09230 if (!dp) { 09231 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09232 } 09233 return res; 09234 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2586 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxsl, LOG_WARNING, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02587 { 02588 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02589 ast_mutex_lock(&iaxsl[callno]); 02590 if (iaxs[callno]) 02591 iaxs[callno]->owner = newchan; 02592 else 02593 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02594 ast_mutex_unlock(&iaxsl[callno]); 02595 return 0; 02596 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1130 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(), and iax2_destroy().
01131 { 01132 if (fr->retrans > -1) 01133 ast_sched_del(sched, fr->retrans); 01134 iax_frame_free(fr); 01135 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len, | |||
int | lockpeer | |||
) | [static] |
Definition at line 875 of file chan_iax2.c.
References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_peer(), IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer().
Referenced by find_callno().
00876 { 00877 struct iax2_peer *peer; 00878 int res = 0; 00879 00880 if (lockpeer) 00881 ast_mutex_lock(&peerl.lock); 00882 peer = peerl.peers; 00883 while (peer) { 00884 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 00885 (peer->addr.sin_port == sin.sin_port)) { 00886 ast_copy_string(host, peer->name, len); 00887 res = 1; 00888 break; 00889 } 00890 peer = peer->next; 00891 } 00892 if (lockpeer) 00893 ast_mutex_unlock(&peerl.lock); 00894 if (!peer) { 00895 peer = realtime_peer(NULL, &sin); 00896 if (peer) { 00897 ast_copy_string(host, peer->name, len); 00898 if (ast_test_flag(peer, IAX_TEMPONLY)) 00899 destroy_peer(peer); 00900 res = 1; 00901 } 00902 } 00903 00904 return res; 00905 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3403 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().
03404 { 03405 struct iax2_peer *peer; 03406 int res = 0; 03407 ast_mutex_lock(&peerl.lock); 03408 peer = peerl.peers; 03409 while(peer) { 03410 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03411 (peer->addr.sin_port == sin.sin_port)) { 03412 res = ast_test_flag(peer, IAX_TRUNK); 03413 break; 03414 } 03415 peer = peer->next; 03416 } 03417 ast_mutex_unlock(&peerl.lock); 03418 return res; 03419 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3091 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), error(), ast_channel::hangupcause, iax2_destroy_nolock(), iax2_predestroy_nolock(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxsl, ast_channel::name, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03092 { 03093 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03094 int alreadygone; 03095 struct iax_ie_data ied; 03096 memset(&ied, 0, sizeof(ied)); 03097 ast_mutex_lock(&iaxsl[callno]); 03098 if (callno && iaxs[callno]) { 03099 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03100 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03101 /* Send the hangup unless we have had a transmission error or are already gone */ 03102 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03103 if (!iaxs[callno]->error && !alreadygone) 03104 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03105 /* Explicitly predestroy it */ 03106 iax2_predestroy_nolock(callno); 03107 /* If we were already gone to begin with, destroy us now */ 03108 if (alreadygone) { 03109 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03110 iax2_destroy_nolock(callno); 03111 } 03112 } 03113 ast_mutex_unlock(&iaxsl[callno]); 03114 if (option_verbose > 2) 03115 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03116 return 0; 03117 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition | |||
) | [static] |
Definition at line 3372 of file chan_iax2.c.
References AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03373 { 03374 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03375 if (option_debug && iaxdebug) 03376 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03377 return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1); 03378 }
static int iax2_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 9260 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
09261 { 09262 int res = 0; 09263 struct iax2_dpcache *dp; 09264 #if 0 09265 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09266 #endif 09267 if ((priority != 1) && (priority != 2)) 09268 return 0; 09269 ast_mutex_lock(&dpcache_lock); 09270 dp = find_cache(chan, data, context, exten, priority); 09271 if (dp) { 09272 if (dp->flags & CACHE_FLAG_MATCHMORE) 09273 res= 1; 09274 } 09275 ast_mutex_unlock(&dpcache_lock); 09276 if (!dp) { 09277 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09278 } 09279 return res; 09280 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4616 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04617 { 04618 if (argc != 3) 04619 return RESULT_SHOWUSAGE; 04620 iaxdebug = 0; 04621 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04622 return RESULT_SUCCESS; 04623 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4634 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04635 { 04636 if (argc != 4) 04637 return RESULT_SHOWUSAGE; 04638 #ifdef NEWJB 04639 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04640 jb_debug_output("\n"); 04641 #endif 04642 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04643 return RESULT_SUCCESS; 04644 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4625 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04626 { 04627 if (argc != 4) 04628 return RESULT_SHOWUSAGE; 04629 iaxtrunkdebug = 0; 04630 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04631 return RESULT_SUCCESS; 04632 }
static int iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 7890 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().
07891 { 07892 struct iax2_peer *peer = data; 07893 peer->pokeexpire = -1; 07894 if (peer->lastms > -1) { 07895 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07896 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07897 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07898 } 07899 if (peer->callno > 0) 07900 iax2_destroy(peer->callno); 07901 peer->callno = 0; 07902 peer->lastms = -1; 07903 /* Try again quickly */ 07904 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07905 return 0; 07906 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 7908 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, 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().
07909 { 07910 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07911 /* IF we have no IP, or this isn't to be monitored, return 07912 imeediately after clearing things out */ 07913 peer->lastms = 0; 07914 peer->historicms = 0; 07915 peer->pokeexpire = -1; 07916 peer->callno = 0; 07917 return 0; 07918 } 07919 if (peer->callno > 0) { 07920 ast_log(LOG_NOTICE, "Still have a callno...\n"); 07921 iax2_destroy(peer->callno); 07922 } 07923 if (heldcall) 07924 ast_mutex_unlock(&iaxsl[heldcall]); 07925 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 07926 if (heldcall) 07927 ast_mutex_lock(&iaxsl[heldcall]); 07928 if (peer->callno < 1) { 07929 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 07930 return -1; 07931 } 07932 if (peer->pokeexpire > -1) 07933 ast_sched_del(sched, peer->pokeexpire); 07934 /* Speed up retransmission times */ 07935 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 07936 iaxs[peer->callno]->peerpoke = peer; 07937 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 07938 07939 /* If the host is already unreachable then use the unreachable interval instead */ 07940 if (peer->lastms < 0) { 07941 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 07942 } else 07943 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 07944 07945 return 0; 07946 }
static int iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 6013 of file chan_iax2.c.
References iax2_poke_peer(), and iax2_peer::pokeexpire.
Referenced by iax2_poke_noanswer(), and socket_read().
06014 { 06015 struct iax2_peer *peer = data; 06016 peer->pokeexpire = -1; 06017 iax2_poke_peer(peer, 0); 06018 return 0; 06019 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1537 of file chan_iax2.c.
References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_update_use_count(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxs, iaxsl, ast_user_list::lock, LOG_WARNING, chan_iax2_pvt::owner, sched, ast_channel::tech_pvt, usecnt_lock, user, userl, and ast_user_list::users.
Referenced by iax2_predestroy_nolock().
01538 { 01539 struct ast_channel *c; 01540 struct chan_iax2_pvt *pvt; 01541 struct iax2_user *user; 01542 ast_mutex_lock(&iaxsl[callno]); 01543 pvt = iaxs[callno]; 01544 if (!pvt) { 01545 ast_mutex_unlock(&iaxsl[callno]); 01546 return -1; 01547 } 01548 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01549 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01550 ast_mutex_lock(&userl.lock); 01551 user = userl.users; 01552 while (user) { 01553 if (!strcmp(user->name, pvt->username)) { 01554 user->curauthreq--; 01555 break; 01556 } 01557 user = user->next; 01558 } 01559 ast_mutex_unlock(&userl.lock); 01560 } 01561 /* No more pings or lagrq's */ 01562 if (pvt->pingid > -1) 01563 ast_sched_del(sched, pvt->pingid); 01564 if (pvt->lagid > -1) 01565 ast_sched_del(sched, pvt->lagid); 01566 if (pvt->autoid > -1) 01567 ast_sched_del(sched, pvt->autoid); 01568 if (pvt->authid > -1) 01569 ast_sched_del(sched, pvt->authid); 01570 if (pvt->initid > -1) 01571 ast_sched_del(sched, pvt->initid); 01572 #ifdef NEWJB 01573 if (pvt->jbid > -1) 01574 ast_sched_del(sched, pvt->jbid); 01575 pvt->jbid = -1; 01576 #endif 01577 pvt->pingid = -1; 01578 pvt->lagid = -1; 01579 pvt->autoid = -1; 01580 pvt->initid = -1; 01581 pvt->authid = -1; 01582 ast_set_flag(pvt, IAX_ALREADYGONE); 01583 } 01584 c = pvt->owner; 01585 if (c) { 01586 c->_softhangup |= AST_SOFTHANGUP_DEV; 01587 c->tech_pvt = NULL; 01588 ast_queue_hangup(c); 01589 pvt->owner = NULL; 01590 ast_mutex_lock(&usecnt_lock); 01591 usecnt--; 01592 if (usecnt < 0) 01593 ast_log(LOG_WARNING, "Usecnt < 0???\n"); 01594 ast_mutex_unlock(&usecnt_lock); 01595 } 01596 ast_mutex_unlock(&iaxsl[callno]); 01597 ast_update_use_count(); 01598 return 0; 01599 }
static int iax2_predestroy_nolock | ( | int | callno | ) | [static] |
Definition at line 1601 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iax2_predestroy(), and iaxsl.
Referenced by iax2_hangup(), and send_command_final().
01602 { 01603 int res; 01604 ast_mutex_unlock(&iaxsl[callno]); 01605 res = iax2_predestroy(callno); 01606 ast_mutex_lock(&iaxsl[callno]); 01607 return res; 01608 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 7868 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
07869 { 07870 int force = 0; 07871 int res; 07872 if (argc < 4) 07873 return RESULT_SHOWUSAGE; 07874 if ((argc > 4)) { 07875 if (!strcasecmp(argv[4], "forced")) 07876 force = 1; 07877 else 07878 return RESULT_SHOWUSAGE; 07879 } 07880 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07881 if (res < 0) 07882 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07883 else if (res < 1) 07884 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07885 else 07886 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07887 return RESULT_SUCCESS; 07888 }
static char* iax2_prov_complete_template_3rd | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 7769 of file chan_iax2.c.
References iax_prov_complete_template().
07770 { 07771 if (pos != 3) 07772 return NULL; 07773 return iax_prov_complete_template(line, word, pos, state); 07774 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 7776 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), iax_ie_data::buf, create_addr(), find_callno(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
07777 { 07778 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07779 is found for template */ 07780 struct iax_ie_data provdata; 07781 struct iax_ie_data ied; 07782 unsigned int sig; 07783 struct sockaddr_in sin; 07784 int callno; 07785 struct create_addr_info cai; 07786 07787 memset(&cai, 0, sizeof(cai)); 07788 07789 if (option_debug) 07790 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07791 07792 if (iax_provision_build(&provdata, &sig, template, force)) { 07793 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07794 return 0; 07795 } 07796 07797 if (end) { 07798 memcpy(&sin, end, sizeof(sin)); 07799 cai.sockfd = sockfd; 07800 } else if (create_addr(dest, &sin, &cai)) 07801 return -1; 07802 07803 /* Build the rest of the message */ 07804 memset(&ied, 0, sizeof(ied)); 07805 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07806 07807 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07808 if (!callno) 07809 return -1; 07810 07811 ast_mutex_lock(&iaxsl[callno]); 07812 if (iaxs[callno]) { 07813 /* Schedule autodestruct in case they don't ever give us anything back */ 07814 if (iaxs[callno]->autoid > -1) 07815 ast_sched_del(sched, iaxs[callno]->autoid); 07816 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07817 ast_set_flag(iaxs[callno], IAX_PROVISION); 07818 /* Got a call number now, so go ahead and send the provisioning information */ 07819 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07820 } 07821 ast_mutex_unlock(&iaxsl[callno]); 07822 07823 return 1; 07824 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1862 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01863 { 01864 struct iax2_peer *peer; 01865 01866 if (argc != 4) 01867 return RESULT_SHOWUSAGE; 01868 if (!strcmp(argv[3],"all")) { 01869 reload_config(); 01870 ast_cli(fd, "OK cache is flushed.\n"); 01871 } else if ((peer = find_peer(argv[3], 0))) { 01872 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 01873 ast_set_flag(peer, IAX_RTAUTOCLEAR); 01874 expire_registry(peer); 01875 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 01876 } else { 01877 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 01878 } 01879 } else { 01880 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 01881 } 01882 01883 return RESULT_SUCCESS; 01884 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 1137 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), and iaxs.
Referenced by __do_deliver(), attempt_transmit(), auto_congest(), get_from_jb(), and socket_read().
01138 { 01139 /* Assumes lock for callno is already held... */ 01140 for (;;) { 01141 if (iaxs[callno] && iaxs[callno]->owner) { 01142 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01143 /* Avoid deadlock by pausing and trying again */ 01144 ast_mutex_unlock(&iaxsl[callno]); 01145 usleep(1); 01146 ast_mutex_lock(&iaxsl[callno]); 01147 } else { 01148 ast_queue_frame(iaxs[callno]->owner, f); 01149 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01150 break; 01151 } 01152 } else 01153 break; 01154 } 01155 return 0; 01156 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3148 of file chan_iax2.c.
References AST_FRAME_NULL, ast_log(), and LOG_NOTICE.
03149 { 03150 static struct ast_frame f = { AST_FRAME_NULL, }; 03151 ast_log(LOG_NOTICE, "I should never be called!\n"); 03152 return &f; 03153 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5576 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_log(), iax2_registry::callno, copy(), hostname, hp, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_ERROR, LOG_WARNING, malloc, registrations, secret, and strsep().
Referenced by set_config().
05577 { 05578 struct iax2_registry *reg; 05579 char copy[256]; 05580 char *username, *hostname, *secret; 05581 char *porta; 05582 char *stringp=NULL; 05583 05584 struct ast_hostent ahp; struct hostent *hp; 05585 if (!value) 05586 return -1; 05587 ast_copy_string(copy, value, sizeof(copy)); 05588 stringp=copy; 05589 username = strsep(&stringp, "@"); 05590 hostname = strsep(&stringp, "@"); 05591 if (!hostname) { 05592 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno); 05593 return -1; 05594 } 05595 stringp=username; 05596 username = strsep(&stringp, ":"); 05597 secret = strsep(&stringp, ":"); 05598 stringp=hostname; 05599 hostname = strsep(&stringp, ":"); 05600 porta = strsep(&stringp, ":"); 05601 05602 if (porta && !atoi(porta)) { 05603 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05604 return -1; 05605 } 05606 hp = ast_gethostbyname(hostname, &ahp); 05607 if (!hp) { 05608 ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno); 05609 return -1; 05610 } 05611 reg = malloc(sizeof(struct iax2_registry)); 05612 if (reg) { 05613 memset(reg, 0, sizeof(struct iax2_registry)); 05614 ast_copy_string(reg->username, username, sizeof(reg->username)); 05615 if (secret) 05616 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05617 reg->expire = -1; 05618 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05619 reg->addr.sin_family = AF_INET; 05620 memcpy(®->addr.sin_addr, hp->h_addr, sizeof(®->addr.sin_addr)); 05621 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05622 reg->next = registrations; 05623 reg->callno = 0; 05624 registrations = reg; 05625 } else { 05626 ast_log(LOG_ERROR, "Out of memory\n"); 05627 return -1; 05628 } 05629 return 0; 05630 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8986 of file chan_iax2.c.
References reload_config().
08987 { 08988 return reload_config(); 08989 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7958 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), fmt, globalflags, host, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxsl, LOG_WARNING, make_trunk(), ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.
07959 { 07960 int callno; 07961 int res; 07962 int fmt, native; 07963 struct sockaddr_in sin; 07964 struct ast_channel *c; 07965 struct parsed_dial_string pds; 07966 struct create_addr_info cai; 07967 char *tmpstr; 07968 07969 memset(&pds, 0, sizeof(pds)); 07970 tmpstr = ast_strdupa(data); 07971 parse_dial_string(tmpstr, &pds); 07972 07973 memset(&cai, 0, sizeof(cai)); 07974 cai.capability = iax2_capability; 07975 07976 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07977 07978 if (!pds.peer) { 07979 ast_log(LOG_WARNING, "No peer given\n"); 07980 return NULL; 07981 } 07982 07983 07984 /* Populate our address from the given */ 07985 if (create_addr(pds.peer, &sin, &cai)) { 07986 *cause = AST_CAUSE_UNREGISTERED; 07987 return NULL; 07988 } 07989 07990 if (pds.port) 07991 sin.sin_port = htons(atoi(pds.port)); 07992 07993 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07994 if (callno < 1) { 07995 ast_log(LOG_WARNING, "Unable to create call\n"); 07996 *cause = AST_CAUSE_CONGESTION; 07997 return NULL; 07998 } 07999 08000 ast_mutex_lock(&iaxsl[callno]); 08001 08002 /* If this is a trunk, update it now */ 08003 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08004 if (ast_test_flag(&cai, IAX_TRUNK)) 08005 callno = make_trunk(callno, 1); 08006 iaxs[callno]->maxtime = cai.maxtime; 08007 if (cai.found) 08008 ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host)); 08009 08010 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08011 08012 ast_mutex_unlock(&iaxsl[callno]); 08013 08014 if (c) { 08015 /* Choose a format we can live with */ 08016 if (c->nativeformats & format) 08017 c->nativeformats &= format; 08018 else { 08019 native = c->nativeformats; 08020 fmt = format; 08021 res = ast_translator_best_choice(&fmt, &native); 08022 if (res < 0) { 08023 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08024 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08025 ast_hangup(c); 08026 return NULL; 08027 } 08028 c->nativeformats = native; 08029 } 08030 c->readformat = ast_best_codec(c->nativeformats); 08031 c->writeformat = c->readformat; 08032 } 08033 08034 return c; 08035 }
static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f, | |||
unsigned int | ts, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 3978 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_read().
03979 { 03980 /* Queue a packet for delivery on a given private structure. Use "ts" for 03981 timestamp, or calculate if ts is 0. Send immediately without retransmission 03982 or delayed, with retransmission */ 03983 struct ast_iax2_full_hdr *fh; 03984 struct ast_iax2_mini_hdr *mh; 03985 struct ast_iax2_video_hdr *vh; 03986 struct { 03987 struct iax_frame fr2; 03988 unsigned char buffer[4096]; 03989 } frb; 03990 struct iax_frame *fr; 03991 int res; 03992 int sendmini=0; 03993 unsigned int lastsent; 03994 unsigned int fts; 03995 03996 if (!pvt) { 03997 ast_log(LOG_WARNING, "No private structure for packet?\n"); 03998 return -1; 03999 } 04000 04001 lastsent = pvt->lastsent; 04002 04003 /* Calculate actual timestamp */ 04004 fts = calc_timestamp(pvt, ts, f); 04005 04006 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04007 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04008 * increment the "predicted timestamps" for voice, if we're predecting */ 04009 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04010 return 0; 04011 04012 04013 if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L))) 04014 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04015 (f->frametype == AST_FRAME_VOICE) 04016 /* is a voice frame */ && 04017 (f->subclass == pvt->svoiceformat) 04018 /* is the same type */ ) { 04019 /* Force immediate rather than delayed transmission */ 04020 now = 1; 04021 /* Mark that mini-style frame is appropriate */ 04022 sendmini = 1; 04023 } 04024 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 04025 (f->frametype == AST_FRAME_VIDEO) && 04026 ((f->subclass & ~0x1) == pvt->svideoformat)) { 04027 now = 1; 04028 sendmini = 1; 04029 } 04030 /* Allocate an iax_frame */ 04031 if (now) { 04032 fr = &frb.fr2; 04033 } else 04034 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen); 04035 if (!fr) { 04036 ast_log(LOG_WARNING, "Out of memory\n"); 04037 return -1; 04038 } 04039 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04040 iax_frame_wrap(fr, f); 04041 04042 fr->ts = fts; 04043 fr->callno = pvt->callno; 04044 fr->transfer = transfer; 04045 fr->final = final; 04046 if (!sendmini) { 04047 /* We need a full frame */ 04048 if (seqno > -1) 04049 fr->oseqno = seqno; 04050 else 04051 fr->oseqno = pvt->oseqno++; 04052 fr->iseqno = pvt->iseqno; 04053 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04054 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04055 fh->ts = htonl(fr->ts); 04056 fh->oseqno = fr->oseqno; 04057 if (transfer) { 04058 fh->iseqno = 0; 04059 } else 04060 fh->iseqno = fr->iseqno; 04061 /* Keep track of the last thing we've acknowledged */ 04062 if (!transfer) 04063 pvt->aseqno = fr->iseqno; 04064 fh->type = fr->af.frametype & 0xFF; 04065 if (fr->af.frametype == AST_FRAME_VIDEO) 04066 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04067 else 04068 fh->csub = compress_subclass(fr->af.subclass); 04069 if (transfer) { 04070 fr->dcallno = pvt->transfercallno; 04071 } else 04072 fr->dcallno = pvt->peercallno; 04073 fh->dcallno = htons(fr->dcallno); 04074 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04075 fr->data = fh; 04076 fr->retries = 0; 04077 /* Retry after 2x the ping time has passed */ 04078 fr->retrytime = pvt->pingtime * 2; 04079 if (fr->retrytime < MIN_RETRY_TIME) 04080 fr->retrytime = MIN_RETRY_TIME; 04081 if (fr->retrytime > MAX_RETRY_TIME) 04082 fr->retrytime = MAX_RETRY_TIME; 04083 /* Acks' don't get retried */ 04084 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04085 fr->retries = -1; 04086 else if (f->frametype == AST_FRAME_VOICE) 04087 pvt->svoiceformat = f->subclass; 04088 else if (f->frametype == AST_FRAME_VIDEO) 04089 pvt->svideoformat = f->subclass & ~0x1; 04090 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04091 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04092 if (iaxdebug) { 04093 if (fr->transfer) 04094 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04095 else 04096 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04097 } 04098 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04099 } else 04100 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04101 } 04102 04103 if (now) { 04104 res = send_packet(fr); 04105 } else 04106 res = iax2_transmit(fr); 04107 } else { 04108 if (ast_test_flag(pvt, IAX_TRUNK)) { 04109 iax2_trunk_queue(pvt, fr); 04110 res = 0; 04111 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04112 /* Video frame have no sequence number */ 04113 fr->oseqno = -1; 04114 fr->iseqno = -1; 04115 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04116 vh->zeros = 0; 04117 vh->callno = htons(0x8000 | fr->callno); 04118 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04119 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04120 fr->data = vh; 04121 fr->retries = -1; 04122 res = send_packet(fr); 04123 } else { 04124 /* Mini-frames have no sequence number */ 04125 fr->oseqno = -1; 04126 fr->iseqno = -1; 04127 /* Mini frame will do */ 04128 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04129 mh->callno = htons(fr->callno); 04130 mh->ts = htons(fr->ts & 0xFFFF); 04131 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04132 fr->data = mh; 04133 fr->retries = -1; 04134 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04135 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04136 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04137 } else 04138 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04139 } 04140 res = send_packet(fr); 04141 } 04142 } 04143 return res; 04144 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2581 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02582 { 02583 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02584 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2576 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
02577 { 02578 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02579 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2569 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02570 { 02571 02572 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02573 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02574 }
static int iax2_set_jitter | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1826 of file chan_iax2.c.
References ast_cli(), IAX_MAX_CALLS, iaxs, max_jitter_buffer, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01827 { 01828 #ifdef NEWJB 01829 ast_cli(fd, "sorry, this command is deprecated\n"); 01830 return RESULT_SUCCESS; 01831 #else 01832 if ((argc != 4) && (argc != 5)) 01833 return RESULT_SHOWUSAGE; 01834 if (argc == 4) { 01835 max_jitter_buffer = atoi(argv[3]); 01836 if (max_jitter_buffer < 0) 01837 max_jitter_buffer = 0; 01838 } else { 01839 if (argc == 5) { 01840 if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) { 01841 if (iaxs[atoi(argv[3])]) { 01842 iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]); 01843 if (iaxs[atoi(argv[3])]->jitterbuffer < 0) 01844 iaxs[atoi(argv[3])]->jitterbuffer = 0; 01845 } else 01846 ast_cli(fd, "No such call '%d'\n", atoi(argv[3])); 01847 } else 01848 ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3])); 01849 } 01850 } 01851 return RESULT_SUCCESS; 01852 #endif 01853 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3119 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_log(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, free, LOG_WARNING, malloc, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03120 { 03121 struct ast_option_header *h; 03122 int res; 03123 03124 switch (option) { 03125 case AST_OPTION_TXGAIN: 03126 case AST_OPTION_RXGAIN: 03127 /* these two cannot be sent, because they require a result */ 03128 errno = ENOSYS; 03129 return -1; 03130 default: 03131 h = malloc(datalen + sizeof(*h)); 03132 if (h) { 03133 h->flag = AST_OPTION_FLAG_REQUEST; 03134 h->option = htons(option); 03135 memcpy(h->data, data, datalen); 03136 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03137 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03138 datalen + sizeof(*h), -1); 03139 free(h); 03140 return res; 03141 } else { 03142 ast_log(LOG_WARNING, "Out of memory\n"); 03143 return -1; 03144 } 03145 } 03146 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2059 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02060 { 02061 struct iax2_dpcache *dp; 02062 char tmp[1024], *pc; 02063 int s; 02064 int x,y; 02065 struct timeval tv; 02066 gettimeofday(&tv, NULL); 02067 ast_mutex_lock(&dpcache_lock); 02068 dp = dpcache; 02069 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02070 while(dp) { 02071 s = dp->expiry.tv_sec - tv.tv_sec; 02072 tmp[0] = '\0'; 02073 if (dp->flags & CACHE_FLAG_EXISTS) 02074 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02075 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02076 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02077 if (dp->flags & CACHE_FLAG_CANEXIST) 02078 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02079 if (dp->flags & CACHE_FLAG_PENDING) 02080 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02081 if (dp->flags & CACHE_FLAG_TIMEOUT) 02082 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02083 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02084 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02085 if (dp->flags & CACHE_FLAG_MATCHMORE) 02086 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02087 if (dp->flags & CACHE_FLAG_UNKNOWN) 02088 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02089 /* Trim trailing pipe */ 02090 if (!ast_strlen_zero(tmp)) 02091 tmp[strlen(tmp) - 1] = '\0'; 02092 else 02093 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02094 y=0; 02095 pc = strchr(dp->peercontext, '@'); 02096 if (!pc) 02097 pc = dp->peercontext; 02098 else 02099 pc++; 02100 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02101 if (dp->waiters[x] > -1) 02102 y++; 02103 if (s > 0) 02104 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02105 else 02106 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02107 dp = dp->next; 02108 } 02109 ast_mutex_unlock(&dpcache_lock); 02110 return RESULT_SUCCESS; 02111 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4429 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_registry::callno, jb_info::current, FORMAT, FORMAT2, FORMATB, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04430 { 04431 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04432 #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" 04433 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04434 int x; 04435 int numchans = 0; 04436 char iabuf[INET_ADDRSTRLEN]; 04437 04438 if (argc != 3) 04439 return RESULT_SHOWUSAGE; 04440 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04441 for (x=0;x<IAX_MAX_CALLS;x++) { 04442 ast_mutex_lock(&iaxsl[x]); 04443 if (iaxs[x]) { 04444 #ifdef BRIDGE_OPTIMIZATION 04445 if (iaxs[x]->bridgecallno) 04446 ast_cli(fd, FORMATB, 04447 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04448 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04449 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04450 iaxs[x]->callno, iaxs[x]->peercallno, 04451 iaxs[x]->oseqno, iaxs[x]->iseqno, 04452 iaxs[x]->bridgecallno ); 04453 else 04454 #endif 04455 { 04456 int lag, jitter, localdelay; 04457 #ifdef NEWJB 04458 jb_info jbinfo; 04459 04460 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04461 jb_getinfo(iaxs[x]->jb, &jbinfo); 04462 jitter = jbinfo.jitter; 04463 localdelay = jbinfo.current - jbinfo.min; 04464 } else { 04465 jitter = -1; 04466 localdelay = 0; 04467 } 04468 #else 04469 jitter = iaxs[x]->jitter; 04470 localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0; 04471 #endif 04472 lag = iaxs[x]->remote_rr.delay; 04473 ast_cli(fd, FORMAT, 04474 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04475 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 04476 !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 04477 iaxs[x]->callno, iaxs[x]->peercallno, 04478 iaxs[x]->oseqno, iaxs[x]->iseqno, 04479 lag, 04480 jitter, 04481 localdelay, 04482 ast_getformatname(iaxs[x]->voiceformat) ); 04483 } 04484 numchans++; 04485 } 04486 ast_mutex_unlock(&iaxsl[x]); 04487 } 04488 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04489 return RESULT_SUCCESS; 04490 #undef FORMAT 04491 #undef FORMAT2 04492 #undef FORMATB 04493 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4326 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, FORMAT, FORMAT2, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
04327 { 04328 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04329 #if !defined(__FreeBSD__) 04330 #define FORMAT "%-15.15s %-15d %-15d\n" 04331 #else /* __FreeBSD__ */ 04332 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04333 #endif /* __FreeBSD__ */ 04334 struct iax_firmware *cur; 04335 if ((argc != 3) && (argc != 4)) 04336 return RESULT_SHOWUSAGE; 04337 ast_mutex_lock(&waresl.lock); 04338 04339 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04340 for (cur = waresl.wares;cur;cur = cur->next) { 04341 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04342 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04343 (int)ntohl(cur->fwh->datalen)); 04344 } 04345 ast_mutex_unlock(&waresl.lock); 04346 return RESULT_SUCCESS; 04347 #undef FORMAT 04348 #undef FORMAT2 04349 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4575 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04576 { 04577 int numchans = 0; 04578 if (argc != 3) 04579 return RESULT_SHOWUSAGE; 04580 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04581 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04582 numchans = ast_cli_netstats(fd, 1); 04583 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04584 return RESULT_SUCCESS; 04585 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1955 of file chan_iax2.c.
References iax2_peer::addr, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::defaddr, destroy_peer(), iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TEMPONLY, iax2_peer::mailbox, iax2_peer::name, peer_status(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.
01956 { 01957 char status[30]; 01958 char cbuf[256]; 01959 char iabuf[INET_ADDRSTRLEN]; 01960 struct iax2_peer *peer; 01961 char codec_buf[512]; 01962 int x = 0, codec = 0, load_realtime = 0; 01963 01964 if (argc < 4) 01965 return RESULT_SHOWUSAGE; 01966 01967 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 01968 01969 peer = find_peer(argv[3], load_realtime); 01970 if (peer) { 01971 ast_cli(fd,"\n\n"); 01972 ast_cli(fd, " * Name : %s\n", peer->name); 01973 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 01974 ast_cli(fd, " Context : %s\n", peer->context); 01975 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 01976 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 01977 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 01978 ast_cli(fd, " Expire : %d\n", peer->expire); 01979 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 01980 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 01981 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 01982 ast_cli(fd, " Username : %s\n", peer->username); 01983 ast_cli(fd, " Codecs : "); 01984 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 01985 ast_cli(fd, "%s\n", codec_buf); 01986 01987 ast_cli(fd, " Codec Order : ("); 01988 for(x = 0; x < 32 ; x++) { 01989 codec = ast_codec_pref_index(&peer->prefs,x); 01990 if(!codec) 01991 break; 01992 ast_cli(fd, "%s", ast_getformatname(codec)); 01993 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 01994 ast_cli(fd, "|"); 01995 } 01996 01997 if (!x) 01998 ast_cli(fd, "none"); 01999 ast_cli(fd, ")\n"); 02000 02001 ast_cli(fd, " Status : "); 02002 peer_status(peer, status, sizeof(status)); 02003 ast_cli(fd, "%s\n",status); 02004 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02005 ast_cli(fd,"\n"); 02006 if (ast_test_flag(peer, IAX_TEMPONLY)) 02007 destroy_peer(peer); 02008 } else { 02009 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02010 ast_cli(fd,"\n"); 02011 } 02012 02013 return RESULT_SUCCESS; 02014 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4315 of file chan_iax2.c.
References __iax2_show_peers().
04316 { 04317 return __iax2_show_peers(0, fd, argc, argv); 04318 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4387 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), FORMAT, FORMAT2, host, ast_peer_list::lock, iax2_registry::next, peerl, iax2_registry::refresh, registrations, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
04388 { 04389 #define FORMAT2 "%-20.20s %-10.10s %-20.20s %8.8s %s\n" 04390 #define FORMAT "%-20.20s %-10.10s %-20.20s %8d %s\n" 04391 struct iax2_registry *reg; 04392 char host[80]; 04393 char perceived[80]; 04394 char iabuf[INET_ADDRSTRLEN]; 04395 if (argc != 3) 04396 return RESULT_SHOWUSAGE; 04397 ast_mutex_lock(&peerl.lock); 04398 ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State"); 04399 for (reg = registrations;reg;reg = reg->next) { 04400 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04401 if (reg->us.sin_addr.s_addr) 04402 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); 04403 else 04404 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04405 ast_cli(fd, FORMAT, host, 04406 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04407 } 04408 ast_mutex_unlock(&peerl.lock); 04409 return RESULT_SUCCESS; 04410 #undef FORMAT 04411 #undef FORMAT2 04412 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2039 of file chan_iax2.c.
References ast_cli(), iax_frame::final, ast_iax2_queue::head, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02040 { 02041 struct iax_frame *cur; 02042 int cnt = 0, dead=0, final=0; 02043 if (argc != 3) 02044 return RESULT_SHOWUSAGE; 02045 for (cur = iaxq.head; cur ; cur = cur->next) { 02046 if (cur->retries < 0) 02047 dead++; 02048 if (cur->final) 02049 final++; 02050 cnt++; 02051 } 02052 ast_cli(fd, " IAX Statistics\n"); 02053 ast_cli(fd, "---------------------\n"); 02054 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02055 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt); 02056 return RESULT_SUCCESS; 02057 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4148 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_user_list::lock, RESULT_SHOWUSAGE, RESULT_SUCCESS, user, userl, and ast_user_list::users.
04149 { 04150 regex_t regexbuf; 04151 int havepattern = 0; 04152 04153 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04154 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04155 04156 struct iax2_user *user; 04157 char auth[90]; 04158 char *pstr = ""; 04159 04160 switch (argc) { 04161 case 5: 04162 if (!strcasecmp(argv[3], "like")) { 04163 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04164 return RESULT_SHOWUSAGE; 04165 havepattern = 1; 04166 } else 04167 return RESULT_SHOWUSAGE; 04168 case 3: 04169 break; 04170 default: 04171 return RESULT_SHOWUSAGE; 04172 } 04173 04174 ast_mutex_lock(&userl.lock); 04175 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04176 for(user=userl.users;user;user=user->next) { 04177 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04178 continue; 04179 04180 if (!ast_strlen_zero(user->secret)) { 04181 ast_copy_string(auth,user->secret,sizeof(auth)); 04182 } else if (!ast_strlen_zero(user->inkeys)) { 04183 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04184 } else 04185 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04186 04187 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04188 pstr = "REQ Only"; 04189 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04190 pstr = "Disabled"; 04191 else 04192 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04193 04194 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04195 user->contexts ? user->contexts->context : context, 04196 user->ha ? "Yes" : "No", pstr); 04197 04198 } 04199 ast_mutex_unlock(&userl.lock); 04200 04201 if (havepattern) 04202 regfree(®exbuf); 04203 04204 return RESULT_SUCCESS; 04205 #undef FORMAT 04206 #undef FORMAT2 04207 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3155 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, send_command(), and TRANSFER_BEGIN.
03156 { 03157 int res; 03158 struct iax_ie_data ied0; 03159 struct iax_ie_data ied1; 03160 unsigned int transferid = rand(); 03161 memset(&ied0, 0, sizeof(ied0)); 03162 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03163 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03164 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03165 03166 memset(&ied1, 0, sizeof(ied1)); 03167 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03168 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03169 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03170 03171 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03172 if (res) 03173 return -1; 03174 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03175 if (res) 03176 return -1; 03177 iaxs[callno0]->transferring = TRANSFER_BEGIN; 03178 iaxs[callno1]->transferring = TRANSFER_BEGIN; 03179 return 0; 03180 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1886 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01887 { 01888 if (argc != 4) 01889 return RESULT_SHOWUSAGE; 01890 01891 test_losspct = atoi(argv[3]); 01892 01893 return RESULT_SUCCESS; 01894 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3380 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03381 { 03382 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03383 struct iax_ie_data ied; 03384 char tmp[256], *context; 03385 ast_copy_string(tmp, dest, sizeof(tmp)); 03386 context = strchr(tmp, '@'); 03387 if (context) { 03388 *context = '\0'; 03389 context++; 03390 } 03391 memset(&ied, 0, sizeof(ied)); 03392 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03393 if (context) 03394 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03395 if (option_debug) 03396 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03397 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03398 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2536 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_iax2_queue::count, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::prev, iax_frame::sentyet, and ast_iax2_queue::tail.
Referenced by iax2_send().
02537 { 02538 /* Lock the queue and place this packet at the end */ 02539 fr->next = NULL; 02540 fr->prev = NULL; 02541 /* By setting this to 0, the network thread will send it for us, and 02542 queue retransmission if necessary */ 02543 fr->sentyet = 0; 02544 ast_mutex_lock(&iaxq.lock); 02545 if (!iaxq.head) { 02546 /* Empty queue */ 02547 iaxq.head = fr; 02548 iaxq.tail = fr; 02549 } else { 02550 /* Double link */ 02551 iaxq.tail->next = fr; 02552 fr->prev = iaxq.tail; 02553 iaxq.tail = fr; 02554 } 02555 iaxq.count++; 02556 ast_mutex_unlock(&iaxq.lock); 02557 /* Wake up the network thread */ 02558 pthread_kill(netthreadid, SIGURG); 02559 return 0; 02560 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6064 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06065 { 06066 /* Drop when trunk is about 5 seconds idle */ 06067 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06068 return 1; 06069 return 0; 06070 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3750 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, realloc, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
03751 { 03752 struct ast_frame *f; 03753 struct iax2_trunk_peer *tpeer; 03754 void *tmp, *ptr; 03755 struct ast_iax2_meta_trunk_entry *met; 03756 struct ast_iax2_meta_trunk_mini *mtm; 03757 char iabuf[INET_ADDRSTRLEN]; 03758 03759 f = &fr->af; 03760 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03761 if (tpeer) { 03762 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03763 /* Need to reallocate space */ 03764 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03765 tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE); 03766 if (tmp) { 03767 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03768 tpeer->trunkdata = tmp; 03769 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); 03770 } else { 03771 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)); 03772 ast_mutex_unlock(&tpeer->lock); 03773 return -1; 03774 } 03775 } else { 03776 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)); 03777 ast_mutex_unlock(&tpeer->lock); 03778 return -1; 03779 } 03780 } 03781 03782 /* Append to meta frame */ 03783 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03784 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03785 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03786 mtm->len = htons(f->datalen); 03787 mtm->mini.callno = htons(pvt->callno); 03788 mtm->mini.ts = htons(0xffff & fr->ts); 03789 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03790 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03791 } else { 03792 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03793 /* Store call number and length in meta header */ 03794 met->callno = htons(pvt->callno); 03795 met->len = htons(f->datalen); 03796 /* Advance pointers/decrease length past trunk entry header */ 03797 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03798 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03799 } 03800 /* Copy actual trunk data */ 03801 memcpy(ptr, f->data, f->datalen); 03802 tpeer->trunkdatalen += f->datalen; 03803 03804 tpeer->calls++; 03805 ast_mutex_unlock(&tpeer->lock); 03806 } 03807 return 0; 03808 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 5992 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().
Referenced by socket_read().
05993 { 05994 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 05995 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4646 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04647 { 04648 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04649 int res = -1; 04650 ast_mutex_lock(&iaxsl[callno]); 04651 if (iaxs[callno]) { 04652 /* If there's an outstanding error, return failure now */ 04653 if (!iaxs[callno]->error) { 04654 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04655 res = 0; 04656 /* Don't waste bandwidth sending null frames */ 04657 else if (f->frametype == AST_FRAME_NULL) 04658 res = 0; 04659 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04660 res = 0; 04661 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04662 res = 0; 04663 else 04664 /* Simple, just queue for transmission */ 04665 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04666 } else { 04667 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04668 } 04669 } 04670 /* If it's already gone, just return */ 04671 ast_mutex_unlock(&iaxsl[callno]); 04672 return res; 04673 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1315 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by update_registry().
01316 { 01317 int res = 0; 01318 struct iax_firmware *cur; 01319 if (!ast_strlen_zero(dev)) { 01320 ast_mutex_lock(&waresl.lock); 01321 cur = waresl.wares; 01322 while(cur) { 01323 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01324 res = ntohs(cur->fwh->version); 01325 break; 01326 } 01327 cur = cur->next; 01328 } 01329 ast_mutex_unlock(&waresl.lock); 01330 } 01331 return res; 01332 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 675 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00676 { 00677 if (iaxdebug) 00678 ast_verbose("%s", data); 00679 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 681 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00682 { 00683 ast_log(LOG_WARNING, "%s", data); 00684 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1334 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.
Referenced by socket_read().
01335 { 01336 int res = -1; 01337 unsigned int bs = desc & 0xff; 01338 unsigned int start = (desc >> 8) & 0xffffff; 01339 unsigned int bytes; 01340 struct iax_firmware *cur; 01341 if (!ast_strlen_zero((char *)dev) && bs) { 01342 start *= bs; 01343 ast_mutex_lock(&waresl.lock); 01344 cur = waresl.wares; 01345 while(cur) { 01346 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01347 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01348 if (start < ntohl(cur->fwh->datalen)) { 01349 bytes = ntohl(cur->fwh->datalen) - start; 01350 if (bytes > bs) 01351 bytes = bs; 01352 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01353 } else { 01354 bytes = 0; 01355 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01356 } 01357 if (bytes == bs) 01358 res = 0; 01359 else 01360 res = 1; 01361 break; 01362 } 01363 cur = cur->next; 01364 } 01365 ast_mutex_unlock(&waresl.lock); 01366 } 01367 return res; 01368 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6243 of file chan_iax2.c.
References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_read().
06244 { 06245 struct iax_dual *d; 06246 struct ast_channel *chan1m, *chan2m; 06247 pthread_t th; 06248 chan1m = ast_channel_alloc(0); 06249 chan2m = ast_channel_alloc(0); 06250 if (chan2m && chan1m) { 06251 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 06252 /* Make formats okay */ 06253 chan1m->readformat = chan1->readformat; 06254 chan1m->writeformat = chan1->writeformat; 06255 ast_channel_masquerade(chan1m, chan1); 06256 /* Setup the extensions and such */ 06257 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06258 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06259 chan1m->priority = chan1->priority; 06260 06261 /* We make a clone of the peer channel too, so we can play 06262 back the announcement */ 06263 snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name); 06264 /* Make formats okay */ 06265 chan2m->readformat = chan2->readformat; 06266 chan2m->writeformat = chan2->writeformat; 06267 ast_channel_masquerade(chan2m, chan2); 06268 /* Setup the extensions and such */ 06269 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06270 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06271 chan2m->priority = chan2->priority; 06272 if (ast_do_masquerade(chan2m)) { 06273 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06274 ast_hangup(chan2m); 06275 return -1; 06276 } 06277 } else { 06278 if (chan1m) 06279 ast_hangup(chan1m); 06280 if (chan2m) 06281 ast_hangup(chan2m); 06282 return -1; 06283 } 06284 d = malloc(sizeof(struct iax_dual)); 06285 if (d) { 06286 memset(d, 0, sizeof(*d)); 06287 d->chan1 = chan1m; 06288 d->chan2 = chan2m; 06289 if (!ast_pthread_create(&th, NULL, iax_park_thread, d)) 06290 return 0; 06291 free(d); 06292 } 06293 return -1; 06294 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6223 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().
06224 { 06225 struct ast_channel *chan1, *chan2; 06226 struct iax_dual *d; 06227 struct ast_frame *f; 06228 int ext; 06229 int res; 06230 d = stuff; 06231 chan1 = d->chan1; 06232 chan2 = d->chan2; 06233 free(d); 06234 f = ast_read(chan1); 06235 if (f) 06236 ast_frfree(f); 06237 res = ast_park_call(chan1, chan2, 0, &ext); 06238 ast_hangup(chan2); 06239 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06240 return NULL; 06241 }
Definition at line 942 of file chan_iax2.c.
References iax_frame::af, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_read().
00943 { 00944 /* Malloc() a copy of a frame */ 00945 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen); 00946 if (new) { 00947 memcpy(new, fr, sizeof(struct iax_frame)); 00948 iax_frame_wrap(new, &fr->af); 00949 new->data = NULL; 00950 new->datalen = 0; 00951 new->direction = DIRECTION_INGRESS; 00952 new->retrans = -1; 00953 } 00954 return new; 00955 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 711 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00712 { 00713 va_list args; 00714 char buf[1024]; 00715 00716 va_start(args, fmt); 00717 vsnprintf(buf, 1024, fmt, args); 00718 va_end(args); 00719 00720 ast_verbose(buf); 00721 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 687 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00688 { 00689 va_list args; 00690 char buf[1024]; 00691 00692 va_start(args, fmt); 00693 vsnprintf(buf, 1024, fmt, args); 00694 va_end(args); 00695 00696 ast_log(LOG_ERROR, buf); 00697 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 699 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00700 { 00701 va_list args; 00702 char buf[1024]; 00703 00704 va_start(args, fmt); 00705 vsnprintf(buf, 1024, fmt, args); 00706 va_end(args); 00707 00708 ast_log(LOG_WARNING, buf); 00709 }
char* key | ( | void | ) |
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 9759 of file chan_iax2.c.
References ASTERISK_GPL_KEY.
09760 { 09761 return ASTERISK_GPL_KEY; 09762 }
int load_module | ( | void | ) |
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 9657 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_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), iax2_cli, iax2_do_register(), iax2_poke_peer(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, 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, registrations, reload_firmware(), sched, sched_context_create(), set_config(), iax2_peer::sockfd, start_network_thread(), userl, VERBOSE_PREFIX_2, and waresl.
09658 { 09659 char *config = "iax.conf"; 09660 int res = 0; 09661 int x; 09662 struct iax2_registry *reg; 09663 struct iax2_peer *peer; 09664 09665 ast_custom_function_register(&iaxpeer_function); 09666 09667 iax_set_output(iax_debug_output); 09668 iax_set_error(iax_error_output); 09669 #ifdef NEWJB 09670 jb_setoutput(jb_error_output, jb_warning_output, NULL); 09671 #endif 09672 09673 #ifdef IAX_TRUNKING 09674 #ifdef ZT_TIMERACK 09675 timingfd = open("/dev/zap/timer", O_RDWR); 09676 if (timingfd < 0) 09677 #endif 09678 timingfd = open("/dev/zap/pseudo", O_RDWR); 09679 if (timingfd < 0) 09680 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 09681 #endif 09682 09683 memset(iaxs, 0, sizeof(iaxs)); 09684 09685 for (x=0;x<IAX_MAX_CALLS;x++) 09686 ast_mutex_init(&iaxsl[x]); 09687 09688 io = io_context_create(); 09689 sched = sched_context_create(); 09690 09691 if (!io || !sched) { 09692 ast_log(LOG_ERROR, "Out of memory\n"); 09693 return -1; 09694 } 09695 09696 netsock = ast_netsock_list_alloc(); 09697 if (!netsock) { 09698 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 09699 return -1; 09700 } 09701 ast_netsock_init(netsock); 09702 09703 ast_mutex_init(&iaxq.lock); 09704 ast_mutex_init(&userl.lock); 09705 ast_mutex_init(&peerl.lock); 09706 ast_mutex_init(&waresl.lock); 09707 09708 ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0])); 09709 09710 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 09711 09712 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 09713 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 09714 09715 set_config(config, 0); 09716 09717 if (ast_channel_register(&iax2_tech)) { 09718 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype); 09719 __unload_module(); 09720 return -1; 09721 } 09722 09723 if (ast_register_switch(&iax2_switch)) 09724 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 09725 09726 res = start_network_thread(); 09727 if (!res) { 09728 if (option_verbose > 1) 09729 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 09730 } else { 09731 ast_log(LOG_ERROR, "Unable to start network thread\n"); 09732 ast_netsock_release(netsock); 09733 } 09734 09735 for (reg = registrations; reg; reg = reg->next) 09736 iax2_do_register(reg); 09737 ast_mutex_lock(&peerl.lock); 09738 for (peer = peerl.peers; peer; peer = peer->next) { 09739 if (peer->sockfd < 0) 09740 peer->sockfd = defaultsockfd; 09741 iax2_poke_peer(peer, 0); 09742 } 09743 ast_mutex_unlock(&peerl.lock); 09744 reload_firmware(); 09745 iax_provision_reload(); 09746 return res; 09747 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3182 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03183 { 03184 ast_mutex_lock(&iaxsl[callno0]); 03185 while (ast_mutex_trylock(&iaxsl[callno1])) { 03186 ast_mutex_unlock(&iaxsl[callno0]); 03187 usleep(10); 03188 ast_mutex_lock(&iaxsl[callno0]); 03189 } 03190 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1009 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, iaxs, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), and TRUNK_CALL_START.
Referenced by iax2_request(), and socket_read().
01010 { 01011 int x; 01012 int res= 0; 01013 struct timeval now; 01014 if (iaxs[callno]->oseqno) { 01015 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01016 return -1; 01017 } 01018 if (callno & TRUNK_CALL_START) { 01019 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01020 return -1; 01021 } 01022 gettimeofday(&now, NULL); 01023 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01024 ast_mutex_lock(&iaxsl[x]); 01025 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01026 iaxs[x] = iaxs[callno]; 01027 iaxs[x]->callno = x; 01028 iaxs[callno] = NULL; 01029 /* Update the two timers that should have been started */ 01030 if (iaxs[x]->pingid > -1) 01031 ast_sched_del(sched, iaxs[x]->pingid); 01032 if (iaxs[x]->lagid > -1) 01033 ast_sched_del(sched, iaxs[x]->lagid); 01034 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01035 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01036 if (locked) 01037 ast_mutex_unlock(&iaxsl[callno]); 01038 res = x; 01039 if (!locked) 01040 ast_mutex_unlock(&iaxsl[x]); 01041 break; 01042 } 01043 ast_mutex_unlock(&iaxsl[x]); 01044 } 01045 if (x >= IAX_MAX_CALLS - 1) { 01046 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01047 return -1; 01048 } 01049 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01050 /* We move this call from a non-trunked to a trunked call */ 01051 update_max_trunk(); 01052 update_max_nontrunk(); 01053 return res; 01054 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 4319 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SUCCESS, and s.
Referenced by load_module().
04320 { 04321 ast_cli_netstats(s->fd, 0); 04322 ast_cli(s->fd, "\r\n"); 04323 return RESULT_SUCCESS; 04324 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 4352 of file chan_iax2.c.
References __iax2_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), id, and s.
Referenced by load_module().
04353 { 04354 char *a[] = { "iax2", "show", "users" }; 04355 int ret; 04356 char *id; 04357 id = astman_get_header(m,"ActionID"); 04358 if (!ast_strlen_zero(id)) 04359 ast_cli(s->fd, "ActionID: %s\r\n",id); 04360 ret = __iax2_show_peers(1, s->fd, 3, a ); 04361 ast_cli(s->fd, "\r\n\r\n" ); 04362 return ret; 04363 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur | |||
) | [static] |
Definition at line 961 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and chan_iax2_pvt::transferring.
Referenced by ast_extension_close(), ast_extension_match(), ast_parse_device_state(), complete_show_channels(), find_callno(), find_cli(), find_command(), key_matches(), pbx_find_extension(), realtime_switch_common(), schedule_delivery(), and softhangup_exec().
00962 { 00963 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 00964 (cur->addr.sin_port == sin->sin_port)) { 00965 /* This is the main host */ 00966 if ((cur->peercallno == callno) || 00967 ((dcallno == cur->callno) && !cur->peercallno)) { 00968 /* That's us. Be sure we keep track of the peer call number */ 00969 return 1; 00970 } 00971 } 00972 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 00973 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 00974 /* We're transferring */ 00975 if (dcallno == cur->callno) 00976 return 1; 00977 } 00978 return 0; 00979 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3816 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03817 { 03818 #if 0 03819 /* Debug with "fake encryption" */ 03820 int x; 03821 if (len % 16) 03822 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03823 for (x=0;x<len;x++) 03824 dst[x] = src[x] ^ 0xff; 03825 #else 03826 unsigned char lastblock[16] = { 0 }; 03827 int x; 03828 while(len > 0) { 03829 aes_decrypt(src, dst, dcx); 03830 for (x=0;x<16;x++) 03831 dst[x] ^= lastblock[x]; 03832 memcpy(lastblock, src, sizeof(lastblock)); 03833 dst += 16; 03834 src += 16; 03835 len -= 16; 03836 } 03837 #endif 03838 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3840 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03841 { 03842 #if 0 03843 /* Debug with "fake encryption" */ 03844 int x; 03845 if (len % 16) 03846 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03847 for (x=0;x<len;x++) 03848 dst[x] = src[x] ^ 0xff; 03849 #else 03850 unsigned char curblock[16] = { 0 }; 03851 int x; 03852 while(len > 0) { 03853 for (x=0;x<16;x++) 03854 curblock[x] ^= src[x]; 03855 aes_encrypt(curblock, dst, ecx); 03856 memcpy(curblock, dst, sizeof(curblock)); 03857 dst += 16; 03858 src += 16; 03859 len -= 16; 03860 } 03861 #endif 03862 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 4958 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_read().
04959 { 04960 /* Select exactly one common encryption if there are any */ 04961 p->encmethods &= enc; 04962 if (p->encmethods) { 04963 if (p->encmethods & IAX_ENCRYPT_AES128) 04964 p->encmethods = IAX_ENCRYPT_AES128; 04965 else 04966 p->encmethods = 0; 04967 } 04968 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8037 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_mutex_lock(), ast_iax2_queue::count, ast_iax2_queue::head, iaxq, io, ast_iax2_queue::lock, iax_frame::next, iax_frame::prev, iax_frame::retries, send_packet(), iax_frame::sentyet, ast_iax2_queue::tail, and timing_read().
Referenced by start_network_thread().
08038 { 08039 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08040 from the network, and queue them for delivery to the channels */ 08041 int res, count; 08042 struct iax_frame *f, *freeme; 08043 if (timingfd > -1) 08044 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08045 for(;;) { 08046 /* Go through the queue, sending messages which have not yet been 08047 sent, and scheduling retransmissions if appropriate */ 08048 ast_mutex_lock(&iaxq.lock); 08049 f = iaxq.head; 08050 count = 0; 08051 while(f) { 08052 freeme = NULL; 08053 if (!f->sentyet) { 08054 f->sentyet++; 08055 /* Send a copy immediately -- errors here are ok, so don't bother locking */ 08056 if (iaxs[f->callno]) { 08057 send_packet(f); 08058 count++; 08059 } 08060 if (f->retries < 0) { 08061 /* This is not supposed to be retransmitted */ 08062 if (f->prev) 08063 f->prev->next = f->next; 08064 else 08065 iaxq.head = f->next; 08066 if (f->next) 08067 f->next->prev = f->prev; 08068 else 08069 iaxq.tail = f->prev; 08070 iaxq.count--; 08071 /* Free the iax frame */ 08072 freeme = f; 08073 } else { 08074 /* We need reliable delivery. Schedule a retransmission */ 08075 f->retries++; 08076 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 08077 } 08078 } 08079 f = f->next; 08080 if (freeme) 08081 iax_frame_free(freeme); 08082 } 08083 ast_mutex_unlock(&iaxq.lock); 08084 if (count >= 20) 08085 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08086 08087 /* Now do the IO, and run scheduled tasks */ 08088 res = ast_sched_wait(sched); 08089 if ((res > 1000) || (res < 0)) 08090 res = 1000; 08091 res = ast_io_wait(io, res); 08092 if (res >= 0) { 08093 if (res >= 20) 08094 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08095 count = ast_sched_runq(sched); 08096 if (count >= 20) 08097 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08098 } 08099 } 08100 return NULL; 08101 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
int | lockpeer, | |||
const char * | host | |||
) | [static] |
Definition at line 907 of file chan_iax2.c.
References jb_new(), jb_setconf(), malloc, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, and jb_conf::resync_threshold.
Referenced by find_callno().
00908 { 00909 struct chan_iax2_pvt *tmp; 00910 tmp = malloc(sizeof(struct chan_iax2_pvt)); 00911 if (tmp) { 00912 memset(tmp, 0, sizeof(struct chan_iax2_pvt)); 00913 tmp->prefs = prefs; 00914 tmp->callno = 0; 00915 tmp->peercallno = 0; 00916 tmp->transfercallno = 0; 00917 tmp->bridgecallno = 0; 00918 tmp->pingid = -1; 00919 tmp->lagid = -1; 00920 tmp->autoid = -1; 00921 tmp->authid = -1; 00922 tmp->initid = -1; 00923 /* ast_copy_string(tmp->context, context, sizeof(tmp->context)); */ 00924 ast_copy_string(tmp->exten, "s", sizeof(tmp->exten)); 00925 ast_copy_string(tmp->host, host, sizeof(tmp->host)); 00926 #ifdef NEWJB 00927 { 00928 jb_conf jbconf; 00929 00930 tmp->jb = jb_new(); 00931 tmp->jbid = -1; 00932 jbconf.max_jitterbuf = maxjitterbuffer; 00933 jbconf.resync_threshold = resyncthreshold; 00934 jbconf.max_contig_interp = maxjitterinterps; 00935 jb_setconf(tmp->jb,&jbconf); 00936 } 00937 #endif 00938 } 00939 return tmp; 00940 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 2920 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
02921 { 02922 if (ast_strlen_zero(data)) 02923 return; 02924 02925 pds->peer = strsep(&data, "/"); 02926 pds->exten = strsep(&data, "/"); 02927 pds->options = data; 02928 02929 if (pds->exten) { 02930 data = pds->exten; 02931 pds->exten = strsep(&data, "@"); 02932 pds->context = data; 02933 } 02934 02935 if (strchr(pds->peer, '@')) { 02936 data = pds->peer; 02937 pds->username = strsep(&data, "@"); 02938 pds->peer = data; 02939 } 02940 02941 if (pds->username) { 02942 data = pds->username; 02943 pds->username = strsep(&data, ":"); 02944 pds->password = data; 02945 } 02946 02947 data = pds->peer; 02948 pds->peer = strsep(&data, ":"); 02949 pds->port = data; 02950 02951 /* check for a key name wrapped in [] in the secret position, if found, 02952 move it to the key field instead 02953 */ 02954 if (pds->password && (pds->password[0] == '[')) { 02955 pds->key = ast_strip_quoted(pds->password, "[", "]"); 02956 pds->password = NULL; 02957 } 02958 }
static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
const char * | srcaddr | |||
) | [static] |
Definition at line 8162 of file chan_iax2.c.
References ast_get_ip(), ast_log(), ast_netsock_find(), ast_netsock_sockfd(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, netsock, iax2_peer::sockfd, and strsep().
Referenced by build_peer().
08163 { 08164 struct sockaddr_in sin; 08165 int nonlocal = 1; 08166 int port = IAX_DEFAULT_PORTNO; 08167 int sockfd = defaultsockfd; 08168 char *tmp; 08169 char *addr; 08170 char *portstr; 08171 08172 tmp = ast_strdupa(srcaddr); 08173 if (!tmp) { 08174 ast_log(LOG_WARNING, "Out of memory!\n"); 08175 return -1; 08176 } 08177 08178 addr = strsep(&tmp, ":"); 08179 portstr = tmp; 08180 08181 if (portstr) { 08182 port = atoi(portstr); 08183 if (port < 1) 08184 port = IAX_DEFAULT_PORTNO; 08185 } 08186 08187 if (!ast_get_ip(&sin, addr)) { 08188 struct ast_netsock *sock; 08189 int res; 08190 08191 sin.sin_port = 0; 08192 sin.sin_family = AF_INET; 08193 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08194 if (res == 0) { 08195 /* ip address valid. */ 08196 sin.sin_port = htons(port); 08197 sock = ast_netsock_find(netsock, &sin); 08198 if (sock) { 08199 sockfd = ast_netsock_sockfd(sock); 08200 nonlocal = 0; 08201 } 08202 } 08203 } 08204 08205 peer->sockfd = sockfd; 08206 08207 if (nonlocal) { 08208 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08209 srcaddr, peer->name); 08210 return -1; 08211 } else { 08212 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08213 return 0; 08214 } 08215 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 1932 of file chan_iax2.c.
References iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer().
01933 { 01934 int res = 0; 01935 if (peer->maxms) { 01936 if (peer->lastms < 0) { 01937 ast_copy_string(status, "UNREACHABLE", statuslen); 01938 } else if (peer->lastms > peer->maxms) { 01939 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 01940 res = 1; 01941 } else if (peer->lastms) { 01942 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 01943 res = 1; 01944 } else { 01945 ast_copy_string(status, "UNKNOWN", statuslen); 01946 } 01947 } else { 01948 ast_copy_string(status, "Unmonitored", statuslen); 01949 res = -1; 01950 } 01951 return res; 01952 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 2186 of file chan_h323.c.
References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers.
Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module().
02187 { 02188 /* Prune peers who still are supposed to be deleted */ 02189 struct oh323_peer *peer, *peerlast, *peernext; 02190 ast_mutex_lock(&peerl.lock); 02191 peerlast = NULL; 02192 for (peer=peerl.peers;peer;) { 02193 peernext = peer->next; 02194 if (peer->delme) { 02195 free(peer); 02196 if (peerlast) { 02197 peerlast->next = peernext; 02198 } else { 02199 peerl.peers = peernext; 02200 } 02201 } else { 02202 peerlast = peer; 02203 } 02204 peer = peernext; 02205 } 02206 ast_mutex_unlock(&peerl.lock); 02207 }
static void prune_users | ( | void | ) | [static] |
Definition at line 8618 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_user(), IAX_DELME, ast_user_list::lock, iax2_user::next, user, userl, and ast_user_list::users.
08619 { 08620 struct iax2_user *user, *usernext, *userlast = NULL; 08621 ast_mutex_lock(&userl.lock); 08622 for (user=userl.users;user;) { 08623 usernext = user->next; 08624 if (ast_test_flag(user, IAX_DELME)) { 08625 destroy_user(user); 08626 if (userlast) 08627 userlast->next = usernext; 08628 else 08629 userl.users = usernext; 08630 } else 08631 userlast = user; 08632 user = usernext; 08633 } 08634 ast_mutex_unlock(&userl.lock); 08635 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 4937 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_read().
04938 { 04939 struct ast_iax2_full_hdr fh; 04940 char iabuf[INET_ADDRSTRLEN]; 04941 fh.scallno = htons(src | IAX_FLAG_FULL); 04942 fh.dcallno = htons(dst); 04943 fh.ts = 0; 04944 fh.oseqno = 0; 04945 fh.iseqno = 0; 04946 fh.type = AST_FRAME_IAX; 04947 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 04948 if (iaxdebug) 04949 iax_showframe(NULL, &fh, 0, sin, 0); 04950 #if 0 04951 if (option_debug) 04952 #endif 04953 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 04954 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst); 04955 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 04956 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2604 of file chan_iax2.c.
References iax2_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), destroy_peer(), expire_registry(), global_rtautoclear, globalflags, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, ast_variable::name, ast_variable::next, option_debug, peerl, ast_peer_list::peers, reg_source_db(), sched, ast_variable::value, and var.
Referenced by authenticate_reply(), find_peer(), and iax2_getpeername().
02605 { 02606 struct ast_variable *var; 02607 struct ast_variable *tmp; 02608 struct iax2_peer *peer=NULL; 02609 time_t regseconds, nowtime; 02610 int dynamic=0; 02611 02612 if (peername) 02613 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02614 else { 02615 char iabuf[INET_ADDRSTRLEN]; 02616 char porta[25]; 02617 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 02618 sprintf(porta, "%d", ntohs(sin->sin_port)); 02619 var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL); 02620 if (var) { 02621 /* We'll need the peer name in order to build the structure! */ 02622 tmp = var; 02623 while(tmp) { 02624 if (!strcasecmp(tmp->name, "name")) 02625 peername = tmp->value; 02626 tmp = tmp->next; 02627 } 02628 } 02629 } 02630 if (!var) 02631 return NULL; 02632 02633 peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02634 02635 if (!peer) 02636 return NULL; 02637 02638 tmp = var; 02639 while(tmp) { 02640 /* Make sure it's not a user only... */ 02641 if (!strcasecmp(tmp->name, "type")) { 02642 if (strcasecmp(tmp->value, "friend") && 02643 strcasecmp(tmp->value, "peer")) { 02644 /* Whoops, we weren't supposed to exist! */ 02645 destroy_peer(peer); 02646 peer = NULL; 02647 break; 02648 } 02649 } else if (!strcasecmp(tmp->name, "regseconds")) { 02650 if (sscanf(tmp->value, "%ld", (time_t *)®seconds) != 1) 02651 regseconds = 0; 02652 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02653 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02654 } else if (!strcasecmp(tmp->name, "port")) { 02655 peer->addr.sin_port = htons(atoi(tmp->value)); 02656 } else if (!strcasecmp(tmp->name, "host")) { 02657 if (!strcasecmp(tmp->value, "dynamic")) 02658 dynamic = 1; 02659 } 02660 tmp = tmp->next; 02661 } 02662 if (!peer) 02663 return NULL; 02664 02665 ast_variables_destroy(var); 02666 02667 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02668 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02669 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02670 if (peer->expire > -1) 02671 ast_sched_del(sched, peer->expire); 02672 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer); 02673 } 02674 ast_mutex_lock(&peerl.lock); 02675 peer->next = peerl.peers; 02676 peerl.peers = peer; 02677 ast_mutex_unlock(&peerl.lock); 02678 if (ast_test_flag(peer, IAX_DYNAMIC)) 02679 reg_source_db(peer); 02680 } else { 02681 ast_set_flag(peer, IAX_TEMPONLY); 02682 } 02683 02684 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02685 time(&nowtime); 02686 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02687 memset(&peer->addr, 0, sizeof(peer->addr)); 02688 if (option_debug) 02689 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02690 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02691 } 02692 else { 02693 if (option_debug) 02694 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02695 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02696 } 02697 } 02698 02699 return peer; 02700 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2743 of file chan_iax2.c.
References ast_inet_ntoa(), ast_update_realtime(), and ipaddr.
Referenced by expire_registry(), update_peer(), and update_registry().
02744 { 02745 char port[10]; 02746 char ipaddr[20]; 02747 char regseconds[20]; 02748 02749 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02750 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 02751 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02752 ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL); 02753 }
static struct iax2_user* realtime_user | ( | const char * | username | ) | [static] |
Definition at line 2702 of file chan_iax2.c.
References ast_load_realtime(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), globalflags, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_user_list::lock, ast_variable::name, ast_variable::next, user, userl, ast_user_list::users, ast_variable::value, and var.
Referenced by check_access(), and find_user().
02703 { 02704 struct ast_variable *var; 02705 struct ast_variable *tmp; 02706 struct iax2_user *user=NULL; 02707 02708 var = ast_load_realtime("iaxusers", "name", username, NULL); 02709 if (!var) 02710 return NULL; 02711 02712 tmp = var; 02713 while(tmp) { 02714 /* Make sure it's not a peer only... */ 02715 if (!strcasecmp(tmp->name, "type")) { 02716 if (strcasecmp(tmp->value, "friend") && 02717 strcasecmp(tmp->value, "user")) { 02718 return NULL; 02719 } 02720 } 02721 tmp = tmp->next; 02722 } 02723 02724 user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02725 if (!user) 02726 return NULL; 02727 02728 ast_variables_destroy(var); 02729 02730 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02731 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02732 ast_mutex_lock(&userl.lock); 02733 user->next = userl.users; 02734 userl.users = user; 02735 ast_mutex_unlock(&userl.lock); 02736 } else { 02737 ast_set_flag(user, IAX_TEMPONLY); 02738 } 02739 02740 return user; 02741 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5681 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.
Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().
05682 { 05683 char data[80]; 05684 struct in_addr in; 05685 char iabuf[INET_ADDRSTRLEN]; 05686 char *c, *d; 05687 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05688 c = strchr(data, ':'); 05689 if (c) { 05690 *c = '\0'; 05691 c++; 05692 if (inet_aton(data, &in)) { 05693 d = strchr(c, ':'); 05694 if (d) { 05695 *d = '\0'; 05696 d++; 05697 if (option_verbose > 2) 05698 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05699 ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); 05700 iax2_poke_peer(p, 0); 05701 p->expiry = atoi(d); 05702 memset(&p->addr, 0, sizeof(p->addr)); 05703 p->addr.sin_family = AF_INET; 05704 p->addr.sin_addr = in; 05705 p->addr.sin_port = htons(atoi(c)); 05706 if (p->expire > -1) 05707 ast_sched_del(sched, p->expire); 05708 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05709 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05710 if (iax2_regfunk) 05711 iax2_regfunk(p->name, 1); 05712 register_peer_exten(p, 1); 05713 } 05714 05715 } 05716 } 05717 } 05718 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5632 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_strlen_zero(), FREE, iax2_peer::name, iax2_peer::regexten, strdup, and strsep().
Referenced by destroy_peer(), expire_register(), expire_registry(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry().
05633 { 05634 char multi[256]; 05635 char *stringp, *ext; 05636 if (!ast_strlen_zero(regcontext)) { 05637 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 05638 stringp = multi; 05639 while((ext = strsep(&stringp, "&"))) { 05640 if (onoff) { 05641 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05642 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype); 05643 } else 05644 ast_context_remove_extension(regcontext, ext, 1, NULL); 05645 } 05646 } 05647 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5098 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(), expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxsl, ies, iax2_peer::inkeys, key(), LOG_NOTICE, LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax2_peer::secret, secret, and strsep().
Referenced by handle_request_register(), and socket_read().
05099 { 05100 char requeststr[256] = ""; 05101 char peer[256] = ""; 05102 char md5secret[256] = ""; 05103 char rsasecret[256] = ""; 05104 char secret[256] = ""; 05105 char iabuf[INET_ADDRSTRLEN]; 05106 struct iax2_peer *p; 05107 struct ast_key *key; 05108 char *keyn; 05109 int x; 05110 int expire = 0; 05111 05112 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05113 iaxs[callno]->peer[0] = '\0'; 05114 if (ies->username) 05115 ast_copy_string(peer, ies->username, sizeof(peer)); 05116 if (ies->password) 05117 ast_copy_string(secret, ies->password, sizeof(secret)); 05118 if (ies->md5_result) 05119 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05120 if (ies->rsa_result) 05121 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05122 if (ies->refresh) 05123 expire = ies->refresh; 05124 05125 if (ast_strlen_zero(peer)) { 05126 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05127 return -1; 05128 } 05129 /* We release the lock for the call to prevent a deadlock, but it's okay because 05130 only the current thread could possibly make it go away or make changes */ 05131 ast_mutex_unlock(&iaxsl[callno]); 05132 /* SLD: first call to lookup peer during registration */ 05133 p = find_peer(peer, 1); 05134 ast_mutex_lock(&iaxsl[callno]); 05135 05136 if (!p) { 05137 if (authdebug) 05138 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05139 return -1; 05140 } 05141 05142 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05143 if (authdebug) 05144 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05145 if (ast_test_flag(p, IAX_TEMPONLY)) 05146 destroy_peer(p); 05147 return -1; 05148 } 05149 05150 if (!ast_apply_ha(p->ha, sin)) { 05151 if (authdebug) 05152 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); 05153 if (ast_test_flag(p, IAX_TEMPONLY)) 05154 destroy_peer(p); 05155 return -1; 05156 } 05157 ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret)); 05158 ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys)); 05159 /* Check secret against what we have on file */ 05160 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05161 if (!ast_strlen_zero(p->inkeys)) { 05162 char tmpkeys[256]; 05163 char *stringp=NULL; 05164 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05165 stringp=tmpkeys; 05166 keyn = strsep(&stringp, ":"); 05167 while(keyn) { 05168 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05169 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05170 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05171 break; 05172 } else if (!key) 05173 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05174 keyn = strsep(&stringp, ":"); 05175 } 05176 if (!keyn) { 05177 if (authdebug) 05178 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05179 if (ast_test_flag(p, IAX_TEMPONLY)) 05180 destroy_peer(p); 05181 return -1; 05182 } 05183 } else { 05184 if (authdebug) 05185 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05186 if (ast_test_flag(p, IAX_TEMPONLY)) 05187 destroy_peer(p); 05188 return -1; 05189 } 05190 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05191 /* They've provided a plain text password and we support that */ 05192 if (strcmp(secret, p->secret)) { 05193 if (authdebug) 05194 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); 05195 if (ast_test_flag(p, IAX_TEMPONLY)) 05196 destroy_peer(p); 05197 return -1; 05198 } else 05199 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05200 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05201 struct MD5Context md5; 05202 unsigned char digest[16]; 05203 char *tmppw, *stringp; 05204 05205 tmppw = ast_strdupa(p->secret); 05206 stringp = tmppw; 05207 while((tmppw = strsep(&stringp, ";"))) { 05208 MD5Init(&md5); 05209 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05210 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05211 MD5Final(digest, &md5); 05212 for (x=0;x<16;x++) 05213 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05214 if (!strcasecmp(requeststr, md5secret)) 05215 break; 05216 } 05217 if (tmppw) { 05218 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05219 } else { 05220 if (authdebug) 05221 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); 05222 if (ast_test_flag(p, IAX_TEMPONLY)) 05223 destroy_peer(p); 05224 return -1; 05225 } 05226 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05227 if (authdebug) 05228 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05229 if (ast_test_flag(p, IAX_TEMPONLY)) 05230 destroy_peer(p); 05231 return -1; 05232 } 05233 ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer)); 05234 /* Choose lowest expiry number */ 05235 if (expire && (expire < iaxs[callno]->expiry)) 05236 iaxs[callno]->expiry = expire; 05237 05238 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05239 05240 if (ast_test_flag(p, IAX_TEMPONLY)) 05241 destroy_peer(p); 05242 return 0; 05243 05244 }
static int registry_authrequest | ( | char * | name, | |
int | callno | |||
) | [static] |
Definition at line 5828 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, IAX_TEMPONLY, LOG_WARNING, and send_command().
Referenced by socket_read().
05829 { 05830 struct iax_ie_data ied; 05831 struct iax2_peer *p; 05832 /* SLD: third call to find_peer in registration */ 05833 p = find_peer(name, 1); 05834 if (p) { 05835 memset(&ied, 0, sizeof(ied)); 05836 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05837 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 05838 /* Build the challenge */ 05839 snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand()); 05840 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 05841 } 05842 iax_ie_append_str(&ied, IAX_IE_USERNAME, name); 05843 if (ast_test_flag(p, IAX_TEMPONLY)) 05844 destroy_peer(p); 05845 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 05846 } 05847 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05848 return 0; 05849 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 5851 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_read().
05852 { 05853 struct iax2_registry *reg; 05854 /* Start pessimistic */ 05855 struct iax_ie_data ied; 05856 char peer[256] = ""; 05857 char iabuf[INET_ADDRSTRLEN]; 05858 char challenge[256] = ""; 05859 int res; 05860 int authmethods = 0; 05861 if (ies->authmethods) 05862 authmethods = ies->authmethods; 05863 if (ies->username) 05864 ast_copy_string(peer, ies->username, sizeof(peer)); 05865 if (ies->challenge) 05866 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 05867 memset(&ied, 0, sizeof(ied)); 05868 reg = iaxs[callno]->reg; 05869 if (reg) { 05870 if (inaddrcmp(®->addr, sin)) { 05871 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 05872 return -1; 05873 } 05874 if (ast_strlen_zero(reg->secret)) { 05875 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 05876 reg->regstate = REG_STATE_NOAUTH; 05877 return -1; 05878 } 05879 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 05880 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 05881 if (reg->secret[0] == '[') { 05882 char tmpkey[256]; 05883 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 05884 tmpkey[strlen(tmpkey) - 1] = '\0'; 05885 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 05886 } else 05887 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 05888 if (!res) { 05889 reg->regstate = REG_STATE_AUTHSENT; 05890 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 05891 } else 05892 return -1; 05893 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 05894 } else 05895 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 05896 return -1; 05897 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4365 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
04366 { 04367 switch(regstate) { 04368 case REG_STATE_UNREGISTERED: 04369 return "Unregistered"; 04370 case REG_STATE_REGSENT: 04371 return "Request Sent"; 04372 case REG_STATE_AUTHSENT: 04373 return "Auth. Sent"; 04374 case REG_STATE_REGISTERED: 04375 return "Registered"; 04376 case REG_STATE_REJECTED: 04377 return "Rejected"; 04378 case REG_STATE_TIMEOUT: 04379 return "Timeout"; 04380 case REG_STATE_NOAUTH: 04381 return "No Authentication"; 04382 default: 04383 return "Unknown"; 04384 } 04385 }
int reload | ( | void | ) |
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 8991 of file chan_iax2.c.
References reload_config().
08992 { 08993 return reload_config(); 08994 }
static int reload_config | ( | void | ) | [static] |
Definition at line 1995 of file chan_h323.c.
References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_alias(), build_peer(), build_user(), cfg, format, free_robin_list(), global_tracefile, hp, IPTOS_MINCOST, ast_variable::lineno, ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.
01996 { 01997 int format; 01998 struct ast_config *cfg; 01999 struct ast_variable *v; 02000 struct oh323_peer *peer = NULL; 02001 struct oh323_user *user = NULL; 02002 struct oh323_alias *alias = NULL; 02003 struct ast_hostent ahp; struct hostent *hp; 02004 char *cat; 02005 char *utype; 02006 02007 cfg = ast_config_load(config); 02008 02009 /* We *must* have a config file otherwise stop immediately */ 02010 if (!cfg) { 02011 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02012 return 1; 02013 } 02014 02015 /* fire up the H.323 Endpoint */ 02016 if (!h323_end_point_exist()) { 02017 h323_end_point_create(); 02018 } 02019 h323debug = 0; 02020 memset(&bindaddr, 0, sizeof(bindaddr)); 02021 memset(&global_options, 0, sizeof(global_options)); 02022 global_options.dtmfcodec = 101; 02023 global_options.dtmfmode = H323_DTMF_RFC2833; 02024 global_options.capability = ~0; /* All capabilities */ 02025 global_options.bridge = 1; /* Do native bridging by default */ 02026 v = ast_variable_browse(cfg, "general"); 02027 while(v) { 02028 /* Create the interface list */ 02029 if (!strcasecmp(v->name, "port")) { 02030 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02031 } else if (!strcasecmp(v->name, "bindaddr")) { 02032 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02033 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02034 } else { 02035 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02036 } 02037 } else if (!strcasecmp(v->name, "tos")) { 02038 if (sscanf(v->value, "%d", &format)) { 02039 tos = format & 0xff; 02040 } else if (!strcasecmp(v->value, "lowdelay")) { 02041 tos = IPTOS_LOWDELAY; 02042 } else if (!strcasecmp(v->value, "throughput")) { 02043 tos = IPTOS_THROUGHPUT; 02044 } else if (!strcasecmp(v->value, "reliability")) { 02045 tos = IPTOS_RELIABILITY; 02046 } else if (!strcasecmp(v->value, "mincost")) { 02047 tos = IPTOS_MINCOST; 02048 } else if (!strcasecmp(v->value, "none")) { 02049 tos = 0; 02050 } else { 02051 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02052 } 02053 } else if (!strcasecmp(v->name, "gatekeeper")) { 02054 if (!strcasecmp(v->value, "DISABLE")) { 02055 gatekeeper_disable = 1; 02056 usingGk = 0; 02057 } else if (!strcasecmp(v->value, "DISCOVER")) { 02058 gatekeeper_disable = 0; 02059 gatekeeper_discover = 1; 02060 usingGk = 1; 02061 } else { 02062 gatekeeper_disable = 0; 02063 usingGk = 1; 02064 strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1); 02065 } 02066 } else if (!strcasecmp(v->name, "secret")) { 02067 strncpy(secret, v->value, sizeof(secret) - 1); 02068 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02069 gkroute = ast_true(v->value); 02070 } else if (!strcasecmp(v->name, "context")) { 02071 strncpy(default_context, v->value, sizeof(default_context) - 1); 02072 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02073 } else if (!strcasecmp(v->name, "UserByAlias")) { 02074 userbyalias = ast_true(v->value); 02075 } else if (!update_common_options(v, &global_options)) { 02076 /* dummy */ 02077 } 02078 v = v->next; 02079 } 02080 02081 cat = ast_category_browse(cfg, NULL); 02082 while(cat) { 02083 if (strcasecmp(cat, "general")) { 02084 utype = ast_variable_retrieve(cfg, cat, "type"); 02085 if (utype) { 02086 if (!strcasecmp(utype, "user")) { 02087 user = build_user(cat, ast_variable_browse(cfg, cat)); 02088 if (user) { 02089 ast_mutex_lock(&userl.lock); 02090 user->next = userl.users; 02091 userl.users = user; 02092 ast_mutex_unlock(&userl.lock); 02093 } 02094 } else if (!strcasecmp(utype, "peer")) { 02095 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02096 if (peer) { 02097 ast_mutex_lock(&peerl.lock); 02098 peer->next = peerl.peers; 02099 peerl.peers = peer; 02100 ast_mutex_unlock(&peerl.lock); 02101 } 02102 } else if (!strcasecmp(utype, "friend")) { 02103 user = build_user(cat, ast_variable_browse(cfg, cat)); 02104 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02105 if (user) { 02106 ast_mutex_lock(&userl.lock); 02107 user->next = userl.users; 02108 userl.users = user; 02109 ast_mutex_unlock(&userl.lock); 02110 } 02111 if (peer) { 02112 ast_mutex_lock(&peerl.lock); 02113 peer->next = peerl.peers; 02114 peerl.peers = peer; 02115 ast_mutex_unlock(&peerl.lock); 02116 } 02117 } else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) { 02118 alias = build_alias(cat, ast_variable_browse(cfg, cat)); 02119 if (alias) { 02120 ast_mutex_lock(&aliasl.lock); 02121 alias->next = aliasl.aliases; 02122 aliasl.aliases = alias; 02123 ast_mutex_unlock(&aliasl.lock); 02124 } 02125 } else { 02126 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02127 } 02128 } else { 02129 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02130 } 02131 } 02132 cat = ast_category_browse(cfg, cat); 02133 } 02134 ast_config_destroy(cfg); 02135 02136 /* Register our H.323 aliases if any*/ 02137 while (alias) { 02138 if (h323_set_alias(alias)) { 02139 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02140 return -1; 02141 } 02142 alias = alias->next; 02143 } 02144 02145 return 0; 02146 }
static void reload_firmware | ( | void | ) | [static] |
Definition at line 1371 of file chan_iax2.c.
References ast_config_AST_VAR_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by load_module().
01372 { 01373 struct iax_firmware *cur, *curl, *curp; 01374 DIR *fwd; 01375 struct dirent *de; 01376 char dir[256]; 01377 char fn[256]; 01378 /* Mark all as dead */ 01379 ast_mutex_lock(&waresl.lock); 01380 cur = waresl.wares; 01381 while(cur) { 01382 cur->dead = 1; 01383 cur = cur->next; 01384 } 01385 /* Now that we've freed them, load the new ones */ 01386 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_VAR_DIR); 01387 fwd = opendir(dir); 01388 if (fwd) { 01389 while((de = readdir(fwd))) { 01390 if (de->d_name[0] != '.') { 01391 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01392 if (!try_firmware(fn)) { 01393 if (option_verbose > 1) 01394 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01395 } 01396 } 01397 } 01398 closedir(fwd); 01399 } else 01400 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01401 01402 /* Clean up leftovers */ 01403 cur = waresl.wares; 01404 curp = NULL; 01405 while(cur) { 01406 curl = cur; 01407 cur = cur->next; 01408 if (curl->dead) { 01409 if (curp) { 01410 curp->next = cur; 01411 } else { 01412 waresl.wares = cur; 01413 } 01414 destroy_firmware(curl); 01415 } else { 01416 curp = cur; 01417 } 01418 } 01419 ast_mutex_unlock(&waresl.lock); 01420 }
Definition at line 6342 of file chan_iax2.c.
References iax_frame::callno, and ies.
Referenced by socket_read().
06343 { 06344 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06345 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06346 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06347 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06348 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06349 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06350 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06351 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
Definition at line 2277 of file chan_iax2.c.
References iax_frame::af, ast_log(), ast_tvadd(), calc_rxstamp(), iax_frame::callno, ast_frame::delivery, iaxs, chan_iax2_pvt::last, match(), MEMORY_SIZE, option_debug, chan_iax2_pvt::rxcore, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, and unwrap_timestamp().
Referenced by socket_read().
02278 { 02279 #ifdef NEWJB 02280 int type, len; 02281 int ret; 02282 int needfree = 0; 02283 #else 02284 int x; 02285 int ms; 02286 int delay; 02287 unsigned int orig_ts; 02288 int drops[MEMORY_SIZE]; 02289 int min, max=0, prevjitterbuffer, maxone=0,y,z, match; 02290 02291 /* Remember current jitterbuffer so we can log any change */ 02292 prevjitterbuffer = iaxs[fr->callno]->jitterbuffer; 02293 /* Similarly for the frame timestamp */ 02294 orig_ts = fr->ts; 02295 #endif 02296 02297 #if 0 02298 if (option_debug && iaxdebug) 02299 ast_log(LOG_DEBUG, "schedule_delivery: ts=%d, last=%d, update=%d\n", 02300 fr->ts, iaxs[fr->callno]->last, updatehistory); 02301 #endif 02302 02303 /* Attempt to recover wrapped timestamps */ 02304 unwrap_timestamp(fr); 02305 02306 if (updatehistory) { 02307 #ifndef NEWJB 02308 02309 /* Attempt to spot a change of timebase on timestamps coming from the other side 02310 We detect by noticing a jump in consecutive timestamps that can't reasonably be explained 02311 by network jitter or reordering. Sometimes, also, the peer stops sending us frames 02312 for a while - in this case this code might also resync us. But that's not a bad thing. 02313 Be careful of non-voice frames which are timestamped differently (especially ACKS!) 02314 [that's why we only do this when updatehistory is true] 02315 */ 02316 x = fr->ts - iaxs[fr->callno]->last; 02317 if (x > TS_GAP_FOR_JB_RESYNC || x < -TS_GAP_FOR_JB_RESYNC) { 02318 if (option_debug && iaxdebug) 02319 ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped. resyncing rxcore (ts=%d, last=%d)\n", 02320 fr->callno, fr->ts, iaxs[fr->callno]->last); 02321 /* zap rxcore - calc_rxstamp will make a new one based on this frame */ 02322 iaxs[fr->callno]->rxcore = ast_tv(0, 0); 02323 /* wipe "last" if stamps have jumped backwards */ 02324 if (x<0) 02325 iaxs[fr->callno]->last = 0; 02326 /* should we also empty history? */ 02327 } 02328 /* ms is a measure of the "lateness" of the frame relative to the "reference" 02329 frame we received. (initially the very first, but also see code just above here). 02330 Understand that "ms" can easily be -ve if lag improves since the reference frame. 02331 Called by IAX thread, with iaxsl lock held. */ 02332 ms = calc_rxstamp(iaxs[fr->callno], fr->ts) - fr->ts; 02333 02334 /* Rotate our history queue of "lateness". Don't worry about those initial 02335 zeros because the first entry will always be zero */ 02336 for (x=0;x<MEMORY_SIZE - 1;x++) 02337 iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1]; 02338 /* Add a history entry for this one */ 02339 iaxs[fr->callno]->history[x] = ms; 02340 #endif 02341 } 02342 #ifndef NEWJB 02343 else 02344 ms = 0; 02345 #endif 02346 02347 02348 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02349 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02350 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02351 else { 02352 #if 0 02353 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02354 #endif 02355 fr->af.delivery = ast_tv(0,0); 02356 } 02357 02358 #ifndef NEWJB 02359 /* Initialize the minimum to reasonable values. It's too much 02360 work to do the same for the maximum, repeatedly */ 02361 min=iaxs[fr->callno]->history[0]; 02362 for (z=0;z < iax2_dropcount + 1;z++) { 02363 /* Start very optimistic ;-) */ 02364 max=-999999999; 02365 for (x=0;x<MEMORY_SIZE;x++) { 02366 if (max < iaxs[fr->callno]->history[x]) { 02367 /* We have a candidate new maximum value. Make 02368 sure it's not in our drop list */ 02369 match = 0; 02370 for (y=0;!match && (y<z);y++) 02371 match |= (drops[y] == x); 02372 if (!match) { 02373 /* It's not in our list, use it as the new maximum */ 02374 max = iaxs[fr->callno]->history[x]; 02375 maxone = x; 02376 } 02377 02378 } 02379 if (!z) { 02380 /* On our first pass, find the minimum too */ 02381 if (min > iaxs[fr->callno]->history[x]) 02382 min = iaxs[fr->callno]->history[x]; 02383 } 02384 } 02385 #if 1 02386 drops[z] = maxone; 02387 #endif 02388 } 02389 #endif 02390 02391 #ifdef NEWJB 02392 type = JB_TYPE_CONTROL; 02393 len = 0; 02394 02395 if(fr->af.frametype == AST_FRAME_VOICE) { 02396 type = JB_TYPE_VOICE; 02397 len = ast_codec_get_samples(&fr->af) / 8; 02398 } else if(fr->af.frametype == AST_FRAME_CNG) { 02399 type = JB_TYPE_SILENCE; 02400 } 02401 02402 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02403 if (tsout) 02404 *tsout = fr->ts; 02405 __do_deliver(fr); 02406 return -1; 02407 } 02408 02409 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02410 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02411 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02412 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02413 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02414 jb_frame frame; 02415 02416 /* deliver any frames in the jb */ 02417 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK) 02418 __do_deliver(frame.data); 02419 02420 jb_reset(iaxs[fr->callno]->jb); 02421 02422 if (iaxs[fr->callno]->jbid > -1) 02423 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02424 02425 iaxs[fr->callno]->jbid = -1; 02426 02427 /* deliver this frame now */ 02428 if (tsout) 02429 *tsout = fr->ts; 02430 __do_deliver(fr); 02431 return -1; 02432 02433 } 02434 02435 02436 /* insert into jitterbuffer */ 02437 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02438 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02439 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02440 if (ret == JB_DROP) { 02441 needfree++; 02442 } else if (ret == JB_SCHED) { 02443 update_jbsched(iaxs[fr->callno]); 02444 } 02445 #else 02446 /* Just for reference, keep the "jitter" value, the difference between the 02447 earliest and the latest. */ 02448 if (max >= min) 02449 iaxs[fr->callno]->jitter = max - min; 02450 02451 /* IIR filter for keeping track of historic jitter, but always increase 02452 historic jitter immediately for increase */ 02453 02454 if (iaxs[fr->callno]->jitter > iaxs[fr->callno]->historicjitter ) 02455 iaxs[fr->callno]->historicjitter = iaxs[fr->callno]->jitter; 02456 else 02457 iaxs[fr->callno]->historicjitter = GAMMA * (double)iaxs[fr->callno]->jitter + (1-GAMMA) * 02458 iaxs[fr->callno]->historicjitter; 02459 02460 /* If our jitter buffer is too big (by a significant margin), then we slowly 02461 shrink it to avoid letting the change be perceived */ 02462 if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer) 02463 iaxs[fr->callno]->jitterbuffer -= jittershrinkrate; 02464 02465 /* If our jitter buffer headroom is too small (by a significant margin), then we slowly enlarge it */ 02466 /* min_jitter_buffer should be SMALLER than max_jitter_buffer - leaving a "no mans land" 02467 in between - otherwise the jitterbuffer size will hunt up and down causing unnecessary 02468 disruption. Set maxexcessbuffer to say 150msec, minexcessbuffer to say 50 */ 02469 if (max > iaxs[fr->callno]->jitterbuffer - min_jitter_buffer) 02470 iaxs[fr->callno]->jitterbuffer += jittershrinkrate; 02471 02472 /* If our jitter buffer is smaller than our maximum delay, grow the jitter 02473 buffer immediately to accomodate it (and a little more). */ 02474 if (max > iaxs[fr->callno]->jitterbuffer) 02475 iaxs[fr->callno]->jitterbuffer = max 02476 /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */; 02477 02478 /* update "min", just for RRs and stats */ 02479 iaxs[fr->callno]->min = min; 02480 02481 /* Subtract the lateness from our jitter buffer to know how long to wait 02482 before sending our packet. */ 02483 delay = iaxs[fr->callno]->jitterbuffer - ms; 02484 02485 /* Whatever happens, no frame waits longer than maxjitterbuffer */ 02486 if (delay > maxjitterbuffer) 02487 delay = maxjitterbuffer; 02488 02489 /* If jitter buffer is disabled then just pretend the frame is "right on time" */ 02490 /* If frame came from trunk, also don't do any delay */ 02491 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) || fromtrunk ) 02492 delay = 0; 02493 02494 if (option_debug && iaxdebug) { 02495 /* Log jitter stats for possible offline analysis */ 02496 ast_log(LOG_DEBUG, "Jitter: call=%d ts=%d orig=%d last=%d %s: min=%d max=%d jb=%d %+d lateness=%d jbdelay=%d jitter=%d historic=%d\n", 02497 fr->callno, fr->ts, orig_ts, iaxs[fr->callno]->last, 02498 (fr->af.frametype == AST_FRAME_VOICE) ? "VOICE" : "CONTROL", 02499 min, max, iaxs[fr->callno]->jitterbuffer, 02500 iaxs[fr->callno]->jitterbuffer - prevjitterbuffer, 02501 ms, delay, 02502 iaxs[fr->callno]->jitter, iaxs[fr->callno]->historicjitter); 02503 } 02504 02505 if (delay < 1) { 02506 /* Don't deliver it more than 4 ms late */ 02507 if ((delay > -4) || (fr->af.frametype != AST_FRAME_VOICE)) { 02508 if (option_debug && iaxdebug) 02509 ast_log(LOG_DEBUG, "schedule_delivery: Delivering immediately (Calculated delay is %d)\n", delay); 02510 if (tsout) 02511 *tsout = fr->ts; 02512 __do_deliver(fr); 02513 return -1; 02514 } else { 02515 if (option_debug && iaxdebug) 02516 ast_log(LOG_DEBUG, "schedule_delivery: Dropping voice packet since %dms delay is too old\n", delay); 02517 iaxs[fr->callno]->frames_dropped++; 02518 needfree++; 02519 } 02520 } else { 02521 if (option_debug && iaxdebug) 02522 ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay); 02523 fr->retrans = ast_sched_add(sched, delay, do_deliver, fr); 02524 } 02525 #endif 02526 if (tsout) 02527 *tsout = fr->ts; 02528 if (needfree) { 02529 /* Free our iax frame */ 02530 iax2_frame_free(fr); 02531 return -1; 02532 } 02533 return 0; 02534 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4690 of file chan_iax2.c.
References __send_command().
Referenced by attempt_transmit(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), send_command_locked(), send_lagrq(), send_ping(), and socket_read().
04691 { 04692 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04693 }
static int send_command_final | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4711 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy_nolock().
Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_hangup(), socket_read(), and update_registry().
04712 { 04713 /* It is assumed that the callno has already been locked */ 04714 iax2_predestroy_nolock(i->callno); 04715 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04716 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4718 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_read().
04719 { 04720 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04721 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4695 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit(), iax2_indicate(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
04696 { 04697 int res; 04698 ast_mutex_lock(&iaxsl[callno]); 04699 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04700 ast_mutex_unlock(&iaxsl[callno]); 04701 return res; 04702 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 4723 of file chan_iax2.c.
References __send_command().
Referenced by socket_read(), and try_transfer().
04724 { 04725 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04726 }
static int send_lagrq | ( | void * | data | ) | [static] |
Definition at line 812 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_LAGRQ, iaxs, and send_command().
Referenced by find_callno(), and make_trunk().
00813 { 00814 int callno = (long)data; 00815 /* Ping only if it's real not if it's bridged */ 00816 if (iaxs[callno]) { 00817 #ifdef BRIDGE_OPTIMIZATION 00818 if (!iaxs[callno]->bridgecallno) 00819 #endif 00820 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 00821 return 1; 00822 } else 00823 return 0; 00824 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1500 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), chan_iax2_pvt::callno, iax_frame::callno, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, LOG_WARNING, option_debug, iax_frame::transfer, and iax_frame::ts.
Referenced by attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01501 { 01502 int res; 01503 char iabuf[INET_ADDRSTRLEN]; 01504 /* Called with iaxsl held */ 01505 if (!iaxs[f->callno]) 01506 return -1; 01507 if (option_debug > 2 && iaxdebug) 01508 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port)); 01509 /* Don't send if there was an error, but return error instead */ 01510 if (!f->callno) { 01511 ast_log(LOG_WARNING, "Call number = %d\n", f->callno); 01512 return -1; 01513 } 01514 if (iaxs[f->callno]->error) 01515 return -1; 01516 if (f->transfer) { 01517 if (iaxdebug) 01518 iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01519 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer, 01520 sizeof(iaxs[f->callno]->transfer)); 01521 } else { 01522 if (iaxdebug) 01523 iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01524 res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr, 01525 sizeof(iaxs[f->callno]->addr)); 01526 } 01527 if (res < 0) { 01528 if (option_debug && iaxdebug) 01529 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01530 handle_error(); 01531 } else 01532 res = 0; 01533 return res; 01534 }
static int send_ping | ( | void * | data | ) | [static] |
Definition at line 786 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_PING, iaxs, and send_command().
Referenced by find_callno(), and make_trunk().
00787 { 00788 int callno = (long)data; 00789 /* Ping only if it's real, not if it's bridged */ 00790 if (iaxs[callno]) { 00791 #ifdef BRIDGE_OPTIMIZATION 00792 if (!iaxs[callno]->bridgecallno) 00793 #endif 00794 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00795 return 1; 00796 } else 00797 return 0; 00798 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6021 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06022 { 06023 int res = 0; 06024 struct iax_frame *fr; 06025 struct ast_iax2_meta_hdr *meta; 06026 struct ast_iax2_meta_trunk_hdr *mth; 06027 int calls = 0; 06028 06029 /* Point to frame */ 06030 fr = (struct iax_frame *)tpeer->trunkdata; 06031 /* Point to meta data */ 06032 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06033 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06034 if (tpeer->trunkdatalen) { 06035 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06036 meta->zeros = 0; 06037 meta->metacmd = IAX_META_TRUNK; 06038 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06039 meta->cmddata = IAX_META_TRUNK_MINI; 06040 else 06041 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06042 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06043 /* And the rest of the ast_iax2 header */ 06044 fr->direction = DIRECTION_OUTGRESS; 06045 fr->retrans = -1; 06046 fr->transfer = 0; 06047 /* Any appropriate call will do */ 06048 fr->data = fr->afdata; 06049 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06050 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06051 calls = tpeer->calls; 06052 #if 0 06053 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)); 06054 #endif 06055 /* Reset transmit trunk side data */ 06056 tpeer->trunkdatalen = 0; 06057 tpeer->calls = 0; 06058 } 06059 if (res < 0) 06060 return res; 06061 return calls; 06062 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Definition at line 8698 of file chan_iax2.c.
References 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(), build_peer(), build_user(), capability, cfg, DEFAULT_MAXMS, format, get_encrypt_methods(), global_rtautoclear, globalflags, iax2_register(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, io, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_jitter_buffer, min_jitter_buffer, ast_variable::name, netsock, iax2_peer::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, portno, prefs, reg_source_db(), set_timing(), socket_read(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), and reload().
08699 { 08700 struct ast_config *cfg; 08701 int capability=iax2_capability; 08702 struct ast_variable *v; 08703 char *cat; 08704 char *utype; 08705 char *tosval; 08706 int format; 08707 int portno = IAX_DEFAULT_PORTNO; 08708 int x; 08709 struct iax2_user *user; 08710 struct iax2_peer *peer; 08711 struct ast_netsock *ns; 08712 #if 0 08713 static unsigned short int last_port=0; 08714 #endif 08715 08716 cfg = ast_config_load(config_file); 08717 08718 if (!cfg) { 08719 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08720 return -1; 08721 } 08722 08723 /* Reset global codec prefs */ 08724 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08725 08726 /* Reset Global Flags */ 08727 memset(&globalflags, 0, sizeof(globalflags)); 08728 ast_set_flag(&globalflags, IAX_RTUPDATE); 08729 08730 #ifdef SO_NO_CHECK 08731 nochecksums = 0; 08732 #endif 08733 08734 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08735 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08736 08737 maxauthreq = 0; 08738 08739 v = ast_variable_browse(cfg, "general"); 08740 08741 /* Seed initial tos value */ 08742 tosval = ast_variable_retrieve(cfg, "general", "tos"); 08743 if (tosval) { 08744 if (ast_str2tos(tosval, &tos)) 08745 ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n"); 08746 } 08747 while(v) { 08748 if (!strcasecmp(v->name, "bindport")){ 08749 if (reload) 08750 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 08751 else 08752 portno = atoi(v->value); 08753 } else if (!strcasecmp(v->name, "pingtime")) 08754 ping_time = atoi(v->value); 08755 else if (!strcasecmp(v->name, "nochecksums")) { 08756 #ifdef SO_NO_CHECK 08757 if (ast_true(v->value)) 08758 nochecksums = 1; 08759 else 08760 nochecksums = 0; 08761 #else 08762 if (ast_true(v->value)) 08763 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 08764 #endif 08765 } 08766 else if (!strcasecmp(v->name, "maxjitterbuffer")) 08767 maxjitterbuffer = atoi(v->value); 08768 #ifdef NEWJB 08769 else if (!strcasecmp(v->name, "resyncthreshold")) 08770 resyncthreshold = atoi(v->value); 08771 else if (!strcasecmp(v->name, "maxjitterinterps")) 08772 maxjitterinterps = atoi(v->value); 08773 #endif 08774 else if (!strcasecmp(v->name, "jittershrinkrate")) 08775 jittershrinkrate = atoi(v->value); 08776 else if (!strcasecmp(v->name, "maxexcessbuffer")) 08777 max_jitter_buffer = atoi(v->value); 08778 else if (!strcasecmp(v->name, "minexcessbuffer")) 08779 min_jitter_buffer = atoi(v->value); 08780 else if (!strcasecmp(v->name, "lagrqtime")) 08781 lagrq_time = atoi(v->value); 08782 else if (!strcasecmp(v->name, "dropcount")) 08783 iax2_dropcount = atoi(v->value); 08784 else if (!strcasecmp(v->name, "maxregexpire")) 08785 max_reg_expire = atoi(v->value); 08786 else if (!strcasecmp(v->name, "minregexpire")) 08787 min_reg_expire = atoi(v->value); 08788 else if (!strcasecmp(v->name, "bindaddr")) { 08789 if (reload) { 08790 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 08791 } else { 08792 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 08793 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 08794 } else { 08795 if (option_verbose > 1) { 08796 if (strchr(v->value, ':')) 08797 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 08798 else 08799 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 08800 } 08801 if (defaultsockfd < 0) 08802 defaultsockfd = ast_netsock_sockfd(ns); 08803 ast_netsock_unref(ns); 08804 } 08805 } 08806 } else if (!strcasecmp(v->name, "authdebug")) 08807 authdebug = ast_true(v->value); 08808 else if (!strcasecmp(v->name, "encryption")) 08809 iax2_encryption = get_encrypt_methods(v->value); 08810 else if (!strcasecmp(v->name, "notransfer")) 08811 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 08812 else if (!strcasecmp(v->name, "codecpriority")) { 08813 if(!strcasecmp(v->value, "caller")) 08814 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 08815 else if(!strcasecmp(v->value, "disabled")) 08816 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08817 else if(!strcasecmp(v->value, "reqonly")) { 08818 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 08819 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 08820 } 08821 } else if (!strcasecmp(v->name, "jitterbuffer")) 08822 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 08823 else if (!strcasecmp(v->name, "forcejitterbuffer")) 08824 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 08825 else if (!strcasecmp(v->name, "delayreject")) 08826 delayreject = ast_true(v->value); 08827 else if (!strcasecmp(v->name, "mailboxdetail")) 08828 ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL); 08829 else if (!strcasecmp(v->name, "rtcachefriends")) 08830 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 08831 else if (!strcasecmp(v->name, "rtignoreregexpire")) 08832 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 08833 else if (!strcasecmp(v->name, "rtupdate")) 08834 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 08835 else if (!strcasecmp(v->name, "trunktimestamps")) 08836 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 08837 else if (!strcasecmp(v->name, "rtautoclear")) { 08838 int i = atoi(v->value); 08839 if(i > 0) 08840 global_rtautoclear = i; 08841 else 08842 i = 0; 08843 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 08844 } else if (!strcasecmp(v->name, "trunkfreq")) { 08845 trunkfreq = atoi(v->value); 08846 if (trunkfreq < 10) 08847 trunkfreq = 10; 08848 } else if (!strcasecmp(v->name, "autokill")) { 08849 if (sscanf(v->value, "%d", &x) == 1) { 08850 if (x >= 0) 08851 autokill = x; 08852 else 08853 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 08854 } else if (ast_true(v->value)) { 08855 autokill = DEFAULT_MAXMS; 08856 } else { 08857 autokill = 0; 08858 } 08859 } else if (!strcasecmp(v->name, "bandwidth")) { 08860 if (!strcasecmp(v->value, "low")) { 08861 capability = IAX_CAPABILITY_LOWBANDWIDTH; 08862 } else if (!strcasecmp(v->value, "medium")) { 08863 capability = IAX_CAPABILITY_MEDBANDWIDTH; 08864 } else if (!strcasecmp(v->value, "high")) { 08865 capability = IAX_CAPABILITY_FULLBANDWIDTH; 08866 } else 08867 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 08868 } else if (!strcasecmp(v->name, "allow")) { 08869 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 08870 } else if (!strcasecmp(v->name, "disallow")) { 08871 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 08872 } else if (!strcasecmp(v->name, "register")) { 08873 iax2_register(v->value, v->lineno); 08874 } else if (!strcasecmp(v->name, "iaxcompat")) { 08875 iaxcompat = ast_true(v->value); 08876 } else if (!strcasecmp(v->name, "regcontext")) { 08877 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 08878 /* Create context if it doesn't exist already */ 08879 if (!ast_context_find(regcontext)) 08880 ast_context_create(NULL, regcontext, channeltype); 08881 } else if (!strcasecmp(v->name, "tos")) { 08882 if (ast_str2tos(v->value, &tos)) 08883 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 08884 } else if (!strcasecmp(v->name, "accountcode")) { 08885 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 08886 } else if (!strcasecmp(v->name, "amaflags")) { 08887 format = ast_cdr_amaflags2int(v->value); 08888 if (format < 0) { 08889 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08890 } else { 08891 amaflags = format; 08892 } 08893 } else if (!strcasecmp(v->name, "language")) { 08894 ast_copy_string(language, v->value, sizeof(language)); 08895 } else if (!strcasecmp(v->name, "maxauthreq")) { 08896 maxauthreq = atoi(v->value); 08897 if (maxauthreq < 0) 08898 maxauthreq = 0; 08899 } /*else if (strcasecmp(v->name,"type")) */ 08900 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08901 v = v->next; 08902 } 08903 08904 if (defaultsockfd < 0) { 08905 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 08906 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 08907 } else { 08908 if (option_verbose > 1) 08909 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 08910 defaultsockfd = ast_netsock_sockfd(ns); 08911 ast_netsock_unref(ns); 08912 } 08913 } 08914 08915 if (min_reg_expire > max_reg_expire) { 08916 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 08917 min_reg_expire, max_reg_expire, max_reg_expire); 08918 min_reg_expire = max_reg_expire; 08919 } 08920 iax2_capability = capability; 08921 cat = ast_category_browse(cfg, NULL); 08922 while(cat) { 08923 if (strcasecmp(cat, "general")) { 08924 utype = ast_variable_retrieve(cfg, cat, "type"); 08925 if (utype) { 08926 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 08927 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 08928 if (user) { 08929 ast_mutex_lock(&userl.lock); 08930 user->next = userl.users; 08931 userl.users = user; 08932 ast_mutex_unlock(&userl.lock); 08933 } 08934 } 08935 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 08936 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 08937 if (peer) { 08938 ast_mutex_lock(&peerl.lock); 08939 peer->next = peerl.peers; 08940 peerl.peers = peer; 08941 ast_mutex_unlock(&peerl.lock); 08942 if (ast_test_flag(peer, IAX_DYNAMIC)) 08943 reg_source_db(peer); 08944 } 08945 } else if (strcasecmp(utype, "user")) { 08946 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 08947 } 08948 } else 08949 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 08950 } 08951 cat = ast_category_browse(cfg, cat); 08952 } 08953 ast_config_destroy(cfg); 08954 set_timing(); 08955 return capability; 08956 }
static void set_timing | ( | void | ) | [static] |
Definition at line 8681 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
08682 { 08683 #ifdef IAX_TRUNKING 08684 int bs = trunkfreq * 8; 08685 if (timingfd > -1) { 08686 if ( 08687 #ifdef ZT_TIMERACK 08688 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08689 #endif 08690 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08691 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08692 } 08693 #endif 08694 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6353 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, check_access(), check_provisioning(), complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, ast_frame::data, ast_frame::datalen, decrypt_frame(), dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, ast_frame::frametype, handle_error(), ast_iax2_queue::head, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy_nolock(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_frame(), iax2_send(), iax2_vnak(), IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iaxfrdup2(), iaxq, iaxsl, ies, inaddrcmp(), iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_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, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_debug, option_verbose, iax_frame::oseqno, iax2_dpcache::peer, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, stop_stuff(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, vnak_retransmit(), ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros.
Referenced by network_thread(), and set_config().
06354 { 06355 struct sockaddr_in sin; 06356 int res; 06357 int updatehistory=1; 06358 int new = NEW_PREVENT; 06359 unsigned char buf[4096]; 06360 void *ptr; 06361 socklen_t len = sizeof(sin); 06362 int dcallno = 0; 06363 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf; 06364 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf; 06365 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; 06366 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf; 06367 struct ast_iax2_meta_trunk_hdr *mth; 06368 struct ast_iax2_meta_trunk_entry *mte; 06369 struct ast_iax2_meta_trunk_mini *mtm; 06370 struct iax_frame *fr; 06371 struct iax_frame *cur; 06372 char iabuf[INET_ADDRSTRLEN]; 06373 struct ast_frame f; 06374 struct ast_channel *c; 06375 struct iax2_dpcache *dp; 06376 struct iax2_peer *peer; 06377 struct iax2_trunk_peer *tpeer; 06378 struct timeval rxtrunktime; 06379 struct iax_ies ies; 06380 struct iax_ie_data ied0, ied1; 06381 int format; 06382 int exists; 06383 int minivid = 0; 06384 unsigned int ts; 06385 char empty[32]=""; /* Safety measure */ 06386 struct iax_frame *duped_fr; 06387 char host_pref_buf[128]; 06388 char caller_pref_buf[128]; 06389 struct ast_codec_pref pref; 06390 char *using_prefs = "mine"; 06391 06392 /* allocate an iax_frame with 4096 bytes of data buffer */ 06393 fr = alloca(sizeof(*fr) + 4096); 06394 fr->callno = 0; 06395 06396 res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len); 06397 if (res < 0) { 06398 if (errno != ECONNREFUSED) 06399 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06400 handle_error(); 06401 return 1; 06402 } 06403 if(test_losspct) { /* simulate random loss condition */ 06404 if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct) 06405 return 1; 06406 06407 } 06408 if (res < sizeof(*mh)) { 06409 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06410 return 1; 06411 } 06412 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06413 if (res < sizeof(*vh)) { 06414 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06415 return 1; 06416 } 06417 06418 /* This is a video frame, get call number */ 06419 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06420 minivid = 1; 06421 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06422 unsigned char metatype; 06423 06424 if (res < sizeof(*meta)) { 06425 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06426 return 1; 06427 } 06428 06429 /* This is a meta header */ 06430 switch(meta->metacmd) { 06431 case IAX_META_TRUNK: 06432 if (res < (sizeof(*meta) + sizeof(*mth))) { 06433 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06434 sizeof(*meta) + sizeof(*mth)); 06435 return 1; 06436 } 06437 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06438 ts = ntohl(mth->ts); 06439 metatype = meta->cmddata; 06440 res -= (sizeof(*meta) + sizeof(*mth)); 06441 ptr = mth->data; 06442 tpeer = find_tpeer(&sin, fd); 06443 if (!tpeer) { 06444 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)); 06445 return 1; 06446 } 06447 tpeer->trunkact = ast_tvnow(); 06448 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06449 tpeer->rxtrunktime = tpeer->trunkact; 06450 rxtrunktime = tpeer->rxtrunktime; 06451 ast_mutex_unlock(&tpeer->lock); 06452 while(res >= sizeof(*mte)) { 06453 /* Process channels */ 06454 unsigned short callno, trunked_ts, len; 06455 06456 if (metatype == IAX_META_TRUNK_MINI) { 06457 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06458 ptr += sizeof(*mtm); 06459 res -= sizeof(*mtm); 06460 len = ntohs(mtm->len); 06461 callno = ntohs(mtm->mini.callno); 06462 trunked_ts = ntohs(mtm->mini.ts); 06463 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06464 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06465 ptr += sizeof(*mte); 06466 res -= sizeof(*mte); 06467 len = ntohs(mte->len); 06468 callno = ntohs(mte->callno); 06469 trunked_ts = 0; 06470 } else { 06471 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)); 06472 break; 06473 } 06474 /* Stop if we don't have enough data */ 06475 if (len > res) 06476 break; 06477 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06478 if (fr->callno) { 06479 ast_mutex_lock(&iaxsl[fr->callno]); 06480 /* If it's a valid call, deliver the contents. If not, we 06481 drop it, since we don't have a scallno to use for an INVAL */ 06482 /* Process as a mini frame */ 06483 f.frametype = AST_FRAME_VOICE; 06484 if (iaxs[fr->callno]) { 06485 if (iaxs[fr->callno]->voiceformat > 0) { 06486 f.subclass = iaxs[fr->callno]->voiceformat; 06487 f.datalen = len; 06488 if (f.datalen >= 0) { 06489 if (f.datalen) 06490 f.data = ptr; 06491 else 06492 f.data = NULL; 06493 if(trunked_ts) { 06494 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06495 } else 06496 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06497 /* Don't pass any packets until we're started */ 06498 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06499 /* Common things */ 06500 f.src = "IAX2"; 06501 f.mallocd = 0; 06502 f.offset = 0; 06503 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06504 f.samples = ast_codec_get_samples(&f); 06505 else 06506 f.samples = 0; 06507 fr->outoforder = 0; 06508 iax_frame_wrap(fr, &f); 06509 #ifdef BRIDGE_OPTIMIZATION 06510 if (iaxs[fr->callno]->bridgecallno) { 06511 forward_delivery(fr); 06512 } else { 06513 duped_fr = iaxfrdup2(fr); 06514 if (duped_fr) { 06515 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06516 } 06517 } 06518 #else 06519 duped_fr = iaxfrdup2(fr); 06520 if (duped_fr) { 06521 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06522 } 06523 #endif 06524 if (iaxs[fr->callno]->last < fr->ts) { 06525 iaxs[fr->callno]->last = fr->ts; 06526 #if 1 06527 if (option_debug) 06528 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06529 #endif 06530 } 06531 } 06532 } else { 06533 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06534 } 06535 } else { 06536 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06537 iax2_vnak(fr->callno); 06538 } 06539 } 06540 ast_mutex_unlock(&iaxsl[fr->callno]); 06541 } 06542 ptr += len; 06543 res -= len; 06544 } 06545 06546 } 06547 return 1; 06548 } 06549 06550 #ifdef DEBUG_SUPPORT 06551 if (iaxdebug && (res >= sizeof(*fh))) 06552 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06553 #endif 06554 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06555 if (res < sizeof(*fh)) { 06556 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 06557 return 1; 06558 } 06559 06560 /* Get the destination call number */ 06561 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06562 /* Retrieve the type and subclass */ 06563 f.frametype = fh->type; 06564 if (f.frametype == AST_FRAME_VIDEO) { 06565 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06566 } else { 06567 f.subclass = uncompress_subclass(fh->csub); 06568 } 06569 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06570 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06571 (f.subclass == IAX_COMMAND_REGREL))) 06572 new = NEW_ALLOW; 06573 } else { 06574 /* Don't know anything about it yet */ 06575 f.frametype = AST_FRAME_NULL; 06576 f.subclass = 0; 06577 } 06578 06579 if (!fr->callno) 06580 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06581 06582 if (fr->callno > 0) 06583 ast_mutex_lock(&iaxsl[fr->callno]); 06584 06585 if (!fr->callno || !iaxs[fr->callno]) { 06586 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06587 frame, reply with an inval */ 06588 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06589 /* We can only raw hangup control frames */ 06590 if (((f.subclass != IAX_COMMAND_INVAL) && 06591 (f.subclass != IAX_COMMAND_TXCNT) && 06592 (f.subclass != IAX_COMMAND_TXACC) && 06593 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06594 (f.frametype != AST_FRAME_IAX)) 06595 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06596 fd); 06597 } 06598 if (fr->callno > 0) 06599 ast_mutex_unlock(&iaxsl[fr->callno]); 06600 return 1; 06601 } 06602 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06603 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06604 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06605 ast_mutex_unlock(&iaxsl[fr->callno]); 06606 return 1; 06607 } 06608 #ifdef DEBUG_SUPPORT 06609 else if (iaxdebug) 06610 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 06611 #endif 06612 } 06613 06614 /* count this frame */ 06615 iaxs[fr->callno]->frames_received++; 06616 06617 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 06618 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06619 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06620 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06621 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06622 if (option_debug && iaxdebug) 06623 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06624 /* Check if it's out of order (and not an ACK or INVAL) */ 06625 fr->oseqno = fh->oseqno; 06626 fr->iseqno = fh->iseqno; 06627 fr->ts = ntohl(fh->ts); 06628 #ifdef IAXTESTS 06629 if (test_resync) { 06630 if (option_debug) 06631 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 06632 fr->ts += test_resync; 06633 } 06634 #endif /* IAXTESTS */ 06635 #if 0 06636 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06637 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06638 (f.subclass == IAX_COMMAND_NEW || 06639 f.subclass == IAX_COMMAND_AUTHREQ || 06640 f.subclass == IAX_COMMAND_ACCEPT || 06641 f.subclass == IAX_COMMAND_REJECT)) ) ) 06642 #endif 06643 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06644 updatehistory = 0; 06645 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 06646 (iaxs[fr->callno]->iseqno || 06647 ((f.subclass != IAX_COMMAND_TXCNT) && 06648 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06649 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06650 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06651 (f.subclass != IAX_COMMAND_TXACC)) || 06652 (f.frametype != AST_FRAME_IAX))) { 06653 if ( 06654 ((f.subclass != IAX_COMMAND_ACK) && 06655 (f.subclass != IAX_COMMAND_INVAL) && 06656 (f.subclass != IAX_COMMAND_TXCNT) && 06657 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06658 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06659 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06660 (f.subclass != IAX_COMMAND_TXACC) && 06661 (f.subclass != IAX_COMMAND_VNAK)) || 06662 (f.frametype != AST_FRAME_IAX)) { 06663 /* If it's not an ACK packet, it's out of order. */ 06664 if (option_debug) 06665 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06666 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 06667 if (iaxs[fr->callno]->iseqno > fr->oseqno) { 06668 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06669 if ((f.frametype != AST_FRAME_IAX) || 06670 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06671 if (option_debug) 06672 ast_log(LOG_DEBUG, "Acking anyway\n"); 06673 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06674 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06675 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06676 } 06677 } else { 06678 /* Send a VNAK requesting retransmission */ 06679 iax2_vnak(fr->callno); 06680 } 06681 ast_mutex_unlock(&iaxsl[fr->callno]); 06682 return 1; 06683 } 06684 } else { 06685 /* Increment unless it's an ACK or VNAK */ 06686 if (((f.subclass != IAX_COMMAND_ACK) && 06687 (f.subclass != IAX_COMMAND_INVAL) && 06688 (f.subclass != IAX_COMMAND_TXCNT) && 06689 (f.subclass != IAX_COMMAND_TXACC) && 06690 (f.subclass != IAX_COMMAND_VNAK)) || 06691 (f.frametype != AST_FRAME_IAX)) 06692 iaxs[fr->callno]->iseqno++; 06693 } 06694 /* A full frame */ 06695 if (res < sizeof(*fh)) { 06696 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 06697 ast_mutex_unlock(&iaxsl[fr->callno]); 06698 return 1; 06699 } 06700 f.datalen = res - sizeof(*fh); 06701 06702 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06703 from the real peer, not the transfer peer */ 06704 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06705 ((f.subclass != IAX_COMMAND_INVAL) || 06706 (f.frametype != AST_FRAME_IAX))) { 06707 unsigned char x; 06708 /* XXX This code is not very efficient. Surely there is a better way which still 06709 properly handles boundary conditions? XXX */ 06710 /* First we have to qualify that the ACKed value is within our window */ 06711 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 06712 if (fr->iseqno == x) 06713 break; 06714 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 06715 /* The acknowledgement is within our window. Time to acknowledge everything 06716 that it says to */ 06717 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 06718 /* Ack the packet with the given timestamp */ 06719 if (option_debug && iaxdebug) 06720 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06721 ast_mutex_lock(&iaxq.lock); 06722 for (cur = iaxq.head; cur ; cur = cur->next) { 06723 /* If it's our call, and our timestamp, mark -1 retries */ 06724 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 06725 cur->retries = -1; 06726 /* Destroy call if this is the end */ 06727 if (cur->final) { 06728 if (iaxdebug && option_debug) 06729 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno); 06730 iax2_destroy_nolock(fr->callno); 06731 } 06732 } 06733 } 06734 ast_mutex_unlock(&iaxq.lock); 06735 } 06736 /* Note how much we've received acknowledgement for */ 06737 if (iaxs[fr->callno]) 06738 iaxs[fr->callno]->rseqno = fr->iseqno; 06739 else { 06740 /* Stop processing now */ 06741 ast_mutex_unlock(&iaxsl[fr->callno]); 06742 return 1; 06743 } 06744 } else 06745 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 06746 } 06747 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06748 ((f.frametype != AST_FRAME_IAX) || 06749 ((f.subclass != IAX_COMMAND_TXACC) && 06750 (f.subclass != IAX_COMMAND_TXCNT)))) { 06751 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06752 ast_mutex_unlock(&iaxsl[fr->callno]); 06753 return 1; 06754 } 06755 06756 if (f.datalen) { 06757 if (f.frametype == AST_FRAME_IAX) { 06758 if (iax_parse_ies(&ies, buf + sizeof(*fh), f.datalen)) { 06759 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 06760 ast_mutex_unlock(&iaxsl[fr->callno]); 06761 return 1; 06762 } 06763 f.data = NULL; 06764 } else 06765 f.data = buf + sizeof(*fh); 06766 } else { 06767 if (f.frametype == AST_FRAME_IAX) 06768 f.data = NULL; 06769 else 06770 f.data = empty; 06771 memset(&ies, 0, sizeof(ies)); 06772 } 06773 if (f.frametype == AST_FRAME_VOICE) { 06774 if (f.subclass != iaxs[fr->callno]->voiceformat) { 06775 iaxs[fr->callno]->voiceformat = f.subclass; 06776 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06777 if (iaxs[fr->callno]->owner) { 06778 int orignative; 06779 retryowner: 06780 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 06781 ast_mutex_unlock(&iaxsl[fr->callno]); 06782 usleep(1); 06783 ast_mutex_lock(&iaxsl[fr->callno]); 06784 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 06785 } 06786 if (iaxs[fr->callno]) { 06787 if (iaxs[fr->callno]->owner) { 06788 orignative = iaxs[fr->callno]->owner->nativeformats; 06789 iaxs[fr->callno]->owner->nativeformats = f.subclass; 06790 if (iaxs[fr->callno]->owner->readformat) 06791 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 06792 iaxs[fr->callno]->owner->nativeformats = orignative; 06793 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 06794 } 06795 } else { 06796 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06797 ast_mutex_unlock(&iaxsl[fr->callno]); 06798 return 1; 06799 } 06800 } 06801 } 06802 } 06803 if (f.frametype == AST_FRAME_VIDEO) { 06804 if (f.subclass != iaxs[fr->callno]->videoformat) { 06805 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06806 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 06807 } 06808 } 06809 if (f.frametype == AST_FRAME_IAX) { 06810 if (iaxs[fr->callno]->initid > -1) { 06811 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06812 ast_sched_del(sched, iaxs[fr->callno]->initid); 06813 iaxs[fr->callno]->initid = -1; 06814 } 06815 /* Handle the IAX pseudo frame itself */ 06816 if (option_debug && iaxdebug) 06817 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06818 06819 /* Update last ts unless the frame's timestamp originated with us. */ 06820 if (iaxs[fr->callno]->last < fr->ts && 06821 f.subclass != IAX_COMMAND_ACK && 06822 f.subclass != IAX_COMMAND_PONG && 06823 f.subclass != IAX_COMMAND_LAGRP) { 06824 iaxs[fr->callno]->last = fr->ts; 06825 if (option_debug && iaxdebug) 06826 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06827 } 06828 06829 switch(f.subclass) { 06830 case IAX_COMMAND_ACK: 06831 /* Do nothing */ 06832 break; 06833 case IAX_COMMAND_QUELCH: 06834 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06835 /* Generate Manager Hold event, if necessary*/ 06836 if (iaxs[fr->callno]->owner) { 06837 manager_event(EVENT_FLAG_CALL, "Hold", 06838 "Channel: %s\r\n" 06839 "Uniqueid: %s\r\n", 06840 iaxs[fr->callno]->owner->name, 06841 iaxs[fr->callno]->owner->uniqueid); 06842 } 06843 06844 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 06845 if (ies.musiconhold) { 06846 if (iaxs[fr->callno]->owner && 06847 ast_bridged_channel(iaxs[fr->callno]->owner)) 06848 ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL); 06849 } 06850 } 06851 break; 06852 case IAX_COMMAND_UNQUELCH: 06853 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06854 /* Generate Manager Unhold event, if necessary*/ 06855 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 06856 manager_event(EVENT_FLAG_CALL, "Unhold", 06857 "Channel: %s\r\n" 06858 "Uniqueid: %s\r\n", 06859 iaxs[fr->callno]->owner->name, 06860 iaxs[fr->callno]->owner->uniqueid); 06861 } 06862 06863 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 06864 if (iaxs[fr->callno]->owner && 06865 ast_bridged_channel(iaxs[fr->callno]->owner)) 06866 ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner)); 06867 } 06868 break; 06869 case IAX_COMMAND_TXACC: 06870 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 06871 /* Ack the packet with the given timestamp */ 06872 ast_mutex_lock(&iaxq.lock); 06873 for (cur = iaxq.head; cur ; cur = cur->next) { 06874 /* Cancel any outstanding txcnt's */ 06875 if ((fr->callno == cur->callno) && (cur->transfer)) 06876 cur->retries = -1; 06877 } 06878 ast_mutex_unlock(&iaxq.lock); 06879 memset(&ied1, 0, sizeof(ied1)); 06880 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 06881 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06882 iaxs[fr->callno]->transferring = TRANSFER_READY; 06883 } 06884 break; 06885 case IAX_COMMAND_NEW: 06886 /* Ignore if it's already up */ 06887 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06888 break; 06889 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06890 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06891 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06892 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 06893 fr->callno = make_trunk(fr->callno, 1); 06894 } 06895 /* For security, always ack immediately */ 06896 if (delayreject) 06897 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06898 if (check_access(fr->callno, &sin, &ies)) { 06899 /* They're not allowed on */ 06900 auth_fail(fr->callno, IAX_COMMAND_REJECT); 06901 if (authdebug) 06902 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); 06903 break; 06904 } 06905 /* This might re-enter the IAX code and need the lock */ 06906 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 06907 ast_mutex_unlock(&iaxsl[fr->callno]); 06908 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 06909 ast_mutex_lock(&iaxsl[fr->callno]); 06910 } else 06911 exists = 0; 06912 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 06913 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 06914 memset(&ied0, 0, sizeof(ied0)); 06915 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06916 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06917 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06918 if (authdebug) 06919 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); 06920 } else { 06921 /* Select an appropriate format */ 06922 06923 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06924 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06925 using_prefs = "reqonly"; 06926 } else { 06927 using_prefs = "disabled"; 06928 } 06929 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 06930 memset(&pref, 0, sizeof(pref)); 06931 strcpy(caller_pref_buf, "disabled"); 06932 strcpy(host_pref_buf, "disabled"); 06933 } else { 06934 using_prefs = "mine"; 06935 /* If the information elements are in here... use them */ 06936 if (ies.codec_prefs) 06937 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 06938 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06939 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06940 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06941 pref = iaxs[fr->callno]->rprefs; 06942 using_prefs = "caller"; 06943 } else { 06944 pref = iaxs[fr->callno]->prefs; 06945 } 06946 } else 06947 pref = iaxs[fr->callno]->prefs; 06948 06949 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 06950 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06951 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06952 } 06953 if (!format) { 06954 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06955 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 06956 if (!format) { 06957 memset(&ied0, 0, sizeof(ied0)); 06958 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06959 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06960 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06961 if (authdebug) { 06962 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06963 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); 06964 else 06965 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); 06966 } 06967 } else { 06968 /* Pick one... */ 06969 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06970 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 06971 format = 0; 06972 } else { 06973 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06974 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06975 memset(&pref, 0, sizeof(pref)); 06976 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06977 strcpy(caller_pref_buf,"disabled"); 06978 strcpy(host_pref_buf,"disabled"); 06979 } else { 06980 using_prefs = "mine"; 06981 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06982 /* Do the opposite of what we tried above. */ 06983 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06984 pref = iaxs[fr->callno]->prefs; 06985 } else { 06986 pref = iaxs[fr->callno]->rprefs; 06987 using_prefs = "caller"; 06988 } 06989 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 06990 06991 } else /* if no codec_prefs IE do it the old way */ 06992 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06993 } 06994 } 06995 06996 if (!format) { 06997 memset(&ied0, 0, sizeof(ied0)); 06998 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06999 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07000 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07001 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07002 if (authdebug) 07003 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); 07004 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07005 break; 07006 } 07007 } 07008 } 07009 if (format) { 07010 /* No authentication required, let them in */ 07011 memset(&ied1, 0, sizeof(ied1)); 07012 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07013 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07014 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07015 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07016 if (option_verbose > 2) 07017 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07018 "%srequested format = %s,\n" 07019 "%srequested prefs = %s,\n" 07020 "%sactual format = %s,\n" 07021 "%shost prefs = %s,\n" 07022 "%spriority = %s\n", 07023 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07024 VERBOSE_PREFIX_4, 07025 ast_getformatname(iaxs[fr->callno]->peerformat), 07026 VERBOSE_PREFIX_4, 07027 caller_pref_buf, 07028 VERBOSE_PREFIX_4, 07029 ast_getformatname(format), 07030 VERBOSE_PREFIX_4, 07031 host_pref_buf, 07032 VERBOSE_PREFIX_4, 07033 using_prefs); 07034 07035 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07036 iax2_destroy_nolock(fr->callno); 07037 } else { 07038 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07039 /* If this is a TBD call, we're ready but now what... */ 07040 if (option_verbose > 2) 07041 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07042 } 07043 } 07044 } 07045 break; 07046 } 07047 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07048 merge_encryption(iaxs[fr->callno],ies.encmethods); 07049 else 07050 iaxs[fr->callno]->encmethods = 0; 07051 if (!authenticate_request(iaxs[fr->callno])) 07052 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07053 break; 07054 case IAX_COMMAND_DPREQ: 07055 /* Request status in the dialplan */ 07056 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07057 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07058 if (iaxcompat) { 07059 /* Spawn a thread for the lookup */ 07060 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07061 } else { 07062 /* Just look it up */ 07063 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07064 } 07065 } 07066 break; 07067 case IAX_COMMAND_HANGUP: 07068 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07069 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07070 /* Set hangup cause according to remote */ 07071 if (ies.causecode && iaxs[fr->callno]->owner) 07072 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07073 /* Send ack immediately, before we destroy */ 07074 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07075 iax2_destroy_nolock(fr->callno); 07076 break; 07077 case IAX_COMMAND_REJECT: 07078 memset(&f, 0, sizeof(f)); 07079 f.frametype = AST_FRAME_CONTROL; 07080 f.subclass = AST_CONTROL_CONGESTION; 07081 07082 /* Set hangup cause according to remote */ 07083 if (ies.causecode && iaxs[fr->callno]->owner) 07084 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07085 07086 iax2_queue_frame(fr->callno, &f); 07087 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07088 /* Send ack immediately, before we destroy */ 07089 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07090 iax2_destroy_nolock(fr->callno); 07091 break; 07092 } 07093 if (iaxs[fr->callno]->owner) { 07094 if (authdebug) 07095 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>"); 07096 } 07097 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno); 07098 /* Send ack immediately, before we destroy */ 07099 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07100 iaxs[fr->callno]->error = EPERM; 07101 iax2_destroy_nolock(fr->callno); 07102 break; 07103 case IAX_COMMAND_TRANSFER: 07104 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07105 if (!strcmp(ies.called_number, ast_parking_ext())) { 07106 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07107 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07108 } else 07109 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07110 } else { 07111 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07112 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07113 ies.called_number, iaxs[fr->callno]->context); 07114 else 07115 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07116 ies.called_number, iaxs[fr->callno]->context); 07117 } 07118 } else 07119 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07120 break; 07121 case IAX_COMMAND_ACCEPT: 07122 /* Ignore if call is already up or needs authentication or is a TBD */ 07123 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07124 break; 07125 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07126 /* Send ack immediately, before we destroy */ 07127 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07128 iax2_destroy_nolock(fr->callno); 07129 break; 07130 } 07131 if (ies.format) { 07132 iaxs[fr->callno]->peerformat = ies.format; 07133 } else { 07134 if (iaxs[fr->callno]->owner) 07135 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07136 else 07137 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07138 } 07139 if (option_verbose > 2) 07140 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)); 07141 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07142 memset(&ied0, 0, sizeof(ied0)); 07143 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07144 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07145 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07146 if (authdebug) 07147 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); 07148 } else { 07149 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07150 if (iaxs[fr->callno]->owner) { 07151 /* Switch us to use a compatible format */ 07152 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07153 if (option_verbose > 2) 07154 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07155 retryowner2: 07156 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07157 ast_mutex_unlock(&iaxsl[fr->callno]); 07158 usleep(1); 07159 ast_mutex_lock(&iaxsl[fr->callno]); 07160 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07161 } 07162 07163 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07164 /* Setup read/write formats properly. */ 07165 if (iaxs[fr->callno]->owner->writeformat) 07166 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07167 if (iaxs[fr->callno]->owner->readformat) 07168 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07169 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07170 } 07171 } 07172 } 07173 ast_mutex_lock(&dpcache_lock); 07174 dp = iaxs[fr->callno]->dpentries; 07175 while(dp) { 07176 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07177 iax2_dprequest(dp, fr->callno); 07178 } 07179 dp = dp->peer; 07180 } 07181 ast_mutex_unlock(&dpcache_lock); 07182 break; 07183 case IAX_COMMAND_POKE: 07184 /* Send back a pong packet with the original timestamp */ 07185 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07186 break; 07187 case IAX_COMMAND_PING: 07188 #ifdef BRIDGE_OPTIMIZATION 07189 if (iaxs[fr->callno]->bridgecallno) { 07190 /* If we're in a bridged call, just forward this */ 07191 forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1); 07192 } else { 07193 struct iax_ie_data pingied; 07194 construct_rr(iaxs[fr->callno], &pingied); 07195 /* Send back a pong packet with the original timestamp */ 07196 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07197 } 07198 #else 07199 { 07200 struct iax_ie_data pingied; 07201 construct_rr(iaxs[fr->callno], &pingied); 07202 /* Send back a pong packet with the original timestamp */ 07203 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07204 } 07205 #endif 07206 break; 07207 case IAX_COMMAND_PONG: 07208 #ifdef BRIDGE_OPTIMIZATION 07209 if (iaxs[fr->callno]->bridgecallno) { 07210 /* Forward to the other side of the bridge */ 07211 forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07212 } else { 07213 /* Calculate ping time */ 07214 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07215 } 07216 #else 07217 /* Calculate ping time */ 07218 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07219 #endif 07220 /* save RR info */ 07221 save_rr(fr, &ies); 07222 07223 if (iaxs[fr->callno]->peerpoke) { 07224 peer = iaxs[fr->callno]->peerpoke; 07225 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07226 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07227 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07228 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07229 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07230 } 07231 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07232 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07233 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07234 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07235 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07236 } 07237 } 07238 peer->lastms = iaxs[fr->callno]->pingtime; 07239 if (peer->smoothing && (peer->lastms > -1)) 07240 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07241 else if (peer->smoothing && peer->lastms < 0) 07242 peer->historicms = (0 + peer->historicms) / 2; 07243 else 07244 peer->historicms = iaxs[fr->callno]->pingtime; 07245 07246 if (peer->pokeexpire > -1) 07247 ast_sched_del(sched, peer->pokeexpire); 07248 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07249 iax2_destroy_nolock(fr->callno); 07250 peer->callno = 0; 07251 /* Try again eventually */ 07252 ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms); 07253 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07254 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07255 else 07256 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07257 } 07258 break; 07259 case IAX_COMMAND_LAGRQ: 07260 case IAX_COMMAND_LAGRP: 07261 #ifdef BRIDGE_OPTIMIZATION 07262 if (iaxs[fr->callno]->bridgecallno) { 07263 forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1); 07264 } else { 07265 #endif 07266 f.src = "LAGRQ"; 07267 f.mallocd = 0; 07268 f.offset = 0; 07269 f.samples = 0; 07270 iax_frame_wrap(fr, &f); 07271 if(f.subclass == IAX_COMMAND_LAGRQ) { 07272 /* Received a LAGRQ - echo back a LAGRP */ 07273 fr->af.subclass = IAX_COMMAND_LAGRP; 07274 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07275 } else { 07276 /* Received LAGRP in response to our LAGRQ */ 07277 unsigned int ts; 07278 /* This is a reply we've been given, actually measure the difference */ 07279 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07280 iaxs[fr->callno]->lag = ts - fr->ts; 07281 if (option_debug && iaxdebug) 07282 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07283 ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07284 } 07285 #ifdef BRIDGE_OPTIMIZATION 07286 } 07287 #endif 07288 break; 07289 case IAX_COMMAND_AUTHREQ: 07290 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07291 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>"); 07292 break; 07293 } 07294 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07295 ast_log(LOG_WARNING, 07296 "I don't know how to authenticate %s to %s\n", 07297 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr)); 07298 } 07299 break; 07300 case IAX_COMMAND_AUTHREP: 07301 /* For security, always ack immediately */ 07302 if (delayreject) 07303 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07304 /* Ignore once we've started */ 07305 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07306 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>"); 07307 break; 07308 } 07309 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07310 if (authdebug) 07311 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); 07312 memset(&ied0, 0, sizeof(ied0)); 07313 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07314 break; 07315 } 07316 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07317 /* This might re-enter the IAX code and need the lock */ 07318 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07319 } else 07320 exists = 0; 07321 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07322 if (authdebug) 07323 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); 07324 memset(&ied0, 0, sizeof(ied0)); 07325 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07326 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07327 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07328 } else { 07329 /* Select an appropriate format */ 07330 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07331 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07332 using_prefs = "reqonly"; 07333 } else { 07334 using_prefs = "disabled"; 07335 } 07336 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07337 memset(&pref, 0, sizeof(pref)); 07338 strcpy(caller_pref_buf, "disabled"); 07339 strcpy(host_pref_buf, "disabled"); 07340 } else { 07341 using_prefs = "mine"; 07342 if (ies.codec_prefs) 07343 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07344 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07345 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07346 pref = iaxs[fr->callno]->rprefs; 07347 using_prefs = "caller"; 07348 } else { 07349 pref = iaxs[fr->callno]->prefs; 07350 } 07351 } else /* if no codec_prefs IE do it the old way */ 07352 pref = iaxs[fr->callno]->prefs; 07353 07354 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07355 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07356 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07357 } 07358 if (!format) { 07359 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07360 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); 07361 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07362 } 07363 if (!format) { 07364 if (authdebug) { 07365 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07366 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); 07367 else 07368 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); 07369 } 07370 memset(&ied0, 0, sizeof(ied0)); 07371 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07372 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07373 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07374 } else { 07375 /* Pick one... */ 07376 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07377 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07378 format = 0; 07379 } else { 07380 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07381 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07382 memset(&pref, 0, sizeof(pref)); 07383 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07384 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07385 strcpy(caller_pref_buf,"disabled"); 07386 strcpy(host_pref_buf,"disabled"); 07387 } else { 07388 using_prefs = "mine"; 07389 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07390 /* Do the opposite of what we tried above. */ 07391 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07392 pref = iaxs[fr->callno]->prefs; 07393 } else { 07394 pref = iaxs[fr->callno]->rprefs; 07395 using_prefs = "caller"; 07396 } 07397 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07398 } else /* if no codec_prefs IE do it the old way */ 07399 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07400 } 07401 } 07402 if (!format) { 07403 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07404 if (authdebug) { 07405 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07406 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); 07407 else 07408 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); 07409 } 07410 memset(&ied0, 0, sizeof(ied0)); 07411 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07412 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07413 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07414 } 07415 } 07416 } 07417 if (format) { 07418 /* Authentication received */ 07419 memset(&ied1, 0, sizeof(ied1)); 07420 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07421 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07422 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07423 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07424 if (option_verbose > 2) 07425 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07426 "%srequested format = %s,\n" 07427 "%srequested prefs = %s,\n" 07428 "%sactual format = %s,\n" 07429 "%shost prefs = %s,\n" 07430 "%spriority = %s\n", 07431 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 07432 VERBOSE_PREFIX_4, 07433 ast_getformatname(iaxs[fr->callno]->peerformat), 07434 VERBOSE_PREFIX_4, 07435 caller_pref_buf, 07436 VERBOSE_PREFIX_4, 07437 ast_getformatname(format), 07438 VERBOSE_PREFIX_4, 07439 host_pref_buf, 07440 VERBOSE_PREFIX_4, 07441 using_prefs); 07442 07443 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07444 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07445 iax2_destroy_nolock(fr->callno); 07446 } else { 07447 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07448 /* If this is a TBD call, we're ready but now what... */ 07449 if (option_verbose > 2) 07450 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 07451 } 07452 } 07453 } 07454 break; 07455 case IAX_COMMAND_DIAL: 07456 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07457 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07458 ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten)); 07459 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07460 if (authdebug) 07461 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); 07462 memset(&ied0, 0, sizeof(ied0)); 07463 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07464 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07465 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07466 } else { 07467 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07468 if (option_verbose > 2) 07469 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); 07470 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07471 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07472 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07473 iax2_destroy_nolock(fr->callno); 07474 } 07475 } 07476 break; 07477 case IAX_COMMAND_INVAL: 07478 iaxs[fr->callno]->error = ENOTCONN; 07479 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07480 iax2_destroy_nolock(fr->callno); 07481 if (option_debug) 07482 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07483 break; 07484 case IAX_COMMAND_VNAK: 07485 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07486 /* Force retransmission */ 07487 vnak_retransmit(fr->callno, fr->iseqno); 07488 break; 07489 case IAX_COMMAND_REGREQ: 07490 case IAX_COMMAND_REGREL: 07491 /* For security, always ack immediately */ 07492 if (delayreject) 07493 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07494 if (register_verify(fr->callno, &sin, &ies)) { 07495 /* Send delayed failure */ 07496 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07497 break; 07498 } 07499 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)) { 07500 if (f.subclass == IAX_COMMAND_REGREL) 07501 memset(&sin, 0, sizeof(sin)); 07502 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07503 ast_log(LOG_WARNING, "Registry error\n"); 07504 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07505 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07506 break; 07507 } 07508 registry_authrequest(iaxs[fr->callno]->peer, fr->callno); 07509 break; 07510 case IAX_COMMAND_REGACK: 07511 if (iax2_ack_registry(&ies, &sin, fr->callno)) 07512 ast_log(LOG_WARNING, "Registration failure\n"); 07513 /* Send ack immediately, before we destroy */ 07514 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07515 iax2_destroy_nolock(fr->callno); 07516 break; 07517 case IAX_COMMAND_REGREJ: 07518 if (iaxs[fr->callno]->reg) { 07519 if (authdebug) { 07520 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)); 07521 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>"); 07522 } 07523 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 07524 } 07525 /* Send ack immediately, before we destroy */ 07526 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07527 iax2_destroy_nolock(fr->callno); 07528 break; 07529 case IAX_COMMAND_REGAUTH: 07530 /* Authentication request */ 07531 if (registry_rerequest(&ies, fr->callno, &sin)) { 07532 memset(&ied0, 0, sizeof(ied0)); 07533 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07534 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07535 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07536 } 07537 break; 07538 case IAX_COMMAND_TXREJ: 07539 iaxs[fr->callno]->transferring = 0; 07540 if (option_verbose > 2) 07541 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07542 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 07543 if (iaxs[fr->callno]->bridgecallno) { 07544 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 07545 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 07546 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07547 } 07548 } 07549 break; 07550 case IAX_COMMAND_TXREADY: 07551 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07552 iaxs[fr->callno]->transferring = TRANSFER_READY; 07553 if (option_verbose > 2) 07554 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07555 if (iaxs[fr->callno]->bridgecallno) { 07556 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) { 07557 if (option_verbose > 2) 07558 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07559 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07560 07561 /* They're both ready, now release them. */ 07562 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07563 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 07564 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 07565 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07566 07567 /* Stop doing lag & ping requests */ 07568 stop_stuff(fr->callno); 07569 stop_stuff(iaxs[fr->callno]->bridgecallno); 07570 07571 memset(&ied0, 0, sizeof(ied0)); 07572 memset(&ied1, 0, sizeof(ied1)); 07573 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07574 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07575 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07576 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07577 07578 } 07579 } 07580 } 07581 break; 07582 case IAX_COMMAND_TXREQ: 07583 try_transfer(iaxs[fr->callno], &ies); 07584 break; 07585 case IAX_COMMAND_TXCNT: 07586 if (iaxs[fr->callno]->transferring) 07587 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07588 break; 07589 case IAX_COMMAND_TXREL: 07590 /* Send ack immediately, rather than waiting until we've changed addresses */ 07591 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07592 complete_transfer(fr->callno, &ies); 07593 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 07594 break; 07595 case IAX_COMMAND_DPREP: 07596 complete_dpreply(iaxs[fr->callno], &ies); 07597 break; 07598 case IAX_COMMAND_UNSUPPORT: 07599 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07600 break; 07601 case IAX_COMMAND_FWDOWNL: 07602 /* Firmware download */ 07603 memset(&ied0, 0, sizeof(ied0)); 07604 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07605 if (res < 0) 07606 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07607 else if (res > 0) 07608 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07609 else 07610 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07611 break; 07612 default: 07613 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 07614 memset(&ied0, 0, sizeof(ied0)); 07615 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07616 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07617 } 07618 /* Don't actually pass these frames along */ 07619 if ((f.subclass != IAX_COMMAND_ACK) && 07620 (f.subclass != IAX_COMMAND_TXCNT) && 07621 (f.subclass != IAX_COMMAND_TXACC) && 07622 (f.subclass != IAX_COMMAND_INVAL) && 07623 (f.subclass != IAX_COMMAND_VNAK)) { 07624 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07625 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07626 } 07627 ast_mutex_unlock(&iaxsl[fr->callno]); 07628 return 1; 07629 } 07630 /* Unless this is an ACK or INVAL frame, ack it */ 07631 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07632 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07633 } else if (minivid) { 07634 f.frametype = AST_FRAME_VIDEO; 07635 if (iaxs[fr->callno]->videoformat > 0) 07636 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07637 else { 07638 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07639 iax2_vnak(fr->callno); 07640 ast_mutex_unlock(&iaxsl[fr->callno]); 07641 return 1; 07642 } 07643 f.datalen = res - sizeof(*vh); 07644 if (f.datalen) 07645 f.data = buf + sizeof(*vh); 07646 else 07647 f.data = NULL; 07648 #ifdef IAXTESTS 07649 if (test_resync) { 07650 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); 07651 } else 07652 #endif /* IAXTESTS */ 07653 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); 07654 } else { 07655 /* A mini frame */ 07656 f.frametype = AST_FRAME_VOICE; 07657 if (iaxs[fr->callno]->voiceformat > 0) 07658 f.subclass = iaxs[fr->callno]->voiceformat; 07659 else { 07660 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07661 iax2_vnak(fr->callno); 07662 ast_mutex_unlock(&iaxsl[fr->callno]); 07663 return 1; 07664 } 07665 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07666 if (f.datalen < 0) { 07667 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07668 ast_mutex_unlock(&iaxsl[fr->callno]); 07669 return 1; 07670 } 07671 if (f.datalen) 07672 f.data = buf + sizeof(*mh); 07673 else 07674 f.data = NULL; 07675 #ifdef IAXTESTS 07676 if (test_resync) { 07677 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07678 } else 07679 #endif /* IAXTESTS */ 07680 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07681 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07682 } 07683 /* Don't pass any packets until we're started */ 07684 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07685 ast_mutex_unlock(&iaxsl[fr->callno]); 07686 return 1; 07687 } 07688 /* Common things */ 07689 f.src = "IAX2"; 07690 f.mallocd = 0; 07691 f.offset = 0; 07692 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07693 f.samples = ast_codec_get_samples(&f); 07694 /* We need to byteswap incoming slinear samples from network byte order */ 07695 if (f.subclass == AST_FORMAT_SLINEAR) 07696 ast_frame_byteswap_be(&f); 07697 } else 07698 f.samples = 0; 07699 iax_frame_wrap(fr, &f); 07700 07701 /* If this is our most recent packet, use it as our basis for timestamping */ 07702 if (iaxs[fr->callno]->last < fr->ts) { 07703 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07704 fr->outoforder = 0; 07705 } else { 07706 if (option_debug && iaxdebug) 07707 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); 07708 fr->outoforder = -1; 07709 } 07710 #ifdef BRIDGE_OPTIMIZATION 07711 if (iaxs[fr->callno]->bridgecallno) { 07712 forward_delivery(fr); 07713 } else { 07714 duped_fr = iaxfrdup2(fr); 07715 if (duped_fr) { 07716 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07717 } 07718 } 07719 #else 07720 duped_fr = iaxfrdup2(fr); 07721 if (duped_fr) { 07722 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07723 } 07724 #endif 07725 07726 if (iaxs[fr->callno]->last < fr->ts) { 07727 iaxs[fr->callno]->last = fr->ts; 07728 #if 1 07729 if (option_debug && iaxdebug) 07730 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07731 #endif 07732 } 07733 07734 /* Always run again */ 07735 ast_mutex_unlock(&iaxsl[fr->callno]); 07736 return 1; 07737 }
static void spawn_dp_lookup | ( | int | callno, | |
char * | context, | |||
char * | callednum, | |||
char * | callerid | |||
) | [static] |
Definition at line 6199 of file chan_iax2.c.
References ast_log(), ast_pthread_create, dp_lookup_thread(), LOG_WARNING, malloc, and strdup.
Referenced by socket_read().
06200 { 06201 pthread_t newthread; 06202 struct dpreq_data *dpr; 06203 dpr = malloc(sizeof(struct dpreq_data)); 06204 if (dpr) { 06205 memset(dpr, 0, sizeof(struct dpreq_data)); 06206 dpr->callno = callno; 06207 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06208 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06209 if (callerid) 06210 dpr->callerid = strdup(callerid); 06211 if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) { 06212 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06213 } 06214 } else 06215 ast_log(LOG_WARNING, "Out of memory!\n"); 06216 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8103 of file chan_iax2.c.
References ast_pthread_create, and network_thread().
Referenced by load_module().
08104 { 08105 return ast_pthread_create(&netthreadid, NULL, network_thread, NULL); 08106 }
static int stop_stuff | ( | int | callno | ) | [static] |
Definition at line 5899 of file chan_iax2.c.
References ast_sched_del(), and sched.
Referenced by socket_read().
05900 { 05901 if (iaxs[callno]->lagid > -1) 05902 ast_sched_del(sched, iaxs[callno]->lagid); 05903 iaxs[callno]->lagid = -1; 05904 if (iaxs[callno]->pingid > -1) 05905 ast_sched_del(sched, iaxs[callno]->pingid); 05906 iaxs[callno]->pingid = -1; 05907 if (iaxs[callno]->autoid > -1) 05908 ast_sched_del(sched, iaxs[callno]->autoid); 05909 iaxs[callno]->autoid = -1; 05910 if (iaxs[callno]->initid > -1) 05911 ast_sched_del(sched, iaxs[callno]->initid); 05912 iaxs[callno]->initid = -1; 05913 if (iaxs[callno]->authid > -1) 05914 ast_sched_del(sched, iaxs[callno]->authid); 05915 iaxs[callno]->authid = -1; 05916 #ifdef NEWJB 05917 if (iaxs[callno]->jbid > -1) 05918 ast_sched_del(sched, iaxs[callno]->jbid); 05919 iaxs[callno]->jbid = -1; 05920 #endif 05921 return 0; 05922 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6072 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, ast_peer_list::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, peerl, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06073 { 06074 char buf[1024]; 06075 int res; 06076 char iabuf[INET_ADDRSTRLEN]; 06077 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06078 int processed = 0; 06079 int totalcalls = 0; 06080 #ifdef ZT_TIMERACK 06081 int x = 1; 06082 #endif 06083 struct timeval now; 06084 if (iaxtrunkdebug) 06085 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06086 gettimeofday(&now, NULL); 06087 if (events & AST_IO_PRI) { 06088 #ifdef ZT_TIMERACK 06089 /* Great, this is a timing interface, just call the ioctl */ 06090 if (ioctl(fd, ZT_TIMERACK, &x)) 06091 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06092 res = 0; 06093 #endif 06094 } else { 06095 /* Read and ignore from the pseudo channel for timing */ 06096 res = read(fd, buf, sizeof(buf)); 06097 if (res < 1) { 06098 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06099 ast_mutex_unlock(&peerl.lock); 06100 return 1; 06101 } 06102 } 06103 /* For each peer that supports trunking... */ 06104 ast_mutex_lock(&tpeerlock); 06105 tpeer = tpeers; 06106 while(tpeer) { 06107 processed++; 06108 res = 0; 06109 ast_mutex_lock(&tpeer->lock); 06110 /* We can drop a single tpeer per pass. That makes all this logic 06111 substantially easier */ 06112 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06113 /* Take it out of the list, but don't free it yet, because it 06114 could be in use */ 06115 if (prev) 06116 prev->next = tpeer->next; 06117 else 06118 tpeers = tpeer->next; 06119 drop = tpeer; 06120 } else { 06121 res = send_trunk(tpeer, &now); 06122 if (iaxtrunkdebug) 06123 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); 06124 } 06125 totalcalls += res; 06126 res = 0; 06127 ast_mutex_unlock(&tpeer->lock); 06128 prev = tpeer; 06129 tpeer = tpeer->next; 06130 } 06131 ast_mutex_unlock(&tpeerlock); 06132 if (drop) { 06133 ast_mutex_lock(&drop->lock); 06134 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06135 because by the time they could get tpeerlock, we've already grabbed it */ 06136 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)); 06137 free(drop->trunkdata); 06138 ast_mutex_unlock(&drop->lock); 06139 ast_mutex_destroy(&drop->lock); 06140 free(drop); 06141 06142 } 06143 if (iaxtrunkdebug) 06144 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06145 iaxtrunkdebug =0; 06146 return 1; 06147 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1486 of file chan_iax2.c.
References ast_log(), iax_frame::data, iax_frame::datalen, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01487 { 01488 int res; 01489 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01490 sizeof(*sin)); 01491 if (res < 0) { 01492 if (option_debug) 01493 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01494 handle_error(); 01495 } else 01496 res = 0; 01497 return res; 01498 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1168 of file chan_iax2.c.
References ast_log(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, malloc, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01169 { 01170 struct stat stbuf; 01171 struct iax_firmware *cur; 01172 int ifd; 01173 int fd; 01174 int res; 01175 01176 struct ast_iax2_firmware_header *fwh, fwh2; 01177 struct MD5Context md5; 01178 unsigned char sum[16]; 01179 unsigned char buf[1024]; 01180 int len, chunk; 01181 char *s2; 01182 char *last; 01183 s2 = alloca(strlen(s) + 100); 01184 if (!s2) { 01185 ast_log(LOG_WARNING, "Alloca failed!\n"); 01186 return -1; 01187 } 01188 last = strrchr(s, '/'); 01189 if (last) 01190 last++; 01191 else 01192 last = s; 01193 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand()); 01194 res = stat(s, &stbuf); 01195 if (res < 0) { 01196 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01197 return -1; 01198 } 01199 /* Make sure it's not a directory */ 01200 if (S_ISDIR(stbuf.st_mode)) 01201 return -1; 01202 ifd = open(s, O_RDONLY); 01203 if (ifd < 0) { 01204 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01205 return -1; 01206 } 01207 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01208 if (fd < 0) { 01209 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01210 close(ifd); 01211 return -1; 01212 } 01213 /* Unlink our newly created file */ 01214 unlink(s2); 01215 01216 /* Now copy the firmware into it */ 01217 len = stbuf.st_size; 01218 while(len) { 01219 chunk = len; 01220 if (chunk > sizeof(buf)) 01221 chunk = sizeof(buf); 01222 res = read(ifd, buf, chunk); 01223 if (res != chunk) { 01224 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01225 close(ifd); 01226 close(fd); 01227 return -1; 01228 } 01229 res = write(fd, buf, chunk); 01230 if (res != chunk) { 01231 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01232 close(ifd); 01233 close(fd); 01234 return -1; 01235 } 01236 len -= chunk; 01237 } 01238 close(ifd); 01239 /* Return to the beginning */ 01240 lseek(fd, 0, SEEK_SET); 01241 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01242 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01243 close(fd); 01244 return -1; 01245 } 01246 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01247 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01248 close(fd); 01249 return -1; 01250 } 01251 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01252 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01253 close(fd); 01254 return -1; 01255 } 01256 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01257 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01258 close(fd); 01259 return -1; 01260 } 01261 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01262 if (!fwh) { 01263 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01264 close(fd); 01265 return -1; 01266 } 01267 MD5Init(&md5); 01268 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01269 MD5Final(sum, &md5); 01270 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01271 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01272 munmap(fwh, stbuf.st_size); 01273 close(fd); 01274 return -1; 01275 } 01276 cur = waresl.wares; 01277 while(cur) { 01278 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01279 /* Found a candidate */ 01280 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01281 /* The version we have on loaded is older, load this one instead */ 01282 break; 01283 /* This version is no newer than what we have. Don't worry about it. 01284 We'll consider it a proper load anyhow though */ 01285 munmap(fwh, stbuf.st_size); 01286 close(fd); 01287 return 0; 01288 } 01289 cur = cur->next; 01290 } 01291 if (!cur) { 01292 /* Allocate a new one and link it */ 01293 cur = malloc(sizeof(struct iax_firmware)); 01294 if (cur) { 01295 memset(cur, 0, sizeof(struct iax_firmware)); 01296 cur->fd = -1; 01297 cur->next = waresl.wares; 01298 waresl.wares = cur; 01299 } 01300 } 01301 if (cur) { 01302 if (cur->fwh) { 01303 munmap(cur->fwh, cur->mmaplen); 01304 } 01305 if (cur->fd > -1) 01306 close(cur->fd); 01307 cur->fwh = fwh; 01308 cur->fd = fd; 01309 cur->mmaplen = stbuf.st_size; 01310 cur->dead = 0; 01311 } 01312 return 0; 01313 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5370 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_read().
05371 { 05372 int newcall = 0; 05373 char newip[256]; 05374 struct iax_ie_data ied; 05375 struct sockaddr_in new; 05376 05377 05378 memset(&ied, 0, sizeof(ied)); 05379 if (ies->apparent_addr) 05380 bcopy(ies->apparent_addr, &new, sizeof(new)); 05381 if (ies->callno) 05382 newcall = ies->callno; 05383 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05384 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05385 return -1; 05386 } 05387 pvt->transfercallno = newcall; 05388 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05389 inet_aton(newip, &pvt->transfer.sin_addr); 05390 pvt->transfer.sin_family = AF_INET; 05391 pvt->transferring = TRANSFER_BEGIN; 05392 pvt->transferid = ies->transferid; 05393 if (ies->transferid) 05394 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05395 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05396 return 0; 05397 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 846 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_read().
00847 { 00848 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 00849 if (csub & IAX_FLAG_SC_LOG) { 00850 /* special case for 'compressed' -1 */ 00851 if (csub == 0xff) 00852 return -1; 00853 else 00854 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 00855 } 00856 else 00857 return csub; 00858 }
int unload_module | ( | void | ) |
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 9645 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.
09646 { 09647 ast_mutex_destroy(&iaxq.lock); 09648 ast_mutex_destroy(&userl.lock); 09649 ast_mutex_destroy(&peerl.lock); 09650 ast_mutex_destroy(&waresl.lock); 09651 ast_custom_function_unregister(&iaxpeer_function); 09652 return __unload_module(); 09653 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3192 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03193 { 03194 ast_mutex_unlock(&iaxsl[callno1]); 03195 ast_mutex_unlock(&iaxsl[callno0]); 03196 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2160 of file chan_iax2.c.
References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02161 { 02162 int x; 02163 02164 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02165 x = fr->ts - iaxs[fr->callno]->last; 02166 if (x < -50000) { 02167 /* Sudden big jump backwards in timestamp: 02168 What likely happened here is that miniframe timestamp has circled but we haven't 02169 gotten the update from the main packet. We'll just pretend that we did, and 02170 update the timestamp appropriately. */ 02171 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02172 if (option_debug && iaxdebug) 02173 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02174 } 02175 if (x > 50000) { 02176 /* Sudden apparent big jump forwards in timestamp: 02177 What's likely happened is this is an old miniframe belonging to the previous 02178 top-16-bit timestamp that has turned up out of order. 02179 Adjust the timestamp appropriately. */ 02180 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02181 if (option_debug && iaxdebug) 02182 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02183 } 02184 } 02185 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2190 of file chan_iax2.c.
References ast_sched_add(), ast_sched_del(), get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by get_from_jb().
02190 { 02191 int when; 02192 02193 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02194 02195 when = jb_next(pvt->jb) - when; 02196 02197 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02198 02199 if(when <= 0) { 02200 /* XXX should really just empty until when > 0.. */ 02201 when = 1; 02202 } 02203 02204 pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt); 02205 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 995 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno().
00996 { 00997 int max = 1; 00998 int x; 00999 /* XXX Prolly don't need locks here XXX */ 01000 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01001 if (iaxs[x]) 01002 max = x + 1; 01003 } 01004 maxnontrunkcall = max; 01005 if (option_debug && iaxdebug) 01006 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01007 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 981 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy().
00982 { 00983 int max = TRUNK_CALL_START; 00984 int x; 00985 /* XXX Prolly don't need locks here XXX */ 00986 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 00987 if (iaxs[x]) 00988 max = x + 1; 00989 } 00990 maxtrunkcall = max; 00991 if (option_debug && iaxdebug) 00992 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 00993 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1724 of file chan_iax2.c.
References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno.
Referenced by attempt_transmit().
01725 { 01726 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 01727 struct ast_iax2_full_hdr *fh = f->data; 01728 /* Mark this as a retransmission */ 01729 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 01730 /* Update iseqno */ 01731 f->iseqno = iaxs[f->callno]->iseqno; 01732 fh->iseqno = f->iseqno; 01733 return 0; 01734 }
static int update_registry | ( | char * | name, | |
struct sockaddr_in * | sin, | |||
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5720 of file chan_iax2.c.
References iax2_peer::addr, ast_app_has_voicemail(), ast_app_messagecount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_peer(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_MESSAGEDETAIL, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), iax2_peer::name, option_verbose, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_read().
05721 { 05722 /* Called from IAX thread only, with proper iaxsl lock */ 05723 struct iax_ie_data ied; 05724 struct iax2_peer *p; 05725 int msgcount; 05726 char data[80]; 05727 char iabuf[INET_ADDRSTRLEN]; 05728 int version; 05729 05730 memset(&ied, 0, sizeof(ied)); 05731 05732 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05733 if (!(p = find_peer(name, 1))) { 05734 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05735 return -1; 05736 } 05737 05738 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 05739 if (sin->sin_addr.s_addr) { 05740 time_t nowtime; 05741 time(&nowtime); 05742 realtime_update_peer(name, sin, nowtime); 05743 } else 05744 realtime_update_peer(name, sin, 0); 05745 } 05746 if (inaddrcmp(&p->addr, sin)) { 05747 if (iax2_regfunk) 05748 iax2_regfunk(p->name, 1); 05749 /* Stash the IP address from which they registered */ 05750 memcpy(&p->addr, sin, sizeof(p->addr)); 05751 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05752 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05753 ast_db_put("IAX/Registry", p->name, data); 05754 if (option_verbose > 2) 05755 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05756 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 05757 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05758 register_peer_exten(p, 1); 05759 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05760 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05761 if (option_verbose > 2) 05762 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05763 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05764 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05765 register_peer_exten(p, 0); 05766 ast_db_del("IAX/Registry", p->name); 05767 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05768 } 05769 /* Update the host */ 05770 /* Verify that the host is really there */ 05771 iax2_poke_peer(p, callno); 05772 } 05773 /* Store socket fd */ 05774 p->sockfd = fd; 05775 /* Setup the expiry */ 05776 if (p->expire > -1) 05777 ast_sched_del(sched, p->expire); 05778 /* treat an unspecified refresh interval as the minimum */ 05779 if (!refresh) 05780 refresh = min_reg_expire; 05781 if (refresh > max_reg_expire) { 05782 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05783 p->name, max_reg_expire, refresh); 05784 p->expiry = max_reg_expire; 05785 } else if (refresh < min_reg_expire) { 05786 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05787 p->name, min_reg_expire, refresh); 05788 p->expiry = min_reg_expire; 05789 } else { 05790 p->expiry = refresh; 05791 } 05792 if (p->expiry && sin->sin_addr.s_addr) 05793 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p); 05794 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05795 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05796 if (sin->sin_addr.s_addr) { 05797 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05798 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05799 if (!ast_strlen_zero(p->mailbox)) { 05800 if (ast_test_flag(p, IAX_MESSAGEDETAIL)) { 05801 int new, old; 05802 ast_app_messagecount(p->mailbox, &new, &old); 05803 if (new > 255) 05804 new = 255; 05805 if (old > 255) 05806 old = 255; 05807 msgcount = (old << 8) | new; 05808 } else { 05809 msgcount = ast_app_has_voicemail(p->mailbox, NULL); 05810 if (msgcount) 05811 msgcount = 65535; 05812 } 05813 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05814 } 05815 if (ast_test_flag(p, IAX_HASCALLERID)) { 05816 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05817 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05818 } 05819 } 05820 version = iax_check_version(devtype); 05821 if (version) 05822 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05823 if (ast_test_flag(p, IAX_TEMPONLY)) 05824 destroy_peer(p); 05825 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05826 }
int usecount | ( | void | ) |
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 9754 of file chan_iax2.c.
09755 { 09756 return usecnt; 09757 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 5997 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::oseqno, and send_packet().
Referenced by socket_read().
05998 { 05999 struct iax_frame *f; 06000 ast_mutex_lock(&iaxq.lock); 06001 f = iaxq.head; 06002 while(f) { 06003 /* Send a copy immediately */ 06004 if ((f->callno == callno) && iaxs[f->callno] && 06005 (f->oseqno >= last)) { 06006 send_packet(f); 06007 } 06008 f = f->next; 06009 } 06010 ast_mutex_unlock(&iaxq.lock); 06011 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
int amaflags = 0 [static] |
int authdebug = 1 [static] |
int autokill = 0 [static] |
Definition at line 164 of file chan_iax2.c.
const char channeltype[] = "IAX2" [static] |
Definition at line 143 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 145 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 jb debug\n" " Enables jitterbuffer debugging information\n"
Definition at line 9544 of file chan_iax2.c.
char debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 trunk debug\n" " Requests current status of IAX trunking\n"
Definition at line 9536 of file chan_iax2.c.
char debug_usage[] [static] |
Initial value:
"Usage: iax2 debug\n" " Enables dumping of IAX packets for debugging purposes\n"
Definition at line 9528 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 179 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 227 of file chan_iax2.c.
const char desc[] = "Inter Asterisk eXchange (Ver 2)" [static] |
Definition at line 141 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
int global_rtautoclear = 120 [static] |
Definition at line 272 of file chan_iax2.c.
Referenced by realtime_peer(), reload_config(), set_config(), and sip_show_settings().
struct ast_flags globalflags = { 0 } [static] |
Definition at line 230 of file chan_iax2.c.
Referenced by build_peer(), build_user(), expire_registry(), find_callno(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), notify_new_message(), populate_defaults(), realtime_peer(), realtime_user(), send_trunk(), sendmail(), set_config(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 209 of file chan_iax2.c.
struct ast_cli_entry iax2_cli[] [static] |
int iax2_dropcount = DEFAULT_DROP [static] |
Definition at line 211 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 228 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(char *username, int onoff) = NULL |
Definition at line 184 of file chan_iax2.c.
Referenced by expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 9490 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 762 of file chan_iax2.c.
Referenced by __unload_module(), ast_iax2_new(), and load_module().
char iax2_test_losspct_usage[] [static] |
Initial value:
"Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n"
Definition at line 9552 of file chan_iax2.c.
int iaxcompat = 0 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 213 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 167 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 169 of file chan_iax2.c.
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 726 of file chan_iax2.c.
Referenced by __do_deliver(), attempt_transmit(), find_callno(), get_from_jb(), iax2_destroy(), iax2_predestroy(), iax2_queue_frame(), iax2_set_jitter(), iax_showframe(), make_trunk(), schedule_delivery(), send_lagrq(), send_packet(), send_ping(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), and update_packet().
ast_mutex_t iaxsl[IAX_MAX_CALLS] [static] |
Definition at line 727 of file chan_iax2.c.
Referenced by ast_cli_netstats(), ast_iax2_new(), attempt_transmit(), auth_fail(), auth_reject(), auto_congest(), auto_hangup(), cache_get_callno_locked(), delete_users(), destroy_peer(), dp_lookup(), find_cache(), get_from_jb(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_nolock(), iax2_fixup(), iax2_hangup(), iax2_poke_peer(), iax2_predestroy(), iax2_predestroy_nolock(), iax2_provision(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), register_verify(), send_command_locked(), socket_read(), and unlock_both().
int iaxtrunkdebug = 0 [static] |
Definition at line 215 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 206 of file chan_iax2.c.
char jitter_usage[] [static] |
Definition at line 1855 of file chan_iax2.c.
int jittershrinkrate = 2 [static] |
Definition at line 161 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 153 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 147 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
int max_jitter_buffer = MAX_JITTER_BUFFER [static] |
int max_reg_expire [static] |
Definition at line 174 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 151 of file chan_iax2.c.
int maxauthreq = 0 [static] |
Definition at line 150 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 156 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 159 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 154 of file chan_iax2.c.
int min_jitter_buffer = MIN_JITTER_BUFFER [static] |
int min_reg_expire [static] |
Definition at line 173 of file chan_iax2.c.
struct ast_netsock_list* netsock [static] |
Definition at line 178 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 no jb debug\n" " Disables jitterbuffer debugging information\n"
Definition at line 9548 of file chan_iax2.c.
char no_debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 no trunk debug\n" " Requests current status of IAX trunking\n"
Definition at line 9540 of file chan_iax2.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: iax2 no debug\n" " Disables dumping of IAX packets for debugging purposes\n"
Definition at line 9532 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
char* pdescrip [static] |
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 7828 of file chan_iax2.c.
Referenced by load_module().
struct ast_peer_list peerl [static] |
int ping_time = 20 [static] |
Definition at line 152 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 139 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), reload_config(), set_config(), sip_alloc(), sip_show_settings(), and temp_peer().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 9486 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
char regcontext[AST_MAX_CONTEXT] = "" [static] |
struct iax2_registry* registrations [static] |
Definition at line 412 of file chan_iax2.c.
Referenced by delete_users(), iax2_register(), iax2_show_registry(), and load_module().
int resyncthreshold = 1000 [static] |
Definition at line 158 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 207 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 9478 of file chan_iax2.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: iax2 show channels\n" " Lists all currently active IAX channels.\n"
Definition at line 9506 of file chan_iax2.c.
char show_firmware_usage[] [static] |
Initial value:
"Usage: iax2 show firmware\n" " Lists all known IAX firmware images.\n"
Definition at line 9520 of file chan_iax2.c.
char show_netstats_usage[] [static] |
Initial value:
"Usage: iax2 show netstats\n" " Lists network status for all currently active IAX channels.\n"
Definition at line 9510 of file chan_iax2.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: iax show peer <name>\n" " Display details on specific IAX peer\n"
Definition at line 9482 of file chan_iax2.c.
char show_peers_usage[] [static] |
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 9514 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 9494 of file chan_iax2.c.
char show_reg_usage[] [static] |
Initial value:
"Usage: iax2 show registry\n" " Lists all registration requests and status.\n"
Definition at line 9524 of file chan_iax2.c.
char show_stats_usage[] [static] |
Initial value:
"Usage: iax show stats\n" " Display statistics on IAX channel driver.\n"
Definition at line 9474 of file chan_iax2.c.
char show_users_usage[] [static] |
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 9501 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 142 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 217 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 176 of file chan_iax2.c.
int tos = 0 [static] |
Definition at line 171 of file chan_iax2.c.
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 162 of file chan_iax2.c.
int usecnt [static] |
Definition at line 181 of file chan_iax2.c.
struct ast_user_list userl [static] |
struct ast_firmware_list waresl [static] |
Referenced by iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), try_firmware(), and unload_module().