#include "asterisk.h"
#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/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 "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.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 | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
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_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#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 %-6.6s %-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 %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#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 | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#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), IAX_STATE_UNCHANGED = (1 << 3) } |
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_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_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25) } |
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, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
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 void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
Create new call, interface with the PBX core. | |
static | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (sched_lock) | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const 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, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
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, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
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) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const 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 | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const 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 (const 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 sockfd) |
static struct iax2_thread * | find_idle_thread (void) |
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 int | 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 (const void *p) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
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) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
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 (const 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, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
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) |
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, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
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 (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
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 (const char *line, const 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_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
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_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
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 *dest, const char *text, int ispdu) |
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[]) |
Show one peer in detail. | |
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_threads (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, int mediaonly) |
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 | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
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, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const 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, 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_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static void | poke_all_peers (void) |
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, struct sockaddr_in *sin) |
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 (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
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 (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | 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) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
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 (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ast_cli_entry | cli_iax2 [] |
static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
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 struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(* | iax2_regfunk )(const 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 | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
struct 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 | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static struct timeval | lastused [IAX_MAX_CALLS] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
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 struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ao2_container * | peers |
static int | ping_time = 21 |
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 int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
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_threads_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 unsigned int | tos = 0 |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 667 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 663 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 677 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 665 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 669 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 671 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 673 of file chan_iax2.c.
Referenced by iax2_dprequest(), iax2_show_cache(), and socket_process().
#define CACHE_FLAG_UNKNOWN (1 << 6) |
Timeout
Definition at line 675 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 126 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 114 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 137 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 132 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_MAX_THREAD_COUNT 100 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 202 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 128 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 446 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 %-6.6s %-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 %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 142 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 185 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 193 of file chan_iax2.c.
Referenced by set_config().
#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 & \ ~AST_FORMAT_G722)
Definition at line 187 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
Definition at line 701 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 704 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 117 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 443 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 1 |
This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.
Definition at line 649 of file chan_iax2.c.
Referenced by load_module(), and set_config().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 449 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 447 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 131 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 444 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 1241 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 PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 125 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().
#define SCHED_MULTITHREADED |
Definition at line 110 of file chan_iax2.c.
Definition at line 967 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START 0x4000 |
Definition at line 135 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 |
Definition at line 452 of file chan_iax2.c.
anonymous enum |
Definition at line 238 of file chan_iax2.c.
00238 { 00239 IAX_STATE_STARTED = (1 << 0), 00240 IAX_STATE_AUTHENTICATED = (1 << 1), 00241 IAX_STATE_TBD = (1 << 2), 00242 IAX_STATE_UNCHANGED = (1 << 3), 00243 } iax2_state;
anonymous enum |
Definition at line 250 of file chan_iax2.c.
00250 { 00251 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00252 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00253 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00254 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00255 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00256 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00257 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00258 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00259 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00260 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00261 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00262 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00263 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00264 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00265 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00266 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00267 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00268 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00269 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00270 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00271 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00272 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00273 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00274 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00275 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00276 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00277 response, so that we've achieved a three-way handshake with 00278 them before sending voice or anything else*/ 00279 } 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 398 of file chan_iax2.c.
00398 { 00399 REG_STATE_UNREGISTERED = 0, 00400 REG_STATE_REGSENT, 00401 REG_STATE_AUTHSENT, 00402 REG_STATE_REGISTERED, 00403 REG_STATE_REJECTED, 00404 REG_STATE_TIMEOUT, 00405 REG_STATE_NOAUTH 00406 };
enum iax_transfer_state |
TRANSFER_NONE | |
TRANSFER_BEGIN | |
TRANSFER_READY | |
TRANSFER_RELEASED | |
TRANSFER_PASSTHROUGH | |
TRANSFER_MBEGIN | |
TRANSFER_MREADY | |
TRANSFER_MRELEASED | |
TRANSFER_MPASSTHROUGH | |
TRANSFER_MEDIA | |
TRANSFER_MEDIAPASS |
Definition at line 408 of file chan_iax2.c.
00408 { 00409 TRANSFER_NONE = 0, 00410 TRANSFER_BEGIN, 00411 TRANSFER_READY, 00412 TRANSFER_RELEASED, 00413 TRANSFER_PASSTHROUGH, 00414 TRANSFER_MBEGIN, 00415 TRANSFER_MREADY, 00416 TRANSFER_MRELEASED, 00417 TRANSFER_MPASSTHROUGH, 00418 TRANSFER_MEDIA, 00419 TRANSFER_MEDIAPASS 00420 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2042 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, iax2_registry::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02043 { 02044 /* Attempt to transmit the frame to the remote peer... 02045 Called without iaxsl held. */ 02046 struct iax_frame *f = (struct iax_frame *)data; 02047 int freeme=0; 02048 int callno = f->callno; 02049 /* Make sure this call is still active */ 02050 if (callno) 02051 ast_mutex_lock(&iaxsl[callno]); 02052 if (callno && iaxs[callno]) { 02053 if ((f->retries < 0) /* Already ACK'd */ || 02054 (f->retries >= max_retries) /* Too many attempts */) { 02055 /* Record an error if we've transmitted too many times */ 02056 if (f->retries >= max_retries) { 02057 if (f->transfer) { 02058 /* Transfer timeout */ 02059 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02060 } else if (f->final) { 02061 if (f->final) 02062 iax2_destroy(callno); 02063 } else { 02064 if (iaxs[callno]->owner) 02065 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); 02066 iaxs[callno]->error = ETIMEDOUT; 02067 if (iaxs[callno]->owner) { 02068 struct ast_frame fr = { 0, }; 02069 /* Hangup the fd */ 02070 fr.frametype = AST_FRAME_CONTROL; 02071 fr.subclass = AST_CONTROL_HANGUP; 02072 iax2_queue_frame(callno, &fr); // XXX 02073 /* Remember, owner could disappear */ 02074 if (iaxs[callno] && iaxs[callno]->owner) 02075 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02076 } else { 02077 if (iaxs[callno]->reg) { 02078 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02079 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02080 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02081 } 02082 iax2_destroy(callno); 02083 } 02084 } 02085 02086 } 02087 freeme++; 02088 } else { 02089 /* Update it if it needs it */ 02090 update_packet(f); 02091 /* Attempt transmission */ 02092 send_packet(f); 02093 f->retries++; 02094 /* Try again later after 10 times as long */ 02095 f->retrytime *= 10; 02096 if (f->retrytime > MAX_RETRY_TIME) 02097 f->retrytime = MAX_RETRY_TIME; 02098 /* Transfer messages max out at one second */ 02099 if (f->transfer && (f->retrytime > 1000)) 02100 f->retrytime = 1000; 02101 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02102 } 02103 } else { 02104 /* Make sure it gets freed */ 02105 f->retries = -1; 02106 freeme++; 02107 } 02108 if (callno) 02109 ast_mutex_unlock(&iaxsl[callno]); 02110 /* Do not try again */ 02111 if (freeme) { 02112 /* Don't attempt delivery, just remove it from the queue */ 02113 AST_LIST_LOCK(&iaxq.queue); 02114 AST_LIST_REMOVE(&iaxq.queue, f, list); 02115 iaxq.count--; 02116 AST_LIST_UNLOCK(&iaxq.queue); 02117 f->retrans = -1; 02118 /* Free the IAX frame */ 02119 iax2_frame_free(f); 02120 } 02121 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6169 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_ie_data::buf, iax2_registry::callno, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
06170 { 06171 /* Called from IAX thread only, without iaxs lock */ 06172 int callno = (int)(long)(nothing); 06173 struct iax_ie_data ied; 06174 ast_mutex_lock(&iaxsl[callno]); 06175 if (iaxs[callno]) { 06176 memset(&ied, 0, sizeof(ied)); 06177 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06178 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06179 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06180 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06181 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06182 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06183 } 06184 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06185 } 06186 ast_mutex_unlock(&iaxsl[callno]); 06187 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 2986 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
02987 { 02988 int callno = PTR_TO_CALLNO(nothing); 02989 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02990 ast_mutex_lock(&iaxsl[callno]); 02991 if (iaxs[callno]) { 02992 iaxs[callno]->initid = -1; 02993 iax2_queue_frame(callno, &f); 02994 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02995 } 02996 ast_mutex_unlock(&iaxsl[callno]); 02997 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6219 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
06220 { 06221 /* Called from IAX thread only, without iaxs lock */ 06222 int callno = (int)(long)(nothing); 06223 struct iax_ie_data ied; 06224 ast_mutex_lock(&iaxsl[callno]); 06225 if (iaxs[callno]) { 06226 memset(&ied, 0, sizeof(ied)); 06227 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06228 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06229 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06230 } 06231 ast_mutex_unlock(&iaxsl[callno]); 06232 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 1801 of file chan_iax2.c.
References iax_frame::af, ast_test_flag, iax_frame::callno, ast_frame::has_timing_info, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
01802 { 01803 /* Just deliver the packet by using queueing. This is called by 01804 the IAX thread with the iaxsl lock held. */ 01805 struct iax_frame *fr = data; 01806 fr->retrans = -1; 01807 fr->af.has_timing_info = 0; 01808 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01809 iax2_queue_frame(fr->callno, &fr->af); 01810 /* Free our iax frame */ 01811 iax2_frame_free(fr); 01812 /* And don't run again */ 01813 return 0; 01814 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5857 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, LOG_DEBUG, manager_event(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
05858 { 05859 struct iax2_peer *peer = (struct iax2_peer *) data; 05860 05861 if (!peer) 05862 return; 05863 05864 peer->expire = -1; 05865 05866 if (option_debug) 05867 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 05868 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05869 realtime_update_peer(peer->name, &peer->addr, 0); 05870 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05871 /* Reset the address */ 05872 memset(&peer->addr, 0, sizeof(peer->addr)); 05873 /* Reset expiry value */ 05874 peer->expiry = min_reg_expire; 05875 if (!ast_test_flag(peer, IAX_TEMPONLY)) 05876 ast_db_del("IAX/Registry", peer->name); 05877 register_peer_exten(peer, 0); 05878 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 05879 if (iax2_regfunk) 05880 iax2_regfunk(peer->name, 0); 05881 05882 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 05883 unlink_peer(peer); 05884 05885 peer_unref(peer); 05886 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2439 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(), iax2_registry::callno, jb_frame::data, 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, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
02440 { 02441 int callno = PTR_TO_CALLNO(p); 02442 struct chan_iax2_pvt *pvt = NULL; 02443 struct iax_frame *fr; 02444 jb_frame frame; 02445 int ret; 02446 long now; 02447 long next; 02448 struct timeval tv; 02449 02450 /* Make sure we have a valid private structure before going on */ 02451 ast_mutex_lock(&iaxsl[callno]); 02452 pvt = iaxs[callno]; 02453 if (!pvt) { 02454 /* No go! */ 02455 ast_mutex_unlock(&iaxsl[callno]); 02456 return; 02457 } 02458 02459 pvt->jbid = -1; 02460 02461 gettimeofday(&tv,NULL); 02462 /* round up a millisecond since ast_sched_runq does; */ 02463 /* prevents us from spinning while waiting for our now */ 02464 /* to catch up with runq's now */ 02465 tv.tv_usec += 1000; 02466 02467 now = ast_tvdiff_ms(tv, pvt->rxcore); 02468 02469 if(now >= (next = jb_next(pvt->jb))) { 02470 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02471 switch(ret) { 02472 case JB_OK: 02473 fr = frame.data; 02474 __do_deliver(fr); 02475 /* __do_deliver() can cause the call to disappear */ 02476 pvt = iaxs[callno]; 02477 break; 02478 case JB_INTERP: 02479 { 02480 struct ast_frame af = { 0, }; 02481 02482 /* create an interpolation frame */ 02483 af.frametype = AST_FRAME_VOICE; 02484 af.subclass = pvt->voiceformat; 02485 af.samples = frame.ms * 8; 02486 af.src = "IAX2 JB interpolation"; 02487 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02488 af.offset = AST_FRIENDLY_OFFSET; 02489 02490 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02491 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02492 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02493 iax2_queue_frame(callno, &af); 02494 /* iax2_queue_frame() could cause the call to disappear */ 02495 pvt = iaxs[callno]; 02496 } 02497 } 02498 break; 02499 case JB_DROP: 02500 iax2_frame_free(frame.data); 02501 break; 02502 case JB_NOFRAME: 02503 case JB_EMPTY: 02504 /* do nothing */ 02505 break; 02506 default: 02507 /* shouldn't happen */ 02508 break; 02509 } 02510 } 02511 if (pvt) 02512 update_jbsched(pvt); 02513 ast_mutex_unlock(&iaxsl[callno]); 02514 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5555 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05556 { 05557 struct iax2_registry *reg = (struct iax2_registry *)data; 05558 reg->expire = -1; 05559 iax2_do_register(reg); 05560 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8595 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
08596 { 08597 struct iax2_peer *peer = (struct iax2_peer *)data; 08598 if (peer->lastms > -1) { 08599 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08600 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08601 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08602 } 08603 if (peer->callno > 0) { 08604 ast_mutex_lock(&iaxsl[peer->callno]); 08605 iax2_destroy(peer->callno); 08606 ast_mutex_unlock(&iaxsl[peer->callno]); 08607 } 08608 peer->callno = 0; 08609 peer->lastms = -1; 08610 /* Try again quickly */ 08611 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08612 if (peer->pokeexpire == -1) 08613 peer_unref(peer); 08614 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6283 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06284 { 06285 struct iax2_peer *peer = (struct iax2_peer *)data; 06286 iax2_poke_peer(peer, 0); 06287 peer_unref(peer); 06288 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4345 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04346 { 04347 regex_t regexbuf; 04348 int havepattern = 0; 04349 int total_peers = 0; 04350 int online_peers = 0; 04351 int offline_peers = 0; 04352 int unmonitored_peers = 0; 04353 struct ao2_iterator i; 04354 04355 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04356 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04357 04358 struct iax2_peer *peer = NULL; 04359 char name[256]; 04360 int registeredonly=0; 04361 char *term = manager ? "\r\n" : "\n"; 04362 04363 switch (argc) { 04364 case 6: 04365 if (!strcasecmp(argv[3], "registered")) 04366 registeredonly = 1; 04367 else 04368 return RESULT_SHOWUSAGE; 04369 if (!strcasecmp(argv[4], "like")) { 04370 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04371 return RESULT_SHOWUSAGE; 04372 havepattern = 1; 04373 } else 04374 return RESULT_SHOWUSAGE; 04375 break; 04376 case 5: 04377 if (!strcasecmp(argv[3], "like")) { 04378 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04379 return RESULT_SHOWUSAGE; 04380 havepattern = 1; 04381 } else 04382 return RESULT_SHOWUSAGE; 04383 break; 04384 case 4: 04385 if (!strcasecmp(argv[3], "registered")) 04386 registeredonly = 1; 04387 else 04388 return RESULT_SHOWUSAGE; 04389 break; 04390 case 3: 04391 break; 04392 default: 04393 return RESULT_SHOWUSAGE; 04394 } 04395 04396 04397 if (s) 04398 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04399 else 04400 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04401 04402 i = ao2_iterator_init(peers, 0); 04403 for (peer = ao2_iterator_next(&i); peer; 04404 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04405 char nm[20]; 04406 char status[20]; 04407 char srch[2000]; 04408 int retstatus; 04409 04410 if (registeredonly && !peer->addr.sin_addr.s_addr) 04411 continue; 04412 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04413 continue; 04414 04415 if (!ast_strlen_zero(peer->username)) 04416 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04417 else 04418 ast_copy_string(name, peer->name, sizeof(name)); 04419 04420 retstatus = peer_status(peer, status, sizeof(status)); 04421 if (retstatus > 0) 04422 online_peers++; 04423 else if (!retstatus) 04424 offline_peers++; 04425 else 04426 unmonitored_peers++; 04427 04428 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04429 04430 snprintf(srch, sizeof(srch), FORMAT, name, 04431 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04432 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04433 nm, 04434 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04435 peer->encmethods ? "(E)" : " ", status, term); 04436 04437 if (s) 04438 astman_append(s, FORMAT, name, 04439 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04440 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04441 nm, 04442 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04443 peer->encmethods ? "(E)" : " ", status, term); 04444 else 04445 ast_cli(fd, FORMAT, name, 04446 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04447 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04448 nm, 04449 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04450 peer->encmethods ? "(E)" : " ", status, term); 04451 total_peers++; 04452 } 04453 04454 if (s) 04455 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04456 else 04457 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04458 04459 if (havepattern) 04460 regfree(®exbuf); 04461 04462 return RESULT_SUCCESS; 04463 #undef FORMAT 04464 #undef FORMAT2 04465 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 942 of file chan_iax2.c.
References ast_log(), find_idle_thread(), func, IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), t, and thread.
00943 { 00944 struct iax2_thread *thread = NULL; 00945 static time_t lasterror; 00946 static time_t t; 00947 00948 thread = find_idle_thread(); 00949 00950 if (thread != NULL) { 00951 thread->schedfunc = func; 00952 thread->scheddata = data; 00953 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00954 #ifdef DEBUG_SCHED_MULTITHREAD 00955 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00956 #endif 00957 signal_condition(&thread->lock, &thread->cond); 00958 return 0; 00959 } 00960 time(&t); 00961 if (t != lasterror) 00962 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n"); 00963 lasterror = t; 00964 00965 return -1; 00966 }
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 4846 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04848 { 04849 struct ast_frame f = { 0, }; 04850 04851 f.frametype = type; 04852 f.subclass = command; 04853 f.datalen = datalen; 04854 f.src = __FUNCTION__; 04855 f.data = (void *) data; 04856 04857 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04858 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1016 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01017 { 01018 int callno = (long)data; 01019 /* Ping only if it's real not if it's bridged */ 01020 ast_mutex_lock(&iaxsl[callno]); 01021 if (iaxs[callno] && iaxs[callno]->lagid != -1) { 01022 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01023 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01024 } 01025 ast_mutex_unlock(&iaxsl[callno]); 01026 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 982 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
00983 { 00984 int callno = (long)data; 00985 ast_mutex_lock(&iaxsl[callno]); 00986 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00987 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00988 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 00989 } 00990 ast_mutex_unlock(&iaxsl[callno]); 00991 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10710 of file chan_iax2.c.
References ao2_ref(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, papp, peers, reload_firmware(), sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10711 { 10712 struct iax2_thread *thread = NULL; 10713 int x; 10714 10715 /* Make sure threads do not hold shared resources when they are canceled */ 10716 10717 /* Grab the sched lock resource to keep it away from threads about to die */ 10718 /* Cancel the network thread, close the net socket */ 10719 if (netthreadid != AST_PTHREADT_NULL) { 10720 AST_LIST_LOCK(&iaxq.queue); 10721 ast_mutex_lock(&sched_lock); 10722 pthread_cancel(netthreadid); 10723 ast_cond_signal(&sched_cond); 10724 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10725 AST_LIST_UNLOCK(&iaxq.queue); 10726 pthread_join(netthreadid, NULL); 10727 } 10728 if (schedthreadid != AST_PTHREADT_NULL) { 10729 ast_mutex_lock(&sched_lock); 10730 pthread_cancel(schedthreadid); 10731 ast_cond_signal(&sched_cond); 10732 ast_mutex_unlock(&sched_lock); 10733 pthread_join(schedthreadid, NULL); 10734 } 10735 10736 /* Call for all threads to halt */ 10737 AST_LIST_LOCK(&idle_list); 10738 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10739 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10740 pthread_cancel(thread->threadid); 10741 } 10742 AST_LIST_TRAVERSE_SAFE_END 10743 AST_LIST_UNLOCK(&idle_list); 10744 10745 AST_LIST_LOCK(&active_list); 10746 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10747 AST_LIST_REMOVE_CURRENT(&active_list, list); 10748 pthread_cancel(thread->threadid); 10749 } 10750 AST_LIST_TRAVERSE_SAFE_END 10751 AST_LIST_UNLOCK(&active_list); 10752 10753 AST_LIST_LOCK(&dynamic_list); 10754 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10755 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10756 pthread_cancel(thread->threadid); 10757 } 10758 AST_LIST_TRAVERSE_SAFE_END 10759 AST_LIST_UNLOCK(&dynamic_list); 10760 10761 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10762 10763 /* Wait for threads to exit */ 10764 while(0 < iaxactivethreadcount) 10765 usleep(10000); 10766 10767 ast_netsock_release(netsock); 10768 ast_netsock_release(outsock); 10769 for (x=0;x<IAX_MAX_CALLS;x++) 10770 if (iaxs[x]) 10771 iax2_destroy(x); 10772 ast_manager_unregister( "IAXpeers" ); 10773 ast_manager_unregister( "IAXnetstats" ); 10774 ast_unregister_application(papp); 10775 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10776 ast_unregister_switch(&iax2_switch); 10777 ast_channel_unregister(&iax2_tech); 10778 delete_users(); 10779 iax_provision_unload(); 10780 sched_context_destroy(sched); 10781 reload_firmware(1); 10782 10783 ast_mutex_destroy(&waresl.lock); 10784 10785 for (x = 0; x < IAX_MAX_CALLS; x++) 10786 ast_mutex_destroy(&iaxsl[x]); 10787 10788 ao2_ref(peers, -1); 10789 ao2_ref(users, -1); 10790 10791 return 0; 10792 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 4899 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04900 { 04901 while(con) { 04902 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04903 return -1; 04904 con = con->next; 04905 } 04906 return 0; 04907 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4673 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04674 { 04675 int x; 04676 int numchans = 0; 04677 for (x=0;x<IAX_MAX_CALLS;x++) { 04678 ast_mutex_lock(&iaxsl[x]); 04679 if (iaxs[x]) { 04680 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04681 char *fmt; 04682 jb_info jbinfo; 04683 04684 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04685 jb_getinfo(iaxs[x]->jb, &jbinfo); 04686 localjitter = jbinfo.jitter; 04687 localdelay = jbinfo.current - jbinfo.min; 04688 locallost = jbinfo.frames_lost; 04689 locallosspct = jbinfo.losspct/1000; 04690 localdropped = jbinfo.frames_dropped; 04691 localooo = jbinfo.frames_ooo; 04692 } else { 04693 localjitter = -1; 04694 localdelay = 0; 04695 locallost = -1; 04696 locallosspct = -1; 04697 localdropped = 0; 04698 localooo = -1; 04699 } 04700 if (limit_fmt) 04701 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04702 else 04703 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04704 if (s) 04705 04706 astman_append(s, fmt, 04707 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04708 iaxs[x]->pingtime, 04709 localjitter, 04710 localdelay, 04711 locallost, 04712 locallosspct, 04713 localdropped, 04714 localooo, 04715 iaxs[x]->frames_received/1000, 04716 iaxs[x]->remote_rr.jitter, 04717 iaxs[x]->remote_rr.delay, 04718 iaxs[x]->remote_rr.losscnt, 04719 iaxs[x]->remote_rr.losspct, 04720 iaxs[x]->remote_rr.dropped, 04721 iaxs[x]->remote_rr.ooo, 04722 iaxs[x]->remote_rr.packets/1000); 04723 else 04724 ast_cli(fd, fmt, 04725 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04726 iaxs[x]->pingtime, 04727 localjitter, 04728 localdelay, 04729 locallost, 04730 locallosspct, 04731 localdropped, 04732 localooo, 04733 iaxs[x]->frames_received/1000, 04734 iaxs[x]->remote_rr.jitter, 04735 iaxs[x]->remote_rr.delay, 04736 iaxs[x]->remote_rr.losscnt, 04737 iaxs[x]->remote_rr.losspct, 04738 iaxs[x]->remote_rr.dropped, 04739 iaxs[x]->remote_rr.ooo, 04740 iaxs[x]->remote_rr.packets/1000 04741 ); 04742 numchans++; 04743 } 04744 ast_mutex_unlock(&iaxsl[x]); 04745 } 04746 return numchans; 04747 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 3581 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), 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_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, iax2_tech, iaxs, iaxsl, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
03582 { 03583 struct ast_channel *tmp; 03584 struct chan_iax2_pvt *i; 03585 struct ast_variable *v = NULL; 03586 03587 if (!(i = iaxs[callno])) { 03588 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03589 return NULL; 03590 } 03591 03592 /* Don't hold call lock */ 03593 ast_mutex_unlock(&iaxsl[callno]); 03594 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno); 03595 ast_mutex_lock(&iaxsl[callno]); 03596 if (!tmp) 03597 return NULL; 03598 tmp->tech = &iax2_tech; 03599 /* We can support any format by default, until we get restricted */ 03600 tmp->nativeformats = capability; 03601 tmp->readformat = ast_best_codec(capability); 03602 tmp->writeformat = ast_best_codec(capability); 03603 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03604 03605 /* Don't use ast_set_callerid() here because it will 03606 * generate a NewCallerID event before the NewChannel event */ 03607 if (!ast_strlen_zero(i->ani)) 03608 tmp->cid.cid_ani = ast_strdup(i->ani); 03609 else 03610 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03611 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03612 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03613 tmp->cid.cid_pres = i->calling_pres; 03614 tmp->cid.cid_ton = i->calling_ton; 03615 tmp->cid.cid_tns = i->calling_tns; 03616 if (!ast_strlen_zero(i->language)) 03617 ast_string_field_set(tmp, language, i->language); 03618 if (!ast_strlen_zero(i->accountcode)) 03619 ast_string_field_set(tmp, accountcode, i->accountcode); 03620 if (i->amaflags) 03621 tmp->amaflags = i->amaflags; 03622 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03623 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03624 if (i->adsi) 03625 tmp->adsicpe = i->peeradsicpe; 03626 else 03627 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03628 i->owner = tmp; 03629 i->capability = capability; 03630 03631 for (v = i->vars ; v ; v = v->next) 03632 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03633 03634 if (state != AST_STATE_DOWN) { 03635 if (ast_pbx_start(tmp)) { 03636 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03637 ast_hangup(tmp); 03638 i->owner = NULL; 03639 return NULL; 03640 } 03641 } 03642 03643 ast_module_ref(ast_module_info->self); 03644 03645 return tmp; 03646 }
static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | active_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | registrations | , | |
iax2_registry | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Inter Asterisk eXchange (Ver 2)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | sched_lock | ) |
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2123 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02124 { 02125 #ifdef SCHED_MULTITHREADED 02126 if (schedule_action(__attempt_transmit, data)) 02127 #endif 02128 __attempt_transmit(data); 02129 return 0; 02130 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6203 of file chan_iax2.c.
References ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), and iaxs.
Referenced by socket_process().
06204 { 06205 /* Schedule sending the authentication failure in one second, to prevent 06206 guessing */ 06207 if (iaxs[callno]) { 06208 iaxs[callno]->authfail = failcode; 06209 if (delayreject) { 06210 if (iaxs[callno]->authid > -1) 06211 ast_sched_del(sched, iaxs[callno]->authid); 06212 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06213 } else 06214 auth_reject((void *)(long)callno); 06215 } 06216 return 0; 06217 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6189 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06190 { 06191 int callno = (int)(long)(data); 06192 ast_mutex_lock(&iaxsl[callno]); 06193 if (iaxs[callno]) 06194 iaxs[callno]->authid = -1; 06195 ast_mutex_unlock(&iaxsl[callno]); 06196 #ifdef SCHED_MULTITHREADED 06197 if (schedule_action(__auth_reject, data)) 06198 #endif 06199 __auth_reject(data); 06200 return 0; 06201 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const 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 5424 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().
05425 { 05426 int res = -1; 05427 int x; 05428 if (!ast_strlen_zero(keyn)) { 05429 if (!(authmethods & IAX_AUTH_RSA)) { 05430 if (ast_strlen_zero(secret)) 05431 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr)); 05432 } else if (ast_strlen_zero(challenge)) { 05433 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05434 } else { 05435 char sig[256]; 05436 struct ast_key *key; 05437 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05438 if (!key) { 05439 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05440 } else { 05441 if (ast_sign(key, (char*)challenge, sig)) { 05442 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05443 res = -1; 05444 } else { 05445 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05446 res = 0; 05447 } 05448 } 05449 } 05450 } 05451 /* Fall back */ 05452 if (res && !ast_strlen_zero(secret)) { 05453 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05454 struct MD5Context md5; 05455 unsigned char digest[16]; 05456 char digres[128]; 05457 MD5Init(&md5); 05458 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05459 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05460 MD5Final(digest, &md5); 05461 /* If they support md5, authenticate with it. */ 05462 for (x=0;x<16;x++) 05463 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05464 if (ecx && dcx) 05465 build_enc_keys(digest, ecx, dcx); 05466 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05467 res = 0; 05468 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05469 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05470 res = 0; 05471 } else 05472 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05473 } 05474 return res; 05475 }
static int authenticate_reply | ( | struct chan_iax2_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies, | |||
const char * | override, | |||
const char * | okey | |||
) | [static] |
Definition at line 5481 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, iax2_registry::callno, iax_ies::challenge, chan_iax2_pvt::dcx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, iax2_peer::mask, merge_encryption(), peer_unref(), peers, iax_ie_data::pos, realtime_peer(), send_command(), and iax_ies::username.
Referenced by socket_process().
05482 { 05483 struct iax2_peer *peer = NULL; 05484 /* Start pessimistic */ 05485 int res = -1; 05486 int authmethods = 0; 05487 struct iax_ie_data ied; 05488 uint16_t callno = p->callno; 05489 05490 memset(&ied, 0, sizeof(ied)); 05491 05492 if (ies->username) 05493 ast_string_field_set(p, username, ies->username); 05494 if (ies->challenge) 05495 ast_string_field_set(p, challenge, ies->challenge); 05496 if (ies->authmethods) 05497 authmethods = ies->authmethods; 05498 if (authmethods & IAX_AUTH_MD5) 05499 merge_encryption(p, ies->encmethods); 05500 else 05501 p->encmethods = 0; 05502 05503 /* Check for override RSA authentication first */ 05504 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05505 /* Normal password authentication */ 05506 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05507 } else { 05508 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05509 while ((peer = ao2_iterator_next(&i))) { 05510 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05511 /* No peer specified at our end, or this is the peer */ 05512 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05513 /* No username specified in peer rule, or this is the right username */ 05514 && (!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))) 05515 /* No specified host, or this is our host */ 05516 ) { 05517 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05518 if (!res) { 05519 peer_unref(peer); 05520 break; 05521 } 05522 } 05523 peer_unref(peer); 05524 } 05525 if (!peer) { 05526 /* We checked our list and didn't find one. It's unlikely, but possible, 05527 that we're trying to authenticate *to* a realtime peer */ 05528 const char *peer_name = ast_strdupa(p->peer); 05529 ast_mutex_unlock(&iaxsl[callno]); 05530 if ((peer = realtime_peer(peer_name, NULL))) { 05531 ast_mutex_lock(&iaxsl[callno]); 05532 if (!(p = iaxs[callno])) { 05533 peer_unref(peer); 05534 return -1; 05535 } 05536 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05537 peer_unref(peer); 05538 } 05539 if (!peer) { 05540 ast_mutex_lock(&iaxsl[callno]); 05541 if (!(p = iaxs[callno])) 05542 return -1; 05543 } 05544 } 05545 } 05546 if (ies->encmethods) 05547 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05548 if (!res) 05549 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05550 return res; 05551 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5159 of file chan_iax2.c.
References ao2_find(), AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_user::curauthreq, 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, iaxs, iax2_user::maxauthreq, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and users.
Referenced by socket_process().
05160 { 05161 struct iax_ie_data ied; 05162 int res = -1, authreq_restrict = 0; 05163 char challenge[10]; 05164 struct chan_iax2_pvt *p = iaxs[call_num]; 05165 05166 memset(&ied, 0, sizeof(ied)); 05167 05168 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05169 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05170 struct iax2_user *user, tmp_user = { 05171 .name = p->username, 05172 }; 05173 05174 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05175 if (user) { 05176 if (user->curauthreq == user->maxauthreq) 05177 authreq_restrict = 1; 05178 else 05179 user->curauthreq++; 05180 user = user_unref(user); 05181 } 05182 } 05183 05184 /* If the AUTHREQ limit test failed, send back an error */ 05185 if (authreq_restrict) { 05186 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05187 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05188 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05189 return 0; 05190 } 05191 05192 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05193 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05194 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05195 ast_string_field_set(p, challenge, challenge); 05196 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05197 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05198 } 05199 if (p->encmethods) 05200 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05201 05202 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05203 05204 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05205 05206 if (p->encmethods) 05207 ast_set_flag(p, IAX_ENCRYPTED); 05208 05209 return res; 05210 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5212 of file chan_iax2.c.
References ao2_find(), ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, key(), LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, iax_ies::rsa_result, iax2_registry::secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05213 { 05214 char requeststr[256]; 05215 char md5secret[256] = ""; 05216 char secret[256] = ""; 05217 char rsasecret[256] = ""; 05218 int res = -1; 05219 int x; 05220 struct iax2_user *user, tmp_user = { 05221 .name = p->username, 05222 }; 05223 05224 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05225 if (user) { 05226 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05227 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05228 ast_clear_flag(p, IAX_MAXAUTHREQ); 05229 } 05230 ast_string_field_set(p, host, user->name); 05231 user = user_unref(user); 05232 } 05233 05234 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05235 return res; 05236 if (ies->password) 05237 ast_copy_string(secret, ies->password, sizeof(secret)); 05238 if (ies->md5_result) 05239 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05240 if (ies->rsa_result) 05241 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05242 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05243 struct ast_key *key; 05244 char *keyn; 05245 char tmpkey[256]; 05246 char *stringp=NULL; 05247 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05248 stringp=tmpkey; 05249 keyn = strsep(&stringp, ":"); 05250 while(keyn) { 05251 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05252 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05253 res = 0; 05254 break; 05255 } else if (!key) 05256 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05257 keyn = strsep(&stringp, ":"); 05258 } 05259 } else if (p->authmethods & IAX_AUTH_MD5) { 05260 struct MD5Context md5; 05261 unsigned char digest[16]; 05262 char *tmppw, *stringp; 05263 05264 tmppw = ast_strdupa(p->secret); 05265 stringp = tmppw; 05266 while((tmppw = strsep(&stringp, ";"))) { 05267 MD5Init(&md5); 05268 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05269 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05270 MD5Final(digest, &md5); 05271 /* If they support md5, authenticate with it. */ 05272 for (x=0;x<16;x++) 05273 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05274 if (!strcasecmp(requeststr, md5secret)) { 05275 res = 0; 05276 break; 05277 } 05278 } 05279 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05280 if (!strcmp(secret, p->secret)) 05281 res = 0; 05282 } 05283 return res; 05284 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 2999 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03000 { 03001 #ifdef SCHED_MULTITHREADED 03002 if (schedule_action(__auto_congest, data)) 03003 #endif 03004 __auto_congest(data); 03005 return 0; 03006 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6234 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06235 { 06236 int callno = (int)(long)(data); 06237 ast_mutex_lock(&iaxsl[callno]); 06238 if (iaxs[callno]) { 06239 iaxs[callno]->autoid = -1; 06240 } 06241 ast_mutex_unlock(&iaxsl[callno]); 06242 #ifdef SCHED_MULTITHREADED 06243 if (schedule_action(__auto_hangup, data)) 06244 #endif 06245 __auto_hangup(data); 06246 return 0; 06247 }
static struct iax2_context* build_context | ( | char * | context | ) | [static, read] |
Definition at line 8910 of file chan_iax2.c.
References ast_calloc, and iax2_context::context.
Referenced by build_user().
08911 { 08912 struct iax2_context *con; 08913 08914 if ((con = ast_calloc(1, sizeof(*con)))) 08915 ast_copy_string(con->context, context, sizeof(con->context)); 08916 08917 return con; 08918 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3942 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03943 { 03944 aes_encrypt_key128(digest, ecx); 03945 aes_decrypt_key128(digest, dcx); 03946 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create peer structure based on configuration.
Definition at line 9056 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ao2_alloc(), ao2_find(), ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), iax2_peer::authmethods, iax2_peer::capability, cid_name, cid_num, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, iax2_registry::secret, iax2_peer::smoothing, iax2_peer::sockfd, unlink_peer(), and ast_variable::value.
09057 { 09058 struct iax2_peer *peer = NULL; 09059 struct ast_ha *oldha = NULL; 09060 int maskfound=0; 09061 int found=0; 09062 int firstpass=1; 09063 struct iax2_peer tmp_peer = { 09064 .name = name, 09065 }; 09066 09067 if (!temponly) { 09068 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09069 if (peer && !ast_test_flag(peer, IAX_DELME)) 09070 firstpass = 0; 09071 } 09072 09073 if (peer) { 09074 found++; 09075 if (firstpass) { 09076 oldha = peer->ha; 09077 peer->ha = NULL; 09078 } 09079 unlink_peer(peer); 09080 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09081 peer->expire = -1; 09082 peer->pokeexpire = -1; 09083 peer->sockfd = defaultsockfd; 09084 if (ast_string_field_init(peer, 32)) 09085 peer = peer_unref(peer); 09086 } 09087 09088 if (peer) { 09089 if (firstpass) { 09090 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09091 peer->encmethods = iax2_encryption; 09092 peer->adsi = adsi; 09093 ast_string_field_set(peer,secret,""); 09094 if (!found) { 09095 ast_string_field_set(peer, name, name); 09096 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09097 peer->expiry = min_reg_expire; 09098 } 09099 peer->prefs = prefs; 09100 peer->capability = iax2_capability; 09101 peer->smoothing = 0; 09102 peer->pokefreqok = DEFAULT_FREQ_OK; 09103 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09104 ast_string_field_set(peer,context,""); 09105 ast_string_field_set(peer,peercontext,""); 09106 ast_clear_flag(peer, IAX_HASCALLERID); 09107 ast_string_field_set(peer, cid_name, ""); 09108 ast_string_field_set(peer, cid_num, ""); 09109 } 09110 09111 if (!v) { 09112 v = alt; 09113 alt = NULL; 09114 } 09115 while(v) { 09116 if (!strcasecmp(v->name, "secret")) { 09117 ast_string_field_set(peer, secret, v->value); 09118 } else if (!strcasecmp(v->name, "mailbox")) { 09119 ast_string_field_set(peer, mailbox, v->value); 09120 } else if (!strcasecmp(v->name, "mohinterpret")) { 09121 ast_string_field_set(peer, mohinterpret, v->value); 09122 } else if (!strcasecmp(v->name, "mohsuggest")) { 09123 ast_string_field_set(peer, mohsuggest, v->value); 09124 } else if (!strcasecmp(v->name, "dbsecret")) { 09125 ast_string_field_set(peer, dbsecret, v->value); 09126 } else if (!strcasecmp(v->name, "trunk")) { 09127 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09128 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09129 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09130 ast_clear_flag(peer, IAX_TRUNK); 09131 } 09132 } else if (!strcasecmp(v->name, "auth")) { 09133 peer->authmethods = get_auth_methods(v->value); 09134 } else if (!strcasecmp(v->name, "encryption")) { 09135 peer->encmethods = get_encrypt_methods(v->value); 09136 } else if (!strcasecmp(v->name, "notransfer")) { 09137 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09138 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09139 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09140 } else if (!strcasecmp(v->name, "transfer")) { 09141 if (!strcasecmp(v->value, "mediaonly")) { 09142 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09143 } else if (ast_true(v->value)) { 09144 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09145 } else 09146 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09147 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09148 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09149 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09150 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09151 } else if (!strcasecmp(v->name, "host")) { 09152 if (!strcasecmp(v->value, "dynamic")) { 09153 /* They'll register with us */ 09154 ast_set_flag(peer, IAX_DYNAMIC); 09155 if (!found) { 09156 /* Initialize stuff iff we're not found, otherwise 09157 we keep going with what we had */ 09158 memset(&peer->addr.sin_addr, 0, 4); 09159 if (peer->addr.sin_port) { 09160 /* If we've already got a port, make it the default rather than absolute */ 09161 peer->defaddr.sin_port = peer->addr.sin_port; 09162 peer->addr.sin_port = 0; 09163 } 09164 } 09165 } else { 09166 /* Non-dynamic. Make sure we become that way if we're not */ 09167 if (peer->expire > -1) 09168 ast_sched_del(sched, peer->expire); 09169 peer->expire = -1; 09170 ast_clear_flag(peer, IAX_DYNAMIC); 09171 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09172 return peer_unref(peer); 09173 if (!peer->addr.sin_port) 09174 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09175 } 09176 if (!maskfound) 09177 inet_aton("255.255.255.255", &peer->mask); 09178 } else if (!strcasecmp(v->name, "defaultip")) { 09179 if (ast_get_ip(&peer->defaddr, v->value)) 09180 return peer_unref(peer); 09181 } else if (!strcasecmp(v->name, "sourceaddress")) { 09182 peer_set_srcaddr(peer, v->value); 09183 } else if (!strcasecmp(v->name, "permit") || 09184 !strcasecmp(v->name, "deny")) { 09185 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09186 } else if (!strcasecmp(v->name, "mask")) { 09187 maskfound++; 09188 inet_aton(v->value, &peer->mask); 09189 } else if (!strcasecmp(v->name, "context")) { 09190 ast_string_field_set(peer, context, v->value); 09191 } else if (!strcasecmp(v->name, "regexten")) { 09192 ast_string_field_set(peer, regexten, v->value); 09193 } else if (!strcasecmp(v->name, "peercontext")) { 09194 ast_string_field_set(peer, peercontext, v->value); 09195 } else if (!strcasecmp(v->name, "port")) { 09196 if (ast_test_flag(peer, IAX_DYNAMIC)) 09197 peer->defaddr.sin_port = htons(atoi(v->value)); 09198 else 09199 peer->addr.sin_port = htons(atoi(v->value)); 09200 } else if (!strcasecmp(v->name, "username")) { 09201 ast_string_field_set(peer, username, v->value); 09202 } else if (!strcasecmp(v->name, "allow")) { 09203 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09204 } else if (!strcasecmp(v->name, "disallow")) { 09205 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09206 } else if (!strcasecmp(v->name, "callerid")) { 09207 if (!ast_strlen_zero(v->value)) { 09208 char name2[80]; 09209 char num2[80]; 09210 ast_callerid_split(v->value, name2, 80, num2, 80); 09211 ast_string_field_set(peer, cid_name, name2); 09212 ast_string_field_set(peer, cid_num, num2); 09213 ast_set_flag(peer, IAX_HASCALLERID); 09214 } else { 09215 ast_clear_flag(peer, IAX_HASCALLERID); 09216 ast_string_field_set(peer, cid_name, ""); 09217 ast_string_field_set(peer, cid_num, ""); 09218 } 09219 } else if (!strcasecmp(v->name, "fullname")) { 09220 if (!ast_strlen_zero(v->value)) { 09221 ast_string_field_set(peer, cid_name, v->value); 09222 ast_set_flag(peer, IAX_HASCALLERID); 09223 } else { 09224 ast_string_field_set(peer, cid_name, ""); 09225 if (ast_strlen_zero(peer->cid_num)) 09226 ast_clear_flag(peer, IAX_HASCALLERID); 09227 } 09228 } else if (!strcasecmp(v->name, "cid_number")) { 09229 if (!ast_strlen_zero(v->value)) { 09230 ast_string_field_set(peer, cid_num, v->value); 09231 ast_set_flag(peer, IAX_HASCALLERID); 09232 } else { 09233 ast_string_field_set(peer, cid_num, ""); 09234 if (ast_strlen_zero(peer->cid_name)) 09235 ast_clear_flag(peer, IAX_HASCALLERID); 09236 } 09237 } else if (!strcasecmp(v->name, "sendani")) { 09238 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09239 } else if (!strcasecmp(v->name, "inkeys")) { 09240 ast_string_field_set(peer, inkeys, v->value); 09241 } else if (!strcasecmp(v->name, "outkey")) { 09242 ast_string_field_set(peer, outkey, v->value); 09243 } else if (!strcasecmp(v->name, "qualify")) { 09244 if (!strcasecmp(v->value, "no")) { 09245 peer->maxms = 0; 09246 } else if (!strcasecmp(v->value, "yes")) { 09247 peer->maxms = DEFAULT_MAXMS; 09248 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09249 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); 09250 peer->maxms = 0; 09251 } 09252 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09253 peer->smoothing = ast_true(v->value); 09254 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09255 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09256 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); 09257 } 09258 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09259 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09260 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); 09261 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09262 } else if (!strcasecmp(v->name, "timezone")) { 09263 ast_string_field_set(peer, zonetag, v->value); 09264 } else if (!strcasecmp(v->name, "adsi")) { 09265 peer->adsi = ast_true(v->value); 09266 }/* else if (strcasecmp(v->name,"type")) */ 09267 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09268 v = v->next; 09269 if (!v) { 09270 v = alt; 09271 alt = NULL; 09272 } 09273 } 09274 if (!peer->authmethods) 09275 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09276 ast_clear_flag(peer, IAX_DELME); 09277 /* Make sure these are IPv4 addresses */ 09278 peer->addr.sin_family = AF_INET; 09279 } 09280 if (oldha) 09281 ast_free_ha(oldha); 09282 return peer; 09283 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 9299 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, 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_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_context::next, prefs, iax2_user::prefs, iax2_registry::secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09300 { 09301 struct iax2_user *user = NULL; 09302 struct iax2_context *con, *conl = NULL; 09303 struct ast_ha *oldha = NULL; 09304 struct iax2_context *oldcon = NULL; 09305 int format; 09306 int firstpass=1; 09307 int oldcurauthreq = 0; 09308 char *varname = NULL, *varval = NULL; 09309 struct ast_variable *tmpvar = NULL; 09310 struct iax2_user tmp_user = { 09311 .name = name, 09312 }; 09313 09314 if (!temponly) { 09315 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09316 if (user && !ast_test_flag(user, IAX_DELME)) 09317 firstpass = 0; 09318 } 09319 09320 if (user) { 09321 if (firstpass) { 09322 oldcurauthreq = user->curauthreq; 09323 oldha = user->ha; 09324 oldcon = user->contexts; 09325 user->ha = NULL; 09326 user->contexts = NULL; 09327 } 09328 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09329 ao2_unlink(users, user); 09330 } else { 09331 user = ao2_alloc(sizeof(*user), user_destructor); 09332 } 09333 09334 if (user) { 09335 if (firstpass) { 09336 ast_string_field_free_memory(user); 09337 memset(user, 0, sizeof(struct iax2_user)); 09338 if (ast_string_field_init(user, 32)) { 09339 user = user_unref(user); 09340 goto cleanup; 09341 } 09342 user->maxauthreq = maxauthreq; 09343 user->curauthreq = oldcurauthreq; 09344 user->prefs = prefs; 09345 user->capability = iax2_capability; 09346 user->encmethods = iax2_encryption; 09347 user->adsi = adsi; 09348 ast_string_field_set(user, name, name); 09349 ast_string_field_set(user, language, language); 09350 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09351 ast_clear_flag(user, IAX_HASCALLERID); 09352 ast_string_field_set(user, cid_name, ""); 09353 ast_string_field_set(user, cid_num, ""); 09354 } 09355 if (!v) { 09356 v = alt; 09357 alt = NULL; 09358 } 09359 while(v) { 09360 if (!strcasecmp(v->name, "context")) { 09361 con = build_context(v->value); 09362 if (con) { 09363 if (conl) 09364 conl->next = con; 09365 else 09366 user->contexts = con; 09367 conl = con; 09368 } 09369 } else if (!strcasecmp(v->name, "permit") || 09370 !strcasecmp(v->name, "deny")) { 09371 user->ha = ast_append_ha(v->name, v->value, user->ha); 09372 } else if (!strcasecmp(v->name, "setvar")) { 09373 varname = ast_strdupa(v->value); 09374 if (varname && (varval = strchr(varname,'='))) { 09375 *varval = '\0'; 09376 varval++; 09377 if((tmpvar = ast_variable_new(varname, varval))) { 09378 tmpvar->next = user->vars; 09379 user->vars = tmpvar; 09380 } 09381 } 09382 } else if (!strcasecmp(v->name, "allow")) { 09383 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09384 } else if (!strcasecmp(v->name, "disallow")) { 09385 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09386 } else if (!strcasecmp(v->name, "trunk")) { 09387 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09388 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09389 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09390 ast_clear_flag(user, IAX_TRUNK); 09391 } 09392 } else if (!strcasecmp(v->name, "auth")) { 09393 user->authmethods = get_auth_methods(v->value); 09394 } else if (!strcasecmp(v->name, "encryption")) { 09395 user->encmethods = get_encrypt_methods(v->value); 09396 } else if (!strcasecmp(v->name, "notransfer")) { 09397 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09398 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09399 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09400 } else if (!strcasecmp(v->name, "transfer")) { 09401 if (!strcasecmp(v->value, "mediaonly")) { 09402 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09403 } else if (ast_true(v->value)) { 09404 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09405 } else 09406 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09407 } else if (!strcasecmp(v->name, "codecpriority")) { 09408 if(!strcasecmp(v->value, "caller")) 09409 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09410 else if(!strcasecmp(v->value, "disabled")) 09411 ast_set_flag(user, IAX_CODEC_NOPREFS); 09412 else if(!strcasecmp(v->value, "reqonly")) { 09413 ast_set_flag(user, IAX_CODEC_NOCAP); 09414 ast_set_flag(user, IAX_CODEC_NOPREFS); 09415 } 09416 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09417 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09418 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09419 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09420 } else if (!strcasecmp(v->name, "dbsecret")) { 09421 ast_string_field_set(user, dbsecret, v->value); 09422 } else if (!strcasecmp(v->name, "secret")) { 09423 if (!ast_strlen_zero(user->secret)) { 09424 char *old = ast_strdupa(user->secret); 09425 09426 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09427 } else 09428 ast_string_field_set(user, secret, v->value); 09429 } else if (!strcasecmp(v->name, "callerid")) { 09430 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09431 char name2[80]; 09432 char num2[80]; 09433 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09434 ast_string_field_set(user, cid_name, name2); 09435 ast_string_field_set(user, cid_num, num2); 09436 ast_set_flag(user, IAX_HASCALLERID); 09437 } else { 09438 ast_clear_flag(user, IAX_HASCALLERID); 09439 ast_string_field_set(user, cid_name, ""); 09440 ast_string_field_set(user, cid_num, ""); 09441 } 09442 } else if (!strcasecmp(v->name, "fullname")) { 09443 if (!ast_strlen_zero(v->value)) { 09444 ast_string_field_set(user, cid_name, v->value); 09445 ast_set_flag(user, IAX_HASCALLERID); 09446 } else { 09447 ast_string_field_set(user, cid_name, ""); 09448 if (ast_strlen_zero(user->cid_num)) 09449 ast_clear_flag(user, IAX_HASCALLERID); 09450 } 09451 } else if (!strcasecmp(v->name, "cid_number")) { 09452 if (!ast_strlen_zero(v->value)) { 09453 ast_string_field_set(user, cid_num, v->value); 09454 ast_set_flag(user, IAX_HASCALLERID); 09455 } else { 09456 ast_string_field_set(user, cid_num, ""); 09457 if (ast_strlen_zero(user->cid_name)) 09458 ast_clear_flag(user, IAX_HASCALLERID); 09459 } 09460 } else if (!strcasecmp(v->name, "accountcode")) { 09461 ast_string_field_set(user, accountcode, v->value); 09462 } else if (!strcasecmp(v->name, "mohinterpret")) { 09463 ast_string_field_set(user, mohinterpret, v->value); 09464 } else if (!strcasecmp(v->name, "mohsuggest")) { 09465 ast_string_field_set(user, mohsuggest, v->value); 09466 } else if (!strcasecmp(v->name, "language")) { 09467 ast_string_field_set(user, language, v->value); 09468 } else if (!strcasecmp(v->name, "amaflags")) { 09469 format = ast_cdr_amaflags2int(v->value); 09470 if (format < 0) { 09471 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09472 } else { 09473 user->amaflags = format; 09474 } 09475 } else if (!strcasecmp(v->name, "inkeys")) { 09476 ast_string_field_set(user, inkeys, v->value); 09477 } else if (!strcasecmp(v->name, "maxauthreq")) { 09478 user->maxauthreq = atoi(v->value); 09479 if (user->maxauthreq < 0) 09480 user->maxauthreq = 0; 09481 } else if (!strcasecmp(v->name, "adsi")) { 09482 user->adsi = ast_true(v->value); 09483 }/* else if (strcasecmp(v->name,"type")) */ 09484 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09485 v = v->next; 09486 if (!v) { 09487 v = alt; 09488 alt = NULL; 09489 } 09490 } 09491 if (!user->authmethods) { 09492 if (!ast_strlen_zero(user->secret)) { 09493 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09494 if (!ast_strlen_zero(user->inkeys)) 09495 user->authmethods |= IAX_AUTH_RSA; 09496 } else if (!ast_strlen_zero(user->inkeys)) { 09497 user->authmethods = IAX_AUTH_RSA; 09498 } else { 09499 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09500 } 09501 } 09502 ast_clear_flag(user, IAX_DELME); 09503 } 09504 cleanup: 09505 if (oldha) 09506 ast_free_ha(oldha); 09507 if (oldcon) 09508 free_context(oldcon); 09509 return user; 09510 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10014 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, iax_ie_data::buf, iax2_registry::callno, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, 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, iaxs, iaxsl, parsed_dial_string::key, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, iax2_registry::secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
10015 { 10016 struct sockaddr_in sin; 10017 int x; 10018 int callno; 10019 struct iax_ie_data ied; 10020 struct create_addr_info cai; 10021 struct parsed_dial_string pds; 10022 char *tmpstr; 10023 10024 for (x=0; x<IAX_MAX_CALLS; x++) { 10025 /* Look for an *exact match* call. Once a call is negotiated, it can only 10026 look up entries for a single context */ 10027 if (!ast_mutex_trylock(&iaxsl[x])) { 10028 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10029 return x; 10030 ast_mutex_unlock(&iaxsl[x]); 10031 } 10032 } 10033 10034 /* No match found, we need to create a new one */ 10035 10036 memset(&cai, 0, sizeof(cai)); 10037 memset(&ied, 0, sizeof(ied)); 10038 memset(&pds, 0, sizeof(pds)); 10039 10040 tmpstr = ast_strdupa(data); 10041 parse_dial_string(tmpstr, &pds); 10042 10043 /* Populate our address from the given */ 10044 if (create_addr(pds.peer, &sin, &cai)) 10045 return -1; 10046 10047 if (option_debug) 10048 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10049 pds.peer, pds.username, pds.password, pds.context); 10050 10051 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 10052 if (callno < 1) { 10053 ast_log(LOG_WARNING, "Unable to create call\n"); 10054 return -1; 10055 } 10056 10057 ast_mutex_lock(&iaxsl[callno]); 10058 ast_string_field_set(iaxs[callno], dproot, data); 10059 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10060 10061 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10062 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10063 /* the string format is slightly different from a standard dial string, 10064 because the context appears in the 'exten' position 10065 */ 10066 if (pds.exten) 10067 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10068 if (pds.username) 10069 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10070 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10071 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10072 /* Keep password handy */ 10073 if (pds.password) 10074 ast_string_field_set(iaxs[callno], secret, pds.password); 10075 if (pds.key) 10076 ast_string_field_set(iaxs[callno], outkey, pds.key); 10077 /* Start the call going */ 10078 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10079 10080 return callno; 10081 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3810 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, LOG_DEBUG, option_debug, and chan_iax2_pvt::rxcore.
03811 { 03812 /* Returns where in "receive time" we are. That is, how many ms 03813 since we received (or would have received) the frame with timestamp 0 */ 03814 int ms; 03815 #ifdef IAXTESTS 03816 int jit; 03817 #endif /* IAXTESTS */ 03818 /* Setup rxcore if necessary */ 03819 if (ast_tvzero(p->rxcore)) { 03820 p->rxcore = ast_tvnow(); 03821 if (option_debug && iaxdebug) 03822 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03823 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03824 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03825 #if 1 03826 if (option_debug && iaxdebug) 03827 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03828 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03829 #endif 03830 } 03831 03832 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03833 #ifdef IAXTESTS 03834 if (test_jit) { 03835 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03836 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03837 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03838 jit = -jit; 03839 ms += jit; 03840 } 03841 } 03842 if (test_late) { 03843 ms += test_late; 03844 test_late = 0; 03845 } 03846 #endif /* IAXTESTS */ 03847 return ms; 03848 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3692 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, iaxs, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples.
Referenced by iax2_send(), and socket_process().
03693 { 03694 int ms; 03695 int voice = 0; 03696 int genuine = 0; 03697 int adjust; 03698 struct timeval *delivery = NULL; 03699 03700 03701 /* What sort of frame do we have?: voice is self-explanatory 03702 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03703 non-genuine frames are CONTROL frames [ringing etc], DTMF 03704 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03705 the others need a timestamp slaved to the voice frames so that they go in sequence 03706 */ 03707 if (f) { 03708 if (f->frametype == AST_FRAME_VOICE) { 03709 voice = 1; 03710 delivery = &f->delivery; 03711 } else if (f->frametype == AST_FRAME_IAX) { 03712 genuine = 1; 03713 } else if (f->frametype == AST_FRAME_CNG) { 03714 p->notsilenttx = 0; 03715 } 03716 } 03717 if (ast_tvzero(p->offset)) { 03718 gettimeofday(&p->offset, NULL); 03719 /* Round to nearest 20ms for nice looking traces */ 03720 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03721 } 03722 /* If the timestamp is specified, just send it as is */ 03723 if (ts) 03724 return ts; 03725 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03726 if (delivery && !ast_tvzero(*delivery)) { 03727 ms = ast_tvdiff_ms(*delivery, p->offset); 03728 if (option_debug > 2 && iaxdebug) 03729 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03730 } else { 03731 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03732 if (ms < 0) 03733 ms = 0; 03734 if (voice) { 03735 /* On a voice frame, use predicted values if appropriate */ 03736 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03737 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03738 /* AN EXPLANATION: 03739 When we send voice, we usually send "calculated" timestamps worked out 03740 on the basis of the number of samples sent. When we send other frames, 03741 we usually send timestamps worked out from the real clock. 03742 The problem is that they can tend to drift out of step because the 03743 source channel's clock and our clock may not be exactly at the same rate. 03744 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03745 for this call. Moving it adjusts timestamps for non-voice frames. 03746 We make the adjustment in the style of a moving average. Each time we 03747 adjust p->offset by 10% of the difference between our clock-derived 03748 timestamp and the predicted timestamp. That's why you see "10000" 03749 below even though IAX2 timestamps are in milliseconds. 03750 The use of a moving average avoids offset moving too radically. 03751 Generally, "adjust" roams back and forth around 0, with offset hardly 03752 changing at all. But if a consistent different starts to develop it 03753 will be eliminated over the course of 10 frames (200-300msecs) 03754 */ 03755 adjust = (ms - p->nextpred); 03756 if (adjust < 0) 03757 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03758 else if (adjust > 0) 03759 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03760 03761 if (!p->nextpred) { 03762 p->nextpred = ms; /*f->samples / 8;*/ 03763 if (p->nextpred <= p->lastsent) 03764 p->nextpred = p->lastsent + 3; 03765 } 03766 ms = p->nextpred; 03767 } else { 03768 /* in this case, just use the actual 03769 * time, since we're either way off 03770 * (shouldn't happen), or we're ending a 03771 * silent period -- and seed the next 03772 * predicted time. Also, round ms to the 03773 * next multiple of frame size (so our 03774 * silent periods are multiples of 03775 * frame size too) */ 03776 03777 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03778 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03779 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03780 03781 if (f->samples >= 8) /* check to make sure we dont core dump */ 03782 { 03783 int diff = ms % (f->samples / 8); 03784 if (diff) 03785 ms += f->samples/8 - diff; 03786 } 03787 03788 p->nextpred = ms; 03789 p->notsilenttx = 1; 03790 } 03791 } else { 03792 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03793 it's a genuine frame */ 03794 if (genuine) { 03795 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03796 if (ms <= p->lastsent) 03797 ms = p->lastsent + 3; 03798 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03799 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03800 ms = p->lastsent + 3; 03801 } 03802 } 03803 } 03804 p->lastsent = ms; 03805 if (voice) 03806 p->nextpred = p->nextpred + f->samples / 8; 03807 return ms; 03808 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3648 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().
03649 { 03650 unsigned long int mssincetx; /* unsigned to handle overflows */ 03651 long int ms, pred; 03652 03653 tpeer->trunkact = *tv; 03654 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03655 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03656 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03657 tpeer->txtrunktime = *tv; 03658 tpeer->lastsent = 999999; 03659 } 03660 /* Update last transmit time now */ 03661 tpeer->lasttxtime = *tv; 03662 03663 /* Calculate ms offset */ 03664 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03665 /* Predict from last value */ 03666 pred = tpeer->lastsent + sampms; 03667 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03668 ms = pred; 03669 03670 /* We never send the same timestamp twice, so fudge a little if we must */ 03671 if (ms == tpeer->lastsent) 03672 ms = tpeer->lastsent + 1; 03673 tpeer->lastsent = ms; 03674 return ms; 03675 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4910 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, iax2_context::context, iax2_user::contexts, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, key(), iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), iax2_registry::secret, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version.
Referenced by socket_process().
04911 { 04912 /* Start pessimistic */ 04913 int res = -1; 04914 int version = 2; 04915 struct iax2_user *user = NULL, *best = NULL; 04916 int bestscore = 0; 04917 int gotcapability = 0; 04918 struct ast_variable *v = NULL, *tmpvar = NULL; 04919 struct ao2_iterator i; 04920 04921 if (!iaxs[callno]) 04922 return res; 04923 if (ies->called_number) 04924 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04925 if (ies->calling_number) { 04926 ast_shrink_phone_number(ies->calling_number); 04927 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04928 } 04929 if (ies->calling_name) 04930 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04931 if (ies->calling_ani) 04932 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04933 if (ies->dnid) 04934 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04935 if (ies->rdnis) 04936 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04937 if (ies->called_context) 04938 ast_string_field_set(iaxs[callno], context, ies->called_context); 04939 if (ies->language) 04940 ast_string_field_set(iaxs[callno], language, ies->language); 04941 if (ies->username) 04942 ast_string_field_set(iaxs[callno], username, ies->username); 04943 if (ies->calling_ton > -1) 04944 iaxs[callno]->calling_ton = ies->calling_ton; 04945 if (ies->calling_tns > -1) 04946 iaxs[callno]->calling_tns = ies->calling_tns; 04947 if (ies->calling_pres > -1) 04948 iaxs[callno]->calling_pres = ies->calling_pres; 04949 if (ies->format) 04950 iaxs[callno]->peerformat = ies->format; 04951 if (ies->adsicpe) 04952 iaxs[callno]->peeradsicpe = ies->adsicpe; 04953 if (ies->capability) { 04954 gotcapability = 1; 04955 iaxs[callno]->peercapability = ies->capability; 04956 } 04957 if (ies->version) 04958 version = ies->version; 04959 04960 /* Use provided preferences until told otherwise for actual preferences */ 04961 if(ies->codec_prefs) { 04962 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04963 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04964 } 04965 04966 if (!gotcapability) 04967 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04968 if (version > IAX_PROTO_VERSION) { 04969 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04970 ast_inet_ntoa(sin->sin_addr), version); 04971 return res; 04972 } 04973 /* Search the userlist for a compatible entry, and fill in the rest */ 04974 i = ao2_iterator_init(users, 0); 04975 while ((user = ao2_iterator_next(&i))) { 04976 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04977 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04978 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04979 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04980 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04981 if (!ast_strlen_zero(iaxs[callno]->username)) { 04982 /* Exact match, stop right now. */ 04983 if (best) 04984 user_unref(best); 04985 best = user; 04986 break; 04987 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04988 /* No required authentication */ 04989 if (user->ha) { 04990 /* There was host authentication and we passed, bonus! */ 04991 if (bestscore < 4) { 04992 bestscore = 4; 04993 if (best) 04994 user_unref(best); 04995 best = user; 04996 continue; 04997 } 04998 } else { 04999 /* No host access, but no secret, either, not bad */ 05000 if (bestscore < 3) { 05001 bestscore = 3; 05002 if (best) 05003 user_unref(best); 05004 best = user; 05005 continue; 05006 } 05007 } 05008 } else { 05009 if (user->ha) { 05010 /* Authentication, but host access too, eh, it's something.. */ 05011 if (bestscore < 2) { 05012 bestscore = 2; 05013 if (best) 05014 user_unref(best); 05015 best = user; 05016 continue; 05017 } 05018 } else { 05019 /* Authentication and no host access... This is our baseline */ 05020 if (bestscore < 1) { 05021 bestscore = 1; 05022 if (best) 05023 user_unref(best); 05024 best = user; 05025 continue; 05026 } 05027 } 05028 } 05029 } 05030 user_unref(user); 05031 } 05032 user = best; 05033 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05034 user = realtime_user(iaxs[callno]->username, sin); 05035 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05036 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05037 user = user_unref(user); 05038 } 05039 } 05040 if (user) { 05041 /* We found our match (use the first) */ 05042 /* copy vars */ 05043 for (v = user->vars ; v ; v = v->next) { 05044 if((tmpvar = ast_variable_new(v->name, v->value))) { 05045 tmpvar->next = iaxs[callno]->vars; 05046 iaxs[callno]->vars = tmpvar; 05047 } 05048 } 05049 /* If a max AUTHREQ restriction is in place, activate it */ 05050 if (user->maxauthreq > 0) 05051 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05052 iaxs[callno]->prefs = user->prefs; 05053 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05054 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05055 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05056 iaxs[callno]->encmethods = user->encmethods; 05057 /* Store the requested username if not specified */ 05058 if (ast_strlen_zero(iaxs[callno]->username)) 05059 ast_string_field_set(iaxs[callno], username, user->name); 05060 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05061 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05062 iaxs[callno]->capability = user->capability; 05063 /* And use the default context */ 05064 if (ast_strlen_zero(iaxs[callno]->context)) { 05065 if (user->contexts) 05066 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05067 else 05068 ast_string_field_set(iaxs[callno], context, context); 05069 } 05070 /* And any input keys */ 05071 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05072 /* And the permitted authentication methods */ 05073 iaxs[callno]->authmethods = user->authmethods; 05074 iaxs[callno]->adsi = user->adsi; 05075 /* If they have callerid, override the given caller id. Always store the ANI */ 05076 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05077 if (ast_test_flag(user, IAX_HASCALLERID)) { 05078 iaxs[callno]->calling_tns = 0; 05079 iaxs[callno]->calling_ton = 0; 05080 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05081 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05082 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05083 } 05084 if (ast_strlen_zero(iaxs[callno]->ani)) 05085 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05086 } else { 05087 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05088 } 05089 if (!ast_strlen_zero(user->accountcode)) 05090 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05091 if (!ast_strlen_zero(user->mohinterpret)) 05092 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05093 if (!ast_strlen_zero(user->mohsuggest)) 05094 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05095 if (user->amaflags) 05096 iaxs[callno]->amaflags = user->amaflags; 05097 if (!ast_strlen_zero(user->language)) 05098 ast_string_field_set(iaxs[callno], language, user->language); 05099 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05100 /* Keep this check last */ 05101 if (!ast_strlen_zero(user->dbsecret)) { 05102 char *family, *key=NULL; 05103 char buf[80]; 05104 family = ast_strdupa(user->dbsecret); 05105 key = strchr(family, '/'); 05106 if (key) { 05107 *key = '\0'; 05108 key++; 05109 } 05110 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05111 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05112 else 05113 ast_string_field_set(iaxs[callno], secret, buf); 05114 } else 05115 ast_string_field_set(iaxs[callno], secret, user->secret); 05116 res = 0; 05117 user = user_unref(user); 05118 } 05119 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05120 return res; 05121 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6588 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.
Referenced by socket_process().
06589 { 06590 unsigned int ourver; 06591 char rsi[80]; 06592 snprintf(rsi, sizeof(rsi), "si-%s", si); 06593 if (iax_provision_version(&ourver, rsi, 1)) 06594 return 0; 06595 if (option_debug) 06596 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06597 if (ourver != ver) 06598 iax2_provision(sin, sockfd, NULL, rsi, 1); 06599 return 0; 06600 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 8936 of file chan_iax2.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
08937 { 08938 int sd; 08939 int res; 08940 08941 sd = socket(AF_INET, SOCK_DGRAM, 0); 08942 if (sd < 0) { 08943 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08944 return -1; 08945 } 08946 08947 res = bind(sd, sa, salen); 08948 if (res < 0) { 08949 if (option_debug) 08950 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08951 close(sd); 08952 return 1; 08953 } 08954 08955 close(sd); 08956 return 0; 08957 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5600 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, iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, 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, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.
Referenced by socket_process().
05601 { 05602 char exten[256] = ""; 05603 int status = CACHE_FLAG_UNKNOWN; 05604 int expiry = iaxdefaultdpcache; 05605 int x; 05606 int matchmore = 0; 05607 struct iax2_dpcache *dp, *prev; 05608 05609 if (ies->called_number) 05610 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05611 05612 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05613 status = CACHE_FLAG_EXISTS; 05614 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05615 status = CACHE_FLAG_CANEXIST; 05616 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05617 status = CACHE_FLAG_NONEXISTENT; 05618 05619 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05620 /* Don't really do anything with this */ 05621 } 05622 if (ies->refresh) 05623 expiry = ies->refresh; 05624 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05625 matchmore = CACHE_FLAG_MATCHMORE; 05626 ast_mutex_lock(&dpcache_lock); 05627 prev = NULL; 05628 dp = pvt->dpentries; 05629 while(dp) { 05630 if (!strcmp(dp->exten, exten)) { 05631 /* Let them go */ 05632 if (prev) 05633 prev->peer = dp->peer; 05634 else 05635 pvt->dpentries = dp->peer; 05636 dp->peer = NULL; 05637 dp->callno = 0; 05638 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05639 if (dp->flags & CACHE_FLAG_PENDING) { 05640 dp->flags &= ~CACHE_FLAG_PENDING; 05641 dp->flags |= status; 05642 dp->flags |= matchmore; 05643 } 05644 /* Wake up waiters */ 05645 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05646 if (dp->waiters[x] > -1) 05647 write(dp->waiters[x], "asdf", 4); 05648 } 05649 prev = dp; 05650 dp = dp->peer; 05651 } 05652 ast_mutex_unlock(&dpcache_lock); 05653 return 0; 05654 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2285 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02286 { 02287 int which = 0; 02288 struct iax2_peer *peer; 02289 char *res = NULL; 02290 int wordlen = strlen(word); 02291 struct ao2_iterator i; 02292 02293 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02294 if (pos != 3) 02295 return NULL; 02296 02297 i = ao2_iterator_init(peers, 0); 02298 while ((peer = ao2_iterator_next(&i))) { 02299 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02300 res = ast_strdup(peer->name); 02301 peer_unref(peer); 02302 break; 02303 } 02304 peer_unref(peer); 02305 } 02306 02307 return res; 02308 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5656 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, 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, LOG_WARNING, 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_process().
05657 { 05658 int peercallno = 0; 05659 struct chan_iax2_pvt *pvt = iaxs[callno]; 05660 struct iax_frame *cur; 05661 jb_frame frame; 05662 05663 if (ies->callno) 05664 peercallno = ies->callno; 05665 05666 if (peercallno < 1) { 05667 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05668 return -1; 05669 } 05670 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05671 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05672 /* Reset sequence numbers */ 05673 pvt->oseqno = 0; 05674 pvt->rseqno = 0; 05675 pvt->iseqno = 0; 05676 pvt->aseqno = 0; 05677 pvt->peercallno = peercallno; 05678 pvt->transferring = TRANSFER_NONE; 05679 pvt->svoiceformat = -1; 05680 pvt->voiceformat = 0; 05681 pvt->svideoformat = -1; 05682 pvt->videoformat = 0; 05683 pvt->transfercallno = -1; 05684 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05685 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05686 /* reset jitterbuffer */ 05687 while(jb_getall(pvt->jb,&frame) == JB_OK) 05688 iax2_frame_free(frame.data); 05689 jb_reset(pvt->jb); 05690 pvt->lag = 0; 05691 pvt->last = 0; 05692 pvt->lastsent = 0; 05693 pvt->nextpred = 0; 05694 pvt->pingtime = DEFAULT_RETRY_TIME; 05695 AST_LIST_LOCK(&iaxq.queue); 05696 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05697 /* We must cancel any packets that would have been transmitted 05698 because now we're talking to someone new. It's okay, they 05699 were transmitted to someone that didn't care anyway. */ 05700 if (callno == cur->callno) 05701 cur->retries = -1; 05702 } 05703 AST_LIST_UNLOCK(&iaxq.queue); 05704 return 0; 05705 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1037 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().
01038 { 01039 int x; 01040 int power=-1; 01041 /* If it's 128 or smaller, just return it */ 01042 if (subclass < IAX_FLAG_SC_LOG) 01043 return subclass; 01044 /* Otherwise find its power */ 01045 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01046 if (subclass & (1 << x)) { 01047 if (power > -1) { 01048 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01049 return 0; 01050 } else 01051 power = x; 01052 } 01053 } 01054 return power | IAX_FLAG_SC_LOG; 01055 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6602 of file chan_iax2.c.
References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, 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, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.
Referenced by socket_process().
06603 { 06604 jb_info stats; 06605 jb_getinfo(pvt->jb, &stats); 06606 06607 memset(iep, 0, sizeof(*iep)); 06608 06609 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06610 if(stats.frames_in == 0) stats.frames_in = 1; 06611 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06612 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06613 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06614 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06615 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06616 }
static int create_addr | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2902 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
02903 { 02904 struct ast_hostent ahp; 02905 struct hostent *hp; 02906 struct iax2_peer *peer; 02907 int res = -1; 02908 02909 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02910 cai->sockfd = defaultsockfd; 02911 cai->maxtime = 0; 02912 sin->sin_family = AF_INET; 02913 02914 if (!(peer = find_peer(peername, 1))) { 02915 cai->found = 0; 02916 02917 hp = ast_gethostbyname(peername, &ahp); 02918 if (hp) { 02919 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02920 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02921 /* use global iax prefs for unknown peer/user */ 02922 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02923 return 0; 02924 } else { 02925 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02926 return -1; 02927 } 02928 } 02929 02930 cai->found = 1; 02931 02932 /* if the peer has no address (current or default), return failure */ 02933 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 02934 goto return_unref; 02935 02936 /* if the peer is being monitored and is currently unreachable, return failure */ 02937 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 02938 goto return_unref; 02939 02940 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02941 cai->maxtime = peer->maxms; 02942 cai->capability = peer->capability; 02943 cai->encmethods = peer->encmethods; 02944 cai->sockfd = peer->sockfd; 02945 cai->adsi = peer->adsi; 02946 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02947 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02948 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02949 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02950 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02951 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02952 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02953 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02954 if (ast_strlen_zero(peer->dbsecret)) { 02955 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02956 } else { 02957 char *family; 02958 char *key = NULL; 02959 02960 family = ast_strdupa(peer->dbsecret); 02961 key = strchr(family, '/'); 02962 if (key) 02963 *key++ = '\0'; 02964 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02965 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02966 goto return_unref; 02967 } 02968 } 02969 02970 if (peer->addr.sin_addr.s_addr) { 02971 sin->sin_addr = peer->addr.sin_addr; 02972 sin->sin_port = peer->addr.sin_port; 02973 } else { 02974 sin->sin_addr = peer->defaddr.sin_addr; 02975 sin->sin_port = peer->defaddr.sin_port; 02976 } 02977 02978 res = 0; 02979 02980 return_unref: 02981 peer_unref(peer); 02982 02983 return res; 02984 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3996 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, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
03997 { 03998 int padding; 03999 unsigned char *workspace; 04000 04001 workspace = alloca(*datalen); 04002 memset(f, 0, sizeof(*f)); 04003 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04004 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04005 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04006 return -1; 04007 /* Decrypt */ 04008 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04009 04010 padding = 16 + (workspace[15] & 0xf); 04011 if (option_debug && iaxdebug) 04012 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04013 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04014 return -1; 04015 04016 *datalen -= padding; 04017 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04018 f->frametype = fh->type; 04019 if (f->frametype == AST_FRAME_VIDEO) { 04020 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04021 } else { 04022 f->subclass = uncompress_subclass(fh->csub); 04023 } 04024 } else { 04025 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04026 if (option_debug && iaxdebug) 04027 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04028 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04029 return -1; 04030 /* Decrypt */ 04031 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04032 padding = 16 + (workspace[15] & 0x0f); 04033 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04034 return -1; 04035 *datalen -= padding; 04036 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04037 } 04038 return 0; 04039 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4082 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), iax2_registry::secret, and strsep().
Referenced by socket_process().
04083 { 04084 int res=-1; 04085 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04086 /* Search for possible keys, given secrets */ 04087 struct MD5Context md5; 04088 unsigned char digest[16]; 04089 char *tmppw, *stringp; 04090 04091 tmppw = ast_strdupa(iaxs[callno]->secret); 04092 stringp = tmppw; 04093 while ((tmppw = strsep(&stringp, ";"))) { 04094 MD5Init(&md5); 04095 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04096 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04097 MD5Final(digest, &md5); 04098 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04099 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04100 if (!res) { 04101 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04102 break; 04103 } 04104 } 04105 } else 04106 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04107 return res; 04108 }
static void defer_full_frame | ( | struct iax2_thread * | from_here, | |
struct iax2_thread * | to_here | |||
) | [static] |
Queue the last read full frame for processing by a certain thread.
If there are already any full frames queued, they are sorted by sequence number.
Definition at line 6664 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
06665 { 06666 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06667 struct ast_iax2_full_hdr *fh, *cur_fh; 06668 06669 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06670 return; 06671 06672 pkt_buf->len = from_here->buf_len; 06673 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06674 06675 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06676 ast_mutex_lock(&to_here->lock); 06677 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06678 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06679 if (fh->oseqno < cur_fh->oseqno) { 06680 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06681 break; 06682 } 06683 } 06684 AST_LIST_TRAVERSE_SAFE_END 06685 06686 if (!cur_pkt_buf) 06687 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06688 06689 ast_mutex_unlock(&to_here->lock); 06690 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9530 of file chan_iax2.c.
References ao2_callback(), ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, user_delme_cb(), and users.
09531 { 09532 struct iax2_registry *reg; 09533 09534 ao2_callback(users, 0, user_delme_cb, NULL); 09535 09536 AST_LIST_LOCK(®istrations); 09537 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09538 if (reg->expire > -1) 09539 ast_sched_del(sched, reg->expire); 09540 if (reg->callno) { 09541 ast_mutex_lock(&iaxsl[reg->callno]); 09542 if (iaxs[reg->callno]) { 09543 iaxs[reg->callno]->reg = NULL; 09544 iax2_destroy(reg->callno); 09545 } 09546 ast_mutex_unlock(&iaxsl[reg->callno]); 09547 } 09548 if (reg->dnsmgr) 09549 ast_dnsmgr_release(reg->dnsmgr); 09550 free(reg); 09551 } 09552 AST_LIST_UNLOCK(®istrations); 09553 09554 ao2_callback(peers, 0, peer_delme_cb, NULL); 09555 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1528 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01529 { 01530 /* Close firmware */ 01531 if (cur->fwh) { 01532 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01533 } 01534 close(cur->fd); 01535 free(cur); 01536 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6436 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_ie_data::buf, 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, iaxs, iaxsl, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06437 { 06438 unsigned short dpstatus = 0; 06439 struct iax_ie_data ied1; 06440 int mm; 06441 06442 memset(&ied1, 0, sizeof(ied1)); 06443 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06444 /* Must be started */ 06445 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06446 dpstatus = IAX_DPSTATUS_EXISTS; 06447 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06448 dpstatus = IAX_DPSTATUS_CANEXIST; 06449 } else { 06450 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06451 } 06452 if (ast_ignore_pattern(context, callednum)) 06453 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06454 if (mm) 06455 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06456 if (!skiplock) 06457 ast_mutex_lock(&iaxsl[callno]); 06458 if (iaxs[callno]) { 06459 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06460 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06461 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06462 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06463 } 06464 if (!skiplock) 06465 ast_mutex_unlock(&iaxsl[callno]); 06466 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6468 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().
06469 { 06470 /* Look up for dpreq */ 06471 struct dpreq_data *dpr = data; 06472 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06473 if (dpr->callerid) 06474 free(dpr->callerid); 06475 free(dpr); 06476 return NULL; 06477 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4041 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, LOG_DEBUG, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
04042 { 04043 int padding; 04044 unsigned char *workspace; 04045 workspace = alloca(*datalen + 32); 04046 if (!workspace) 04047 return -1; 04048 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04049 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04050 if (option_debug && iaxdebug) 04051 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04052 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04053 padding = 16 + (padding & 0xf); 04054 memcpy(workspace, poo, padding); 04055 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04056 workspace[15] &= 0xf0; 04057 workspace[15] |= (padding & 0xf); 04058 if (option_debug && iaxdebug) 04059 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]); 04060 *datalen += padding; 04061 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04062 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04063 memcpy(poo, workspace + *datalen - 32, 32); 04064 } else { 04065 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04066 if (option_debug && iaxdebug) 04067 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04068 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04069 padding = 16 + (padding & 0xf); 04070 memcpy(workspace, poo, padding); 04071 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04072 workspace[15] &= 0xf0; 04073 workspace[15] |= (padding & 0x0f); 04074 *datalen += padding; 04075 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04076 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04077 memcpy(poo, workspace + *datalen - 32, 32); 04078 } 04079 return 0; 04080 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5888 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
05889 { 05890 #ifdef SCHED_MULTITHREADED 05891 if (schedule_action(__expire_registry, data)) 05892 #endif 05893 __expire_registry(data); 05894 return 0; 05895 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static, read] |
Definition at line 10083 of file chan_iax2.c.
References ast_calloc, 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, iax2_registry::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
10084 { 10085 struct iax2_dpcache *dp, *prev = NULL, *next; 10086 struct timeval tv; 10087 int x; 10088 int com[2]; 10089 int timeout; 10090 int old=0; 10091 int outfd; 10092 int abort; 10093 int callno; 10094 struct ast_channel *c; 10095 struct ast_frame *f; 10096 gettimeofday(&tv, NULL); 10097 dp = dpcache; 10098 while(dp) { 10099 next = dp->next; 10100 /* Expire old caches */ 10101 if (ast_tvcmp(tv, dp->expiry) > 0) { 10102 /* It's expired, let it disappear */ 10103 if (prev) 10104 prev->next = dp->next; 10105 else 10106 dpcache = dp->next; 10107 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10108 /* Free memory and go again */ 10109 free(dp); 10110 } else { 10111 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); 10112 } 10113 dp = next; 10114 continue; 10115 } 10116 /* We found an entry that matches us! */ 10117 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10118 break; 10119 prev = dp; 10120 dp = next; 10121 } 10122 if (!dp) { 10123 /* No matching entry. Create a new one. */ 10124 /* First, can we make a callno? */ 10125 callno = cache_get_callno_locked(data); 10126 if (callno < 0) { 10127 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10128 return NULL; 10129 } 10130 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10131 ast_mutex_unlock(&iaxsl[callno]); 10132 return NULL; 10133 } 10134 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10135 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10136 gettimeofday(&dp->expiry, NULL); 10137 dp->orig = dp->expiry; 10138 /* Expires in 30 mins by default */ 10139 dp->expiry.tv_sec += iaxdefaultdpcache; 10140 dp->next = dpcache; 10141 dp->flags = CACHE_FLAG_PENDING; 10142 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10143 dp->waiters[x] = -1; 10144 dpcache = dp; 10145 dp->peer = iaxs[callno]->dpentries; 10146 iaxs[callno]->dpentries = dp; 10147 /* Send the request if we're already up */ 10148 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10149 iax2_dprequest(dp, callno); 10150 ast_mutex_unlock(&iaxsl[callno]); 10151 } 10152 /* By here we must have a dp */ 10153 if (dp->flags & CACHE_FLAG_PENDING) { 10154 /* Okay, here it starts to get nasty. We need a pipe now to wait 10155 for a reply to come back so long as it's pending */ 10156 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10157 /* Find an empty slot */ 10158 if (dp->waiters[x] < 0) 10159 break; 10160 } 10161 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10162 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10163 return NULL; 10164 } 10165 if (pipe(com)) { 10166 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10167 return NULL; 10168 } 10169 dp->waiters[x] = com[1]; 10170 /* Okay, now we wait */ 10171 timeout = iaxdefaulttimeout * 1000; 10172 /* Temporarily unlock */ 10173 ast_mutex_unlock(&dpcache_lock); 10174 /* Defer any dtmf */ 10175 if (chan) 10176 old = ast_channel_defer_dtmf(chan); 10177 abort = 0; 10178 while(timeout) { 10179 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10180 if (outfd > -1) { 10181 break; 10182 } 10183 if (c) { 10184 f = ast_read(c); 10185 if (f) 10186 ast_frfree(f); 10187 else { 10188 /* Got hung up on, abort! */ 10189 break; 10190 abort = 1; 10191 } 10192 } 10193 } 10194 if (!timeout) { 10195 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10196 } 10197 ast_mutex_lock(&dpcache_lock); 10198 dp->waiters[x] = -1; 10199 close(com[1]); 10200 close(com[0]); 10201 if (abort) { 10202 /* Don't interpret anything, just abort. Not sure what th epoint 10203 of undeferring dtmf on a hung up channel is but hey whatever */ 10204 if (!old && chan) 10205 ast_channel_undefer_dtmf(chan); 10206 return NULL; 10207 } 10208 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10209 /* Now to do non-independent analysis the results of our wait */ 10210 if (dp->flags & CACHE_FLAG_PENDING) { 10211 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10212 pending. Don't let it take as long to timeout. */ 10213 dp->flags &= ~CACHE_FLAG_PENDING; 10214 dp->flags |= CACHE_FLAG_TIMEOUT; 10215 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10216 systems without leaving it unavailable once the server comes back online */ 10217 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10218 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10219 if (dp->waiters[x] > -1) 10220 write(dp->waiters[x], "asdf", 4); 10221 } 10222 } 10223 /* Our caller will obtain the rest */ 10224 if (!old && chan) 10225 ast_channel_undefer_dtmf(chan); 10226 } 10227 return dp; 10228 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd | |||
) | [static] |
Definition at line 1342 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_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, 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, 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_process().
01343 { 01344 int res = 0; 01345 int x; 01346 struct timeval now; 01347 char host[80]; 01348 01349 if (new <= NEW_ALLOW) { 01350 /* Look for an existing connection first */ 01351 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01352 ast_mutex_lock(&iaxsl[x]); 01353 if (iaxs[x]) { 01354 /* Look for an exact match */ 01355 if (match(sin, callno, dcallno, iaxs[x])) { 01356 res = x; 01357 } 01358 } 01359 ast_mutex_unlock(&iaxsl[x]); 01360 } 01361 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01362 ast_mutex_lock(&iaxsl[x]); 01363 if (iaxs[x]) { 01364 /* Look for an exact match */ 01365 if (match(sin, callno, dcallno, iaxs[x])) { 01366 res = x; 01367 } 01368 } 01369 ast_mutex_unlock(&iaxsl[x]); 01370 } 01371 } 01372 if ((res < 1) && (new >= NEW_ALLOW)) { 01373 /* It may seem odd that we look through the peer list for a name for 01374 * this *incoming* call. Well, it is weird. However, users don't 01375 * have an IP address/port number that we can match against. So, 01376 * this is just checking for a peer that has that IP/port and 01377 * assuming that we have a user of the same name. This isn't always 01378 * correct, but it will be changed if needed after authentication. */ 01379 if (!iax2_getpeername(*sin, host, sizeof(host))) 01380 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01381 gettimeofday(&now, NULL); 01382 for (x=1;x<TRUNK_CALL_START;x++) { 01383 /* Find first unused call number that hasn't been used in a while */ 01384 ast_mutex_lock(&iaxsl[x]); 01385 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01386 ast_mutex_unlock(&iaxsl[x]); 01387 } 01388 /* We've still got lock held if we found a spot */ 01389 if (x >= TRUNK_CALL_START) { 01390 ast_log(LOG_WARNING, "No more space\n"); 01391 return 0; 01392 } 01393 iaxs[x] = new_iax(sin, host); 01394 update_max_nontrunk(); 01395 if (iaxs[x]) { 01396 if (option_debug && iaxdebug) 01397 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01398 iaxs[x]->sockfd = sockfd; 01399 iaxs[x]->addr.sin_port = sin->sin_port; 01400 iaxs[x]->addr.sin_family = sin->sin_family; 01401 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01402 iaxs[x]->peercallno = callno; 01403 iaxs[x]->callno = x; 01404 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01405 iaxs[x]->expiry = min_reg_expire; 01406 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01407 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01408 iaxs[x]->amaflags = amaflags; 01409 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01410 01411 ast_string_field_set(iaxs[x], accountcode, accountcode); 01412 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01413 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01414 } else { 01415 ast_log(LOG_WARNING, "Out of resources\n"); 01416 ast_mutex_unlock(&iaxsl[x]); 01417 return 0; 01418 } 01419 ast_mutex_unlock(&iaxsl[x]); 01420 res = x; 01421 } 01422 return res; 01423 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 893 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, iax2_thread::ffinfo, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00894 { 00895 pthread_attr_t attr; 00896 struct iax2_thread *thread = NULL; 00897 00898 /* Pop the head of the list off */ 00899 AST_LIST_LOCK(&idle_list); 00900 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00901 AST_LIST_UNLOCK(&idle_list); 00902 00903 /* If no idle thread is available from the regular list, try dynamic */ 00904 if (thread == NULL) { 00905 AST_LIST_LOCK(&dynamic_list); 00906 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00907 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00908 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00909 /* We need to MAKE a thread! */ 00910 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00911 thread->threadnum = iaxdynamicthreadcount; 00912 thread->type = IAX_TYPE_DYNAMIC; 00913 ast_mutex_init(&thread->lock); 00914 ast_cond_init(&thread->cond, NULL); 00915 pthread_attr_init(&attr); 00916 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00917 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00918 free(thread); 00919 thread = NULL; 00920 } else { 00921 /* All went well and the thread is up, so increment our count */ 00922 iaxdynamicthreadcount++; 00923 00924 /* Wait for the thread to be ready before returning it to the caller */ 00925 while (!thread->ready_for_signal) 00926 usleep(1); 00927 } 00928 } 00929 } 00930 AST_LIST_UNLOCK(&dynamic_list); 00931 } 00932 00933 /* this thread is not processing a full frame (since it is idle), 00934 so ensure that the field for the full frame call number is empty */ 00935 if (thread) 00936 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00937 00938 return thread; 00939 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1115 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01116 { 01117 struct iax2_peer *peer = NULL; 01118 struct iax2_peer tmp_peer = { 01119 .name = name, 01120 }; 01121 01122 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01123 01124 /* Now go for realtime if applicable */ 01125 if(!peer && realtime) 01126 peer = realtime_peer(name, NULL); 01127 01128 return peer; 01129 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 3850 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, iax2_trunk_peer::next, option_debug, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process().
03851 { 03852 struct iax2_trunk_peer *tpeer; 03853 03854 /* Finds and locks trunk peer */ 03855 ast_mutex_lock(&tpeerlock); 03856 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03857 /* We don't lock here because tpeer->addr *never* changes */ 03858 if (!inaddrcmp(&tpeer->addr, sin)) { 03859 ast_mutex_lock(&tpeer->lock); 03860 break; 03861 } 03862 } 03863 if (!tpeer) { 03864 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03865 ast_mutex_init(&tpeer->lock); 03866 tpeer->lastsent = 9999; 03867 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03868 tpeer->trunkact = ast_tvnow(); 03869 ast_mutex_lock(&tpeer->lock); 03870 tpeer->next = tpeers; 03871 tpeer->sockfd = fd; 03872 tpeers = tpeer; 03873 #ifdef SO_NO_CHECK 03874 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03875 #endif 03876 if (option_debug) 03877 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03878 } 03879 } 03880 ast_mutex_unlock(&tpeerlock); 03881 return tpeer; 03882 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3677 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03678 { 03679 long ms; /* NOT unsigned */ 03680 if (ast_tvzero(iaxs[callno]->rxcore)) { 03681 /* Initialize rxcore time if appropriate */ 03682 gettimeofday(&iaxs[callno]->rxcore, NULL); 03683 /* Round to nearest 20ms so traces look pretty */ 03684 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03685 } 03686 /* Calculate difference between trunk and channel */ 03687 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03688 /* Return as the sum of trunk time and the difference between trunk and real time */ 03689 return ms + ts; 03690 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8692 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08693 { 08694 struct iax2_context *conl; 08695 while(con) { 08696 conl = con; 08697 con = con->next; 08698 free(conl); 08699 } 08700 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10352 of file chan_iax2.c.
References iax2_peer::addr, iax2_registry::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_registry::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10353 { 10354 struct iax2_peer *peer; 10355 char *peername, *colname; 10356 10357 peername = ast_strdupa(data); 10358 10359 /* if our channel, return the IP address of the endpoint of current channel */ 10360 if (!strcmp(peername,"CURRENTCHANNEL")) { 10361 unsigned short callno; 10362 if (chan->tech != &iax2_tech) 10363 return -1; 10364 callno = PTR_TO_CALLNO(chan->tech_pvt); 10365 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10366 return 0; 10367 } 10368 10369 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10370 *colname++ = '\0'; 10371 else if ((colname = strchr(peername, '|'))) 10372 *colname++ = '\0'; 10373 else 10374 colname = "ip"; 10375 10376 if (!(peer = find_peer(peername, 1))) 10377 return -1; 10378 10379 if (!strcasecmp(colname, "ip")) { 10380 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10381 } else if (!strcasecmp(colname, "status")) { 10382 peer_status(peer, buf, len); 10383 } else if (!strcasecmp(colname, "mailbox")) { 10384 ast_copy_string(buf, peer->mailbox, len); 10385 } else if (!strcasecmp(colname, "context")) { 10386 ast_copy_string(buf, peer->context, len); 10387 } else if (!strcasecmp(colname, "expire")) { 10388 snprintf(buf, len, "%d", peer->expire); 10389 } else if (!strcasecmp(colname, "dynamic")) { 10390 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10391 } else if (!strcasecmp(colname, "callerid_name")) { 10392 ast_copy_string(buf, peer->cid_name, len); 10393 } else if (!strcasecmp(colname, "callerid_num")) { 10394 ast_copy_string(buf, peer->cid_num, len); 10395 } else if (!strcasecmp(colname, "codecs")) { 10396 ast_getformatname_multiple(buf, len -1, peer->capability); 10397 } else if (!strncasecmp(colname, "codec[", 6)) { 10398 char *codecnum, *ptr; 10399 int index = 0, codec = 0; 10400 10401 codecnum = strchr(colname, '['); 10402 *codecnum = '\0'; 10403 codecnum++; 10404 if ((ptr = strchr(codecnum, ']'))) { 10405 *ptr = '\0'; 10406 } 10407 index = atoi(codecnum); 10408 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10409 ast_copy_string(buf, ast_getformatname(codec), len); 10410 } 10411 } 10412 10413 peer_unref(peer); 10414 10415 return 0; 10416 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8920 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08921 { 08922 int methods = 0; 08923 if (strstr(value, "rsa")) 08924 methods |= IAX_AUTH_RSA; 08925 if (strstr(value, "md5")) 08926 methods |= IAX_AUTH_MD5; 08927 if (strstr(value, "plaintext")) 08928 methods |= IAX_AUTH_PLAINTEXT; 08929 return methods; 08930 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1002 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01003 { 01004 int e; 01005 if (!strcasecmp(s, "aes128")) 01006 e = IAX_ENCRYPT_AES128; 01007 else if (ast_true(s)) 01008 e = IAX_ENCRYPT_AES128; 01009 else 01010 e = 0; 01011 return e; 01012 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2516 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02517 { 02518 #ifdef SCHED_MULTITHREADED 02519 if (schedule_action(__get_from_jb, data)) 02520 #endif 02521 __get_from_jb(data); 02522 return 0; 02523 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6634 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and socket_process().
Referenced by iax2_process_thread().
06635 { 06636 struct iax2_pkt_buf *pkt_buf; 06637 06638 ast_mutex_lock(&thread->lock); 06639 06640 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06641 ast_mutex_unlock(&thread->lock); 06642 06643 thread->buf = pkt_buf->buf; 06644 thread->buf_len = pkt_buf->len; 06645 thread->buf_size = pkt_buf->len + 1; 06646 06647 socket_process(thread); 06648 06649 thread->buf = NULL; 06650 ast_free(pkt_buf); 06651 06652 ast_mutex_lock(&thread->lock); 06653 } 06654 06655 ast_mutex_unlock(&thread->lock); 06656 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1816 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
01817 { 01818 /* XXX Ideally we should figure out why an error occured and then abort those 01819 rather than continuing to try. Unfortunately, the published interface does 01820 not seem to work XXX */ 01821 #if 0 01822 struct sockaddr_in *sin; 01823 int res; 01824 struct msghdr m; 01825 struct sock_extended_err e; 01826 m.msg_name = NULL; 01827 m.msg_namelen = 0; 01828 m.msg_iov = NULL; 01829 m.msg_control = &e; 01830 m.msg_controllen = sizeof(e); 01831 m.msg_flags = 0; 01832 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01833 if (res < 0) 01834 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01835 else { 01836 if (m.msg_controllen) { 01837 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01838 if (sin) 01839 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01840 else 01841 ast_log(LOG_WARNING, "No address detected??\n"); 01842 } else { 01843 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01844 } 01845 } 01846 #endif 01847 return 0; 01848 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5708 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), ast_sched_del(), ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05709 { 05710 struct iax2_registry *reg; 05711 /* Start pessimistic */ 05712 char peer[256] = ""; 05713 char msgstatus[60]; 05714 int refresh = 60; 05715 char ourip[256] = "<Unspecified>"; 05716 struct sockaddr_in oldus; 05717 struct sockaddr_in us; 05718 int oldmsgs; 05719 05720 memset(&us, 0, sizeof(us)); 05721 if (ies->apparent_addr) 05722 bcopy(ies->apparent_addr, &us, sizeof(us)); 05723 if (ies->username) 05724 ast_copy_string(peer, ies->username, sizeof(peer)); 05725 if (ies->refresh) 05726 refresh = ies->refresh; 05727 if (ies->calling_number) { 05728 /* We don't do anything with it really, but maybe we should */ 05729 } 05730 reg = iaxs[callno]->reg; 05731 if (!reg) { 05732 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05733 return -1; 05734 } 05735 memcpy(&oldus, ®->us, sizeof(oldus)); 05736 oldmsgs = reg->messages; 05737 if (inaddrcmp(®->addr, sin)) { 05738 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05739 return -1; 05740 } 05741 memcpy(®->us, &us, sizeof(reg->us)); 05742 if (ies->msgcount >= 0) 05743 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05744 /* always refresh the registration at the interval requested by the server 05745 we are registering to 05746 */ 05747 reg->refresh = refresh; 05748 if (reg->expire > -1) 05749 ast_sched_del(sched, reg->expire); 05750 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05751 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05752 if (option_verbose > 2) { 05753 if (reg->messages > 255) 05754 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05755 else if (reg->messages > 1) 05756 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05757 else if (reg->messages > 0) 05758 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05759 else 05760 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05761 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05762 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05763 } 05764 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05765 } 05766 reg->regstate = REG_STATE_REGISTERED; 05767 return 0; 05768 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3498 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), iax2_registry::callno, LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03499 { 03500 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03501 if (option_debug) 03502 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03503 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03504 }
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 3348 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, lock_both(), LOG_WARNING, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, tv, unlock_both(), and VERBOSE_PREFIX_3.
03349 { 03350 struct ast_channel *cs[3]; 03351 struct ast_channel *who, *other; 03352 int to = -1; 03353 int res = -1; 03354 int transferstarted=0; 03355 struct ast_frame *f; 03356 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03357 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03358 struct timeval waittimer = {0, 0}, tv; 03359 03360 lock_both(callno0, callno1); 03361 if (!iaxs[callno0] || !iaxs[callno1]) { 03362 unlock_both(callno0, callno1); 03363 return AST_BRIDGE_FAILED; 03364 } 03365 /* Put them in native bridge mode */ 03366 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03367 iaxs[callno0]->bridgecallno = callno1; 03368 iaxs[callno1]->bridgecallno = callno0; 03369 } 03370 unlock_both(callno0, callno1); 03371 03372 /* If not, try to bridge until we can execute a transfer, if we can */ 03373 cs[0] = c0; 03374 cs[1] = c1; 03375 for (/* ever */;;) { 03376 /* Check in case we got masqueraded into */ 03377 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03378 if (option_verbose > 2) 03379 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03380 /* Remove from native mode */ 03381 if (c0->tech == &iax2_tech) { 03382 ast_mutex_lock(&iaxsl[callno0]); 03383 iaxs[callno0]->bridgecallno = 0; 03384 ast_mutex_unlock(&iaxsl[callno0]); 03385 } 03386 if (c1->tech == &iax2_tech) { 03387 ast_mutex_lock(&iaxsl[callno1]); 03388 iaxs[callno1]->bridgecallno = 0; 03389 ast_mutex_unlock(&iaxsl[callno1]); 03390 } 03391 return AST_BRIDGE_FAILED_NOWARN; 03392 } 03393 if (c0->nativeformats != c1->nativeformats) { 03394 if (option_verbose > 2) { 03395 char buf0[255]; 03396 char buf1[255]; 03397 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03398 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03399 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03400 } 03401 /* Remove from native mode */ 03402 lock_both(callno0, callno1); 03403 if (iaxs[callno0]) 03404 iaxs[callno0]->bridgecallno = 0; 03405 if (iaxs[callno1]) 03406 iaxs[callno1]->bridgecallno = 0; 03407 unlock_both(callno0, callno1); 03408 return AST_BRIDGE_FAILED_NOWARN; 03409 } 03410 /* check if transfered and if we really want native bridging */ 03411 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03412 /* Try the transfer */ 03413 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03414 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03415 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03416 transferstarted = 1; 03417 } 03418 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03419 /* Call has been transferred. We're no longer involved */ 03420 gettimeofday(&tv, NULL); 03421 if (ast_tvzero(waittimer)) { 03422 waittimer = tv; 03423 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03424 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03425 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03426 *fo = NULL; 03427 *rc = c0; 03428 res = AST_BRIDGE_COMPLETE; 03429 break; 03430 } 03431 } 03432 to = 1000; 03433 who = ast_waitfor_n(cs, 2, &to); 03434 if (timeoutms > -1) { 03435 timeoutms -= (1000 - to); 03436 if (timeoutms < 0) 03437 timeoutms = 0; 03438 } 03439 if (!who) { 03440 if (!timeoutms) { 03441 res = AST_BRIDGE_RETRY; 03442 break; 03443 } 03444 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03445 res = AST_BRIDGE_FAILED; 03446 break; 03447 } 03448 continue; 03449 } 03450 f = ast_read(who); 03451 if (!f) { 03452 *fo = NULL; 03453 *rc = who; 03454 res = AST_BRIDGE_COMPLETE; 03455 break; 03456 } 03457 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03458 *fo = f; 03459 *rc = who; 03460 res = AST_BRIDGE_COMPLETE; 03461 break; 03462 } 03463 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03464 if ((f->frametype == AST_FRAME_VOICE) || 03465 (f->frametype == AST_FRAME_TEXT) || 03466 (f->frametype == AST_FRAME_VIDEO) || 03467 (f->frametype == AST_FRAME_IMAGE) || 03468 (f->frametype == AST_FRAME_DTMF)) { 03469 /* monitored dtmf take out of the bridge. 03470 * check if we monitor the specific source. 03471 */ 03472 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03473 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03474 *rc = who; 03475 *fo = f; 03476 res = AST_BRIDGE_COMPLETE; 03477 /* Remove from native mode */ 03478 break; 03479 } 03480 /* everything else goes to the other side */ 03481 ast_write(other, f); 03482 } 03483 ast_frfree(f); 03484 /* Swap who gets priority */ 03485 cs[2] = cs[0]; 03486 cs[0] = cs[1]; 03487 cs[1] = cs[2]; 03488 } 03489 lock_both(callno0, callno1); 03490 if(iaxs[callno0]) 03491 iaxs[callno0]->bridgecallno = 0; 03492 if(iaxs[callno1]) 03493 iaxs[callno1]->bridgecallno = 0; 03494 unlock_both(callno0, callno1); 03495 return res; 03496 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3096 of file chan_iax2.c.
References ast_channel::_state, create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), iax_ie_data::buf, iax2_registry::callno, 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_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), iax2_sched_add(), 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_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, iax2_registry::secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, and parsed_dial_string::username.
03097 { 03098 struct sockaddr_in sin; 03099 char *l=NULL, *n=NULL, *tmpstr; 03100 struct iax_ie_data ied; 03101 char *defaultrdest = "s"; 03102 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03103 struct parsed_dial_string pds; 03104 struct create_addr_info cai; 03105 03106 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03107 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03108 return -1; 03109 } 03110 03111 memset(&cai, 0, sizeof(cai)); 03112 cai.encmethods = iax2_encryption; 03113 03114 memset(&pds, 0, sizeof(pds)); 03115 tmpstr = ast_strdupa(dest); 03116 parse_dial_string(tmpstr, &pds); 03117 03118 if (!pds.exten) 03119 pds.exten = defaultrdest; 03120 03121 if (create_addr(pds.peer, &sin, &cai)) { 03122 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03123 return -1; 03124 } 03125 03126 if (!pds.username && !ast_strlen_zero(cai.username)) 03127 pds.username = cai.username; 03128 if (!pds.password && !ast_strlen_zero(cai.secret)) 03129 pds.password = cai.secret; 03130 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03131 pds.key = cai.outkey; 03132 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03133 pds.context = cai.peercontext; 03134 03135 /* Keep track of the context for outgoing calls too */ 03136 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03137 03138 if (pds.port) 03139 sin.sin_port = htons(atoi(pds.port)); 03140 03141 l = c->cid.cid_num; 03142 n = c->cid.cid_name; 03143 03144 /* Now build request */ 03145 memset(&ied, 0, sizeof(ied)); 03146 03147 /* On new call, first IE MUST be IAX version of caller */ 03148 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03149 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03150 if (pds.options && strchr(pds.options, 'a')) { 03151 /* Request auto answer */ 03152 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03153 } 03154 03155 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03156 03157 if (l) { 03158 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03159 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03160 } else { 03161 if (n) 03162 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03163 else 03164 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03165 } 03166 03167 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03168 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03169 03170 if (n) 03171 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03172 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03173 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03174 03175 if (!ast_strlen_zero(c->language)) 03176 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03177 if (!ast_strlen_zero(c->cid.cid_dnid)) 03178 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03179 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03180 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03181 03182 if (pds.context) 03183 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03184 03185 if (pds.username) 03186 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03187 03188 if (cai.encmethods) 03189 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03190 03191 ast_mutex_lock(&iaxsl[callno]); 03192 03193 if (!ast_strlen_zero(c->context)) 03194 ast_string_field_set(iaxs[callno], context, c->context); 03195 03196 if (pds.username) 03197 ast_string_field_set(iaxs[callno], username, pds.username); 03198 03199 iaxs[callno]->encmethods = cai.encmethods; 03200 03201 iaxs[callno]->adsi = cai.adsi; 03202 03203 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03204 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03205 03206 if (pds.key) 03207 ast_string_field_set(iaxs[callno], outkey, pds.key); 03208 if (pds.password) 03209 ast_string_field_set(iaxs[callno], secret, pds.password); 03210 03211 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03212 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03213 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03214 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03215 03216 if (iaxs[callno]->maxtime) { 03217 /* Initialize pingtime and auto-congest time */ 03218 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03219 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03220 } else if (autokill) { 03221 iaxs[callno]->pingtime = autokill / 2; 03222 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03223 } 03224 03225 /* send the command using the appropriate socket for this peer */ 03226 iaxs[callno]->sockfd = cai.sockfd; 03227 03228 /* Transmit the string in a "NEW" request */ 03229 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03230 03231 ast_mutex_unlock(&iaxsl[callno]); 03232 ast_setstate(c, AST_STATE_RINGING); 03233 03234 return 0; 03235 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 10254 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.
10255 { 10256 int res = 0; 10257 struct iax2_dpcache *dp; 10258 #if 0 10259 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10260 #endif 10261 if ((priority != 1) && (priority != 2)) 10262 return 0; 10263 ast_mutex_lock(&dpcache_lock); 10264 dp = find_cache(chan, data, context, exten, priority); 10265 if (dp) { 10266 if (dp->flags & CACHE_FLAG_CANEXIST) 10267 res= 1; 10268 } 10269 ast_mutex_unlock(&dpcache_lock); 10270 if (!dp) { 10271 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10272 } 10273 return res; 10274 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3008 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03009 { 03010 time_t t; 03011 struct tm tm; 03012 unsigned int tmp; 03013 time(&t); 03014 if (!ast_strlen_zero(tz)) 03015 ast_localtime(&t, &tm, tz); 03016 else 03017 ast_localtime(&t, &tm, NULL); 03018 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03019 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03020 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03021 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03022 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03023 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03024 return tmp; 03025 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1959 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, lastused, ast_channel::lock, LOG_NOTICE, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, update_max_trunk(), and chan_iax2_pvt::vars.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01960 { 01961 struct chan_iax2_pvt *pvt; 01962 struct iax_frame *cur; 01963 struct ast_channel *owner; 01964 01965 retry: 01966 pvt = iaxs[callno]; 01967 gettimeofday(&lastused[callno], NULL); 01968 01969 owner = pvt ? pvt->owner : NULL; 01970 01971 if (owner) { 01972 if (ast_mutex_trylock(&owner->lock)) { 01973 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01974 ast_mutex_unlock(&iaxsl[callno]); 01975 usleep(1); 01976 ast_mutex_lock(&iaxsl[callno]); 01977 goto retry; 01978 } 01979 } 01980 if (!owner) 01981 iaxs[callno] = NULL; 01982 if (pvt) { 01983 if (!owner) 01984 pvt->owner = NULL; 01985 iax2_destroy_helper(pvt); 01986 01987 /* Already gone */ 01988 ast_set_flag(pvt, IAX_ALREADYGONE); 01989 01990 if (owner) { 01991 /* If there's an owner, prod it to give up */ 01992 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01993 * because we already hold the owner channel lock. */ 01994 ast_queue_hangup(owner); 01995 } 01996 01997 AST_LIST_LOCK(&iaxq.queue); 01998 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01999 /* Cancel any pending transmissions */ 02000 if (cur->callno == pvt->callno) 02001 cur->retries = -1; 02002 } 02003 AST_LIST_UNLOCK(&iaxq.queue); 02004 02005 if (pvt->reg) 02006 pvt->reg->callno = 0; 02007 if (!owner) { 02008 jb_frame frame; 02009 if (pvt->vars) { 02010 ast_variables_destroy(pvt->vars); 02011 pvt->vars = NULL; 02012 } 02013 02014 while (jb_getall(pvt->jb, &frame) == JB_OK) 02015 iax2_frame_free(frame.data); 02016 jb_destroy(pvt->jb); 02017 /* gotta free up the stringfields */ 02018 ast_string_field_free_memory(pvt); 02019 free(pvt); 02020 } 02021 } 02022 if (owner) { 02023 ast_mutex_unlock(&owner->lock); 02024 } 02025 if (callno & 0x4000) 02026 update_max_trunk(); 02027 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1896 of file chan_iax2.c.
References ao2_find(), ast_clear_flag, ast_sched_del(), ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, chan_iax2_pvt::pingid, user_unref(), and users.
Referenced by iax2_destroy(), iax2_predestroy(), and stop_stuff().
01897 { 01898 /* Decrement AUTHREQ count if needed */ 01899 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01900 struct iax2_user *user; 01901 struct iax2_user tmp_user = { 01902 .name = pvt->username, 01903 }; 01904 01905 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01906 if (user) { 01907 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01908 user_unref(user); 01909 } 01910 01911 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01912 } 01913 /* No more pings or lagrq's */ 01914 if (pvt->pingid > -1) 01915 ast_sched_del(sched, pvt->pingid); 01916 pvt->pingid = -1; 01917 if (pvt->lagid > -1) 01918 ast_sched_del(sched, pvt->lagid); 01919 pvt->lagid = -1; 01920 if (pvt->autoid > -1) 01921 ast_sched_del(sched, pvt->autoid); 01922 pvt->autoid = -1; 01923 if (pvt->authid > -1) 01924 ast_sched_del(sched, pvt->authid); 01925 pvt->authid = -1; 01926 if (pvt->initid > -1) 01927 ast_sched_del(sched, pvt->initid); 01928 pvt->initid = -1; 01929 if (pvt->jbid > -1) 01930 ast_sched_del(sched, pvt->jbid); 01931 pvt->jbid = -1; 01932 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10441 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(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_DEBUG, iax2_peer::maxms, option_debug, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
10442 { 10443 struct parsed_dial_string pds; 10444 char *tmp = ast_strdupa(data); 10445 struct iax2_peer *p; 10446 int res = AST_DEVICE_INVALID; 10447 10448 memset(&pds, 0, sizeof(pds)); 10449 parse_dial_string(tmp, &pds); 10450 if (ast_strlen_zero(pds.peer)) 10451 return res; 10452 10453 if (option_debug > 2) 10454 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10455 10456 /* SLD: FIXME: second call to find_peer during registration */ 10457 if (!(p = find_peer(pds.peer, 1))) 10458 return res; 10459 10460 res = AST_DEVICE_UNAVAILABLE; 10461 if (option_debug > 2) 10462 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10463 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10464 10465 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10466 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10467 /* Peer is registered, or have default IP address 10468 and a valid registration */ 10469 if (p->historicms == 0 || p->historicms <= p->maxms) 10470 /* let the core figure out whether it is in use or not */ 10471 res = AST_DEVICE_UNKNOWN; 10472 } 10473 10474 peer_unref(p); 10475 10476 return res; 10477 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2635 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02636 { 02637 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02638 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2640 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02641 { 02642 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02643 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4761 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04762 { 04763 if (argc < 2 || argc > 3) 04764 return RESULT_SHOWUSAGE; 04765 iaxdebug = 1; 04766 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04767 return RESULT_SUCCESS; 04768 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4779 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04780 { 04781 if (argc < 3 || argc > 4) 04782 return RESULT_SHOWUSAGE; 04783 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04784 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04785 return RESULT_SUCCESS; 04786 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8417 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08418 { 08419 struct iax_ie_data ied; 08420 if (option_debug && iaxdebug) 08421 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08422 08423 if (reg->dnsmgr && 08424 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08425 /* Maybe the IP has changed, force DNS refresh */ 08426 ast_dnsmgr_refresh(reg->dnsmgr); 08427 } 08428 08429 /* 08430 * if IP has Changed, free allocated call to create a new one with new IP 08431 * call has the pointer to IP and must be updated to the new one 08432 */ 08433 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08434 ast_mutex_lock(&iaxsl[reg->callno]); 08435 iax2_destroy(reg->callno); 08436 ast_mutex_unlock(&iaxsl[reg->callno]); 08437 reg->callno = 0; 08438 } 08439 if (!reg->addr.sin_addr.s_addr) { 08440 if (option_debug && iaxdebug) 08441 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08442 /* Setup the next registration attempt */ 08443 if (reg->expire > -1) 08444 ast_sched_del(sched, reg->expire); 08445 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08446 return -1; 08447 } 08448 08449 if (!reg->callno) { 08450 if (option_debug) 08451 ast_log(LOG_DEBUG, "Allocate call number\n"); 08452 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, defaultsockfd); 08453 if (reg->callno < 1) { 08454 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08455 return -1; 08456 } else if (option_debug) 08457 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08458 iaxs[reg->callno]->reg = reg; 08459 } 08460 /* Schedule the next registration attempt */ 08461 if (reg->expire > -1) 08462 ast_sched_del(sched, reg->expire); 08463 /* Setup the next registration a little early */ 08464 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08465 /* Send the request */ 08466 memset(&ied, 0, sizeof(ied)); 08467 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08468 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08469 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08470 reg->regstate = REG_STATE_REGSENT; 08471 return 0; 08472 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5562 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05563 { 05564 #ifdef SCHED_MULTITHREADED 05565 if (schedule_action(__iax2_do_register_s, data)) 05566 #endif 05567 __iax2_do_register_s(data); 05568 return 0; 05569 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4770 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04771 { 04772 if (argc < 3 || argc > 4) 04773 return RESULT_SHOWUSAGE; 04774 iaxtrunkdebug = 1; 04775 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04776 return RESULT_SUCCESS; 04777 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6249 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
06250 { 06251 struct iax_ie_data ied; 06252 /* Auto-hangup with 30 seconds of inactivity */ 06253 if (iaxs[callno]->autoid > -1) 06254 ast_sched_del(sched, iaxs[callno]->autoid); 06255 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06256 memset(&ied, 0, sizeof(ied)); 06257 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06258 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06259 dp->flags |= CACHE_FLAG_TRANSMITTED; 06260 }
static int iax2_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Execute IAX2 dialplan switch.
Definition at line 10300 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.
10301 { 10302 char odata[256]; 10303 char req[256]; 10304 char *ncontext; 10305 struct iax2_dpcache *dp; 10306 struct ast_app *dial; 10307 #if 0 10308 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); 10309 #endif 10310 if (priority == 2) { 10311 /* Indicate status, can be overridden in dialplan */ 10312 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10313 if (dialstatus) { 10314 dial = pbx_findapp(dialstatus); 10315 if (dial) 10316 pbx_exec(chan, dial, ""); 10317 } 10318 return -1; 10319 } else if (priority != 1) 10320 return -1; 10321 ast_mutex_lock(&dpcache_lock); 10322 dp = find_cache(chan, data, context, exten, priority); 10323 if (dp) { 10324 if (dp->flags & CACHE_FLAG_EXISTS) { 10325 ast_copy_string(odata, data, sizeof(odata)); 10326 ncontext = strchr(odata, '/'); 10327 if (ncontext) { 10328 *ncontext = '\0'; 10329 ncontext++; 10330 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10331 } else { 10332 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10333 } 10334 if (option_verbose > 2) 10335 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10336 } else { 10337 ast_mutex_unlock(&dpcache_lock); 10338 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10339 return -1; 10340 } 10341 } 10342 ast_mutex_unlock(&dpcache_lock); 10343 dial = pbx_findapp("Dial"); 10344 if (dial) { 10345 return pbx_exec(chan, dial, req); 10346 } else { 10347 ast_log(LOG_WARNING, "No dial application registered\n"); 10348 } 10349 return -1; 10350 }
static int iax2_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 switch interface.
Definition at line 10231 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.
10232 { 10233 struct iax2_dpcache *dp; 10234 int res = 0; 10235 #if 0 10236 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10237 #endif 10238 if ((priority != 1) && (priority != 2)) 10239 return 0; 10240 ast_mutex_lock(&dpcache_lock); 10241 dp = find_cache(chan, data, context, exten, priority); 10242 if (dp) { 10243 if (dp->flags & CACHE_FLAG_EXISTS) 10244 res= 1; 10245 } 10246 ast_mutex_unlock(&dpcache_lock); 10247 if (!dp) { 10248 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10249 } 10250 return res; 10251 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2662 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02663 { 02664 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02665 ast_mutex_lock(&iaxsl[callno]); 02666 if (iaxs[callno]) 02667 iaxs[callno]->owner = newchan; 02668 else 02669 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02670 ast_mutex_unlock(&iaxsl[callno]); 02671 return 0; 02672 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1425 of file chan_iax2.c.
References ast_sched_del(), iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), iax2_destroy(), and schedule_delivery().
01426 { 01427 if (fr->retrans > -1) 01428 ast_sched_del(sched, fr->retrans); 01429 iax_frame_free(fr); 01430 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1155 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), peer_unref(), peers, and realtime_peer().
Referenced by find_callno().
01156 { 01157 struct iax2_peer *peer = NULL; 01158 int res = 0; 01159 struct ao2_iterator i; 01160 01161 i = ao2_iterator_init(peers, 0); 01162 while ((peer = ao2_iterator_next(&i))) { 01163 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01164 (peer->addr.sin_port == sin.sin_port)) { 01165 ast_copy_string(host, peer->name, len); 01166 peer_unref(peer); 01167 res = 1; 01168 break; 01169 } 01170 peer_unref(peer); 01171 } 01172 01173 if (!peer) { 01174 peer = realtime_peer(NULL, &sin); 01175 if (peer) { 01176 ast_copy_string(host, peer->name, len); 01177 peer_unref(peer); 01178 res = 1; 01179 } 01180 } 01181 01182 return res; 01183 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3560 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, peer_unref(), and peers.
Referenced by check_access().
03561 { 03562 struct iax2_peer *peer; 03563 int res = 0; 03564 struct ao2_iterator i; 03565 03566 i = ao2_iterator_init(peers, 0); 03567 while ((peer = ao2_iterator_next(&i))) { 03568 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03569 (peer->addr.sin_port == sin.sin_port)) { 03570 res = ast_test_flag(peer, IAX_TRUNK); 03571 peer_unref(peer); 03572 break; 03573 } 03574 peer_unref(peer); 03575 } 03576 03577 return res; 03578 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3237 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), iax_ie_data::buf, iax2_registry::callno, error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_DEBUG, option_debug, option_verbose, iax_ie_data::pos, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03238 { 03239 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03240 int alreadygone; 03241 struct iax_ie_data ied; 03242 memset(&ied, 0, sizeof(ied)); 03243 ast_mutex_lock(&iaxsl[callno]); 03244 if (callno && iaxs[callno]) { 03245 if (option_debug) 03246 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03247 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03248 /* Send the hangup unless we have had a transmission error or are already gone */ 03249 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03250 if (!iaxs[callno]->error && !alreadygone) { 03251 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03252 if (!iaxs[callno]) { 03253 ast_mutex_unlock(&iaxsl[callno]); 03254 return 0; 03255 } 03256 } 03257 /* Explicitly predestroy it */ 03258 iax2_predestroy(callno); 03259 /* If we were already gone to begin with, destroy us now */ 03260 if (alreadygone && iaxs[callno]) { 03261 if (option_debug) 03262 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03263 iax2_destroy(callno); 03264 } 03265 } 03266 ast_mutex_unlock(&iaxsl[callno]); 03267 if (option_verbose > 2) 03268 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03269 return 0; 03270 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3506 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03507 { 03508 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03509 struct chan_iax2_pvt *pvt; 03510 int res = 0; 03511 03512 if (option_debug && iaxdebug) 03513 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03514 03515 ast_mutex_lock(&iaxsl[callno]); 03516 pvt = iaxs[callno]; 03517 03518 switch (condition) { 03519 case AST_CONTROL_HOLD: 03520 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03521 ast_moh_start(c, data, pvt->mohinterpret); 03522 goto done; 03523 } 03524 break; 03525 case AST_CONTROL_UNHOLD: 03526 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03527 ast_moh_stop(c); 03528 goto done; 03529 } 03530 } 03531 03532 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03533 03534 done: 03535 ast_mutex_unlock(&iaxsl[callno]); 03536 03537 return res; 03538 }
static int iax2_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 Switch interface.
Definition at line 10277 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.
10278 { 10279 int res = 0; 10280 struct iax2_dpcache *dp; 10281 #if 0 10282 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10283 #endif 10284 if ((priority != 1) && (priority != 2)) 10285 return 0; 10286 ast_mutex_lock(&dpcache_lock); 10287 dp = find_cache(chan, data, context, exten, priority); 10288 if (dp) { 10289 if (dp->flags & CACHE_FLAG_MATCHMORE) 10290 res= 1; 10291 } 10292 ast_mutex_unlock(&dpcache_lock); 10293 if (!dp) { 10294 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10295 } 10296 return res; 10297 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4788 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04789 { 04790 if (argc < 3 || argc > 4) 04791 return RESULT_SHOWUSAGE; 04792 iaxdebug = 0; 04793 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04794 return RESULT_SUCCESS; 04795 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4806 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04807 { 04808 if (argc < 4 || argc > 5) 04809 return RESULT_SHOWUSAGE; 04810 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04811 jb_debug_output("\n"); 04812 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04813 return RESULT_SUCCESS; 04814 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4797 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04798 { 04799 if (argc < 4 || argc > 5) 04800 return RESULT_SHOWUSAGE; 04801 iaxtrunkdebug = 0; 04802 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04803 return RESULT_SUCCESS; 04804 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8616 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08617 { 08618 struct iax2_peer *peer = (struct iax2_peer *)data; 08619 peer->pokeexpire = -1; 08620 #ifdef SCHED_MULTITHREADED 08621 if (schedule_action(__iax2_poke_noanswer, data)) 08622 #endif 08623 __iax2_poke_noanswer(data); 08624 peer_unref(peer); 08625 return 0; 08626 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8637 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
08638 { 08639 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08640 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08641 immediately after clearing things out */ 08642 peer->lastms = 0; 08643 peer->historicms = 0; 08644 peer->pokeexpire = -1; 08645 peer->callno = 0; 08646 return 0; 08647 } 08648 if (peer->callno > 0) { 08649 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08650 ast_mutex_lock(&iaxsl[peer->callno]); 08651 iax2_destroy(peer->callno); 08652 ast_mutex_unlock(&iaxsl[peer->callno]); 08653 } 08654 if (heldcall) 08655 ast_mutex_unlock(&iaxsl[heldcall]); 08656 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd); 08657 if (heldcall) 08658 ast_mutex_lock(&iaxsl[heldcall]); 08659 if (peer->callno < 1) { 08660 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08661 return -1; 08662 } 08663 08664 /* Speed up retransmission times for this qualify call */ 08665 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08666 iaxs[peer->callno]->peerpoke = peer; 08667 08668 /* Remove any pending pokeexpire task */ 08669 if (peer->pokeexpire > -1) { 08670 if (!ast_sched_del(sched, peer->pokeexpire)) { 08671 peer->pokeexpire = -1; 08672 peer_unref(peer); 08673 } 08674 } 08675 08676 /* Queue up a new task to handle no reply */ 08677 /* If the host is already unreachable then use the unreachable interval instead */ 08678 if (peer->lastms < 0) { 08679 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08680 } else 08681 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08682 08683 if (peer->pokeexpire == -1) 08684 peer_unref(peer); 08685 08686 /* And send the poke */ 08687 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08688 08689 return 0; 08690 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8628 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08629 { 08630 struct iax2_peer *peer = obj; 08631 08632 iax2_poke_peer(peer, 0); 08633 08634 return 0; 08635 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6290 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06291 { 06292 struct iax2_peer *peer = (struct iax2_peer *)data; 06293 peer->pokeexpire = -1; 06294 #ifdef SCHED_MULTITHREADED 06295 if (schedule_action(__iax2_poke_peer_s, data)) 06296 #endif 06297 __iax2_poke_peer_s(data); 06298 return 0; 06299 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1938 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag, ast_test_flag, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
01939 { 01940 struct ast_channel *c; 01941 struct chan_iax2_pvt *pvt = iaxs[callno]; 01942 01943 if (!pvt) 01944 return -1; 01945 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01946 iax2_destroy_helper(pvt); 01947 ast_set_flag(pvt, IAX_ALREADYGONE); 01948 } 01949 c = pvt->owner; 01950 if (c) { 01951 c->tech_pvt = NULL; 01952 iax2_queue_hangup(callno); 01953 pvt->owner = NULL; 01954 ast_module_unref(ast_module_info->self); 01955 } 01956 return 0; 01957 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8292 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), socket_process(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08293 { 08294 struct iax2_thread *thread = data; 08295 struct timeval tv; 08296 struct timespec ts; 08297 int put_into_idle = 0; 08298 08299 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08300 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08301 for(;;) { 08302 /* Wait for something to signal us to be awake */ 08303 ast_mutex_lock(&thread->lock); 08304 08305 /* Flag that we're ready to accept signals */ 08306 thread->ready_for_signal = 1; 08307 08308 /* Put into idle list if applicable */ 08309 if (put_into_idle) 08310 insert_idle_thread(thread); 08311 08312 if (thread->type == IAX_TYPE_DYNAMIC) { 08313 struct iax2_thread *t = NULL; 08314 /* Wait to be signalled or time out */ 08315 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08316 ts.tv_sec = tv.tv_sec; 08317 ts.tv_nsec = tv.tv_usec * 1000; 08318 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08319 /* This thread was never put back into the available dynamic 08320 * thread list, so just go away. */ 08321 if (!put_into_idle) { 08322 ast_mutex_unlock(&thread->lock); 08323 break; 08324 } 08325 AST_LIST_LOCK(&dynamic_list); 08326 /* Account for the case where this thread is acquired *right* after a timeout */ 08327 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08328 iaxdynamicthreadcount--; 08329 AST_LIST_UNLOCK(&dynamic_list); 08330 if (t) { 08331 /* This dynamic thread timed out waiting for a task and was 08332 * not acquired immediately after the timeout, 08333 * so it's time to go away. */ 08334 ast_mutex_unlock(&thread->lock); 08335 break; 08336 } 08337 /* Someone grabbed our thread *right* after we timed out. 08338 * Wait for them to set us up with something to do and signal 08339 * us to continue. */ 08340 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08341 ts.tv_sec = tv.tv_sec; 08342 ts.tv_nsec = tv.tv_usec * 1000; 08343 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08344 { 08345 ast_mutex_unlock(&thread->lock); 08346 break; 08347 } 08348 } 08349 } else { 08350 ast_cond_wait(&thread->cond, &thread->lock); 08351 } 08352 08353 /* Go back into our respective list */ 08354 put_into_idle = 1; 08355 08356 ast_mutex_unlock(&thread->lock); 08357 08358 if (thread->iostate == IAX_IOSTATE_IDLE) 08359 continue; 08360 08361 /* Add ourselves to the active list now */ 08362 AST_LIST_LOCK(&active_list); 08363 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08364 AST_LIST_UNLOCK(&active_list); 08365 08366 /* See what we need to do */ 08367 switch(thread->iostate) { 08368 case IAX_IOSTATE_READY: 08369 thread->actions++; 08370 thread->iostate = IAX_IOSTATE_PROCESSING; 08371 socket_process(thread); 08372 handle_deferred_full_frames(thread); 08373 break; 08374 case IAX_IOSTATE_SCHEDREADY: 08375 thread->actions++; 08376 thread->iostate = IAX_IOSTATE_PROCESSING; 08377 #ifdef SCHED_MULTITHREADED 08378 thread->schedfunc(thread->scheddata); 08379 #endif 08380 break; 08381 } 08382 time(&thread->checktime); 08383 thread->iostate = IAX_IOSTATE_IDLE; 08384 #ifdef DEBUG_SCHED_MULTITHREAD 08385 thread->curfunc[0]='\0'; 08386 #endif 08387 08388 /* Now... remove ourselves from the active list, and return to the idle list */ 08389 AST_LIST_LOCK(&active_list); 08390 AST_LIST_REMOVE(&active_list, thread, list); 08391 AST_LIST_UNLOCK(&active_list); 08392 08393 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08394 handle_deferred_full_frames(thread); 08395 } 08396 08397 /*!\note For some reason, idle threads are exiting without being removed 08398 * from an idle list, which is causing memory corruption. Forcibly remove 08399 * it from the list, if it's there. 08400 */ 08401 AST_LIST_LOCK(&idle_list); 08402 AST_LIST_REMOVE(&idle_list, thread, list); 08403 AST_LIST_UNLOCK(&idle_list); 08404 08405 AST_LIST_LOCK(&dynamic_list); 08406 AST_LIST_REMOVE(&dynamic_list, thread, list); 08407 AST_LIST_UNLOCK(&dynamic_list); 08408 08409 /* I am exiting here on my own volition, I need to clean up my own data structures 08410 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08411 */ 08412 pthread_cleanup_pop(1); 08413 08414 return NULL; 08415 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8283 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08284 { 08285 struct iax2_thread *thread = data; 08286 ast_mutex_destroy(&thread->lock); 08287 ast_cond_destroy(&thread->cond); 08288 free(thread); 08289 ast_atomic_dec_and_test(&iaxactivethreadcount); 08290 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8573 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08574 { 08575 int force = 0; 08576 int res; 08577 if (argc < 4) 08578 return RESULT_SHOWUSAGE; 08579 if ((argc > 4)) { 08580 if (!strcasecmp(argv[4], "forced")) 08581 force = 1; 08582 else 08583 return RESULT_SHOWUSAGE; 08584 } 08585 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08586 if (res < 0) 08587 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08588 else if (res < 1) 08589 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08590 else 08591 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08592 return RESULT_SUCCESS; 08593 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8474 of file chan_iax2.c.
References iax_prov_complete_template().
08475 { 08476 if (pos != 3) 08477 return NULL; 08478 return iax_prov_complete_template(line, word, pos, state); 08479 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8481 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, iax2_registry::callno, create_addr(), find_callno(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, LOG_DEBUG, NEW_FORCE, option_debug, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08482 { 08483 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08484 is found for template */ 08485 struct iax_ie_data provdata; 08486 struct iax_ie_data ied; 08487 unsigned int sig; 08488 struct sockaddr_in sin; 08489 int callno; 08490 struct create_addr_info cai; 08491 08492 memset(&cai, 0, sizeof(cai)); 08493 08494 if (option_debug) 08495 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08496 08497 if (iax_provision_build(&provdata, &sig, template, force)) { 08498 if (option_debug) 08499 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08500 return 0; 08501 } 08502 08503 if (end) { 08504 memcpy(&sin, end, sizeof(sin)); 08505 cai.sockfd = sockfd; 08506 } else if (create_addr(dest, &sin, &cai)) 08507 return -1; 08508 08509 /* Build the rest of the message */ 08510 memset(&ied, 0, sizeof(ied)); 08511 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08512 08513 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08514 if (!callno) 08515 return -1; 08516 08517 ast_mutex_lock(&iaxsl[callno]); 08518 if (iaxs[callno]) { 08519 /* Schedule autodestruct in case they don't ever give us anything back */ 08520 if (iaxs[callno]->autoid > -1) 08521 ast_sched_del(sched, iaxs[callno]->autoid); 08522 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08523 ast_set_flag(iaxs[callno], IAX_PROVISION); 08524 /* Got a call number now, so go ahead and send the provisioning information */ 08525 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08526 } 08527 ast_mutex_unlock(&iaxsl[callno]); 08528 08529 return 1; 08530 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2132 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02133 { 02134 struct iax2_peer *peer; 02135 02136 if (argc != 4) 02137 return RESULT_SHOWUSAGE; 02138 if (!strcmp(argv[3],"all")) { 02139 reload_config(); 02140 ast_cli(fd, "OK cache is flushed.\n"); 02141 } else if ((peer = find_peer(argv[3], 0))) { 02142 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02143 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02144 expire_registry(peer_ref(peer)); 02145 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02146 } else { 02147 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02148 } 02149 peer_unref(peer); 02150 } else { 02151 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02152 } 02153 02154 return RESULT_SUCCESS; 02155 }
static int iax2_queue_control_data | ( | int | callno, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1508 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), iaxs, and iaxsl.
Referenced by socket_process().
01510 { 01511 for (;;) { 01512 if (iaxs[callno] && iaxs[callno]->owner) { 01513 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01514 /* Avoid deadlock by pausing and trying again */ 01515 ast_mutex_unlock(&iaxsl[callno]); 01516 usleep(1); 01517 ast_mutex_lock(&iaxsl[callno]); 01518 } else { 01519 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01520 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01521 break; 01522 } 01523 } else 01524 break; 01525 } 01526 return 0; 01527 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 1442 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), iaxs, and iaxsl.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), and __get_from_jb().
01443 { 01444 for (;;) { 01445 if (iaxs[callno] && iaxs[callno]->owner) { 01446 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01447 /* Avoid deadlock by pausing and trying again */ 01448 ast_mutex_unlock(&iaxsl[callno]); 01449 usleep(1); 01450 ast_mutex_lock(&iaxsl[callno]); 01451 } else { 01452 ast_queue_frame(iaxs[callno]->owner, f); 01453 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01454 break; 01455 } 01456 } else 01457 break; 01458 } 01459 return 0; 01460 }
static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1475 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), iaxs, and iaxsl.
Referenced by iax2_predestroy().
01476 { 01477 for (;;) { 01478 if (iaxs[callno] && iaxs[callno]->owner) { 01479 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01480 /* Avoid deadlock by pausing and trying again */ 01481 ast_mutex_unlock(&iaxsl[callno]); 01482 usleep(1); 01483 ast_mutex_lock(&iaxsl[callno]); 01484 } else { 01485 ast_queue_hangup(iaxs[callno]->owner); 01486 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01487 break; 01488 } 01489 } else 01490 break; 01491 } 01492 return 0; 01493 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 3298 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03299 { 03300 if (option_verbose > 3) 03301 ast_log(LOG_NOTICE, "I should never be called!\n"); 03302 return &ast_null_frame; 03303 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5770 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::dnsmgr, iax2_registry::expire, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, iax2_registry::refresh, iax2_registry::secret, strsep(), and iax2_registry::username.
Referenced by set_config().
05771 { 05772 struct iax2_registry *reg; 05773 char copy[256]; 05774 char *username, *hostname, *secret; 05775 char *porta; 05776 char *stringp=NULL; 05777 05778 if (!value) 05779 return -1; 05780 ast_copy_string(copy, value, sizeof(copy)); 05781 stringp=copy; 05782 username = strsep(&stringp, "@"); 05783 hostname = strsep(&stringp, "@"); 05784 if (!hostname) { 05785 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05786 return -1; 05787 } 05788 stringp=username; 05789 username = strsep(&stringp, ":"); 05790 secret = strsep(&stringp, ":"); 05791 stringp=hostname; 05792 hostname = strsep(&stringp, ":"); 05793 porta = strsep(&stringp, ":"); 05794 05795 if (porta && !atoi(porta)) { 05796 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05797 return -1; 05798 } 05799 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05800 return -1; 05801 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05802 free(reg); 05803 return -1; 05804 } 05805 ast_copy_string(reg->username, username, sizeof(reg->username)); 05806 if (secret) 05807 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05808 reg->expire = -1; 05809 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05810 reg->addr.sin_family = AF_INET; 05811 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05812 AST_LIST_LOCK(®istrations); 05813 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05814 AST_LIST_UNLOCK(®istrations); 05815 05816 return 0; 05817 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10004 of file chan_iax2.c.
References reload_config().
10005 { 10006 return reload_config(); 10007 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 8702 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_string_field_set, ast_test_flag, ast_translator_best_choice(), iax2_registry::callno, create_addr_info::capability, create_addr(), find_callno(), fmt, create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
08703 { 08704 int callno; 08705 int res; 08706 int fmt, native; 08707 struct sockaddr_in sin; 08708 struct ast_channel *c; 08709 struct parsed_dial_string pds; 08710 struct create_addr_info cai; 08711 char *tmpstr; 08712 08713 memset(&pds, 0, sizeof(pds)); 08714 tmpstr = ast_strdupa(data); 08715 parse_dial_string(tmpstr, &pds); 08716 08717 memset(&cai, 0, sizeof(cai)); 08718 cai.capability = iax2_capability; 08719 08720 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08721 08722 if (!pds.peer) { 08723 ast_log(LOG_WARNING, "No peer given\n"); 08724 return NULL; 08725 } 08726 08727 08728 /* Populate our address from the given */ 08729 if (create_addr(pds.peer, &sin, &cai)) { 08730 *cause = AST_CAUSE_UNREGISTERED; 08731 return NULL; 08732 } 08733 08734 if (pds.port) 08735 sin.sin_port = htons(atoi(pds.port)); 08736 08737 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08738 if (callno < 1) { 08739 ast_log(LOG_WARNING, "Unable to create call\n"); 08740 *cause = AST_CAUSE_CONGESTION; 08741 return NULL; 08742 } 08743 08744 ast_mutex_lock(&iaxsl[callno]); 08745 08746 /* If this is a trunk, update it now */ 08747 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08748 if (ast_test_flag(&cai, IAX_TRUNK)) { 08749 int new_callno; 08750 if ((new_callno = make_trunk(callno, 1)) != -1) 08751 callno = new_callno; 08752 } 08753 iaxs[callno]->maxtime = cai.maxtime; 08754 if (cai.found) 08755 ast_string_field_set(iaxs[callno], host, pds.peer); 08756 08757 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08758 08759 ast_mutex_unlock(&iaxsl[callno]); 08760 08761 if (c) { 08762 /* Choose a format we can live with */ 08763 if (c->nativeformats & format) 08764 c->nativeformats &= format; 08765 else { 08766 native = c->nativeformats; 08767 fmt = format; 08768 res = ast_translator_best_choice(&fmt, &native); 08769 if (res < 0) { 08770 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08771 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08772 ast_hangup(c); 08773 return NULL; 08774 } 08775 c->nativeformats = native; 08776 } 08777 c->readformat = ast_best_codec(c->nativeformats); 08778 c->writeformat = c->readformat; 08779 } 08780 08781 return c; 08782 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 970 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), find_callno(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00971 { 00972 int res; 00973 00974 res = ast_sched_add(con, when, callback, data); 00975 signal_condition(&sched_lock, &sched_cond); 00976 00977 return res; 00978 }
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 4110 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, 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, chan_iax2_pvt::ecx, 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, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, 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_process().
04111 { 04112 /* Queue a packet for delivery on a given private structure. Use "ts" for 04113 timestamp, or calculate if ts is 0. Send immediately without retransmission 04114 or delayed, with retransmission */ 04115 struct ast_iax2_full_hdr *fh; 04116 struct ast_iax2_mini_hdr *mh; 04117 struct ast_iax2_video_hdr *vh; 04118 struct { 04119 struct iax_frame fr2; 04120 unsigned char buffer[4096]; 04121 } frb; 04122 struct iax_frame *fr; 04123 int res; 04124 int sendmini=0; 04125 unsigned int lastsent; 04126 unsigned int fts; 04127 04128 frb.fr2.afdatalen = sizeof(frb.buffer); 04129 04130 if (!pvt) { 04131 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04132 return -1; 04133 } 04134 04135 lastsent = pvt->lastsent; 04136 04137 /* Calculate actual timestamp */ 04138 fts = calc_timestamp(pvt, ts, f); 04139 04140 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04141 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04142 * increment the "predicted timestamps" for voice, if we're predecting */ 04143 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04144 return 0; 04145 04146 04147 if ((ast_test_flag(pvt, IAX_TRUNK) || 04148 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04149 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04150 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04151 (f->frametype == AST_FRAME_VOICE) 04152 /* is a voice frame */ && 04153 (f->subclass == pvt->svoiceformat) 04154 /* is the same type */ ) { 04155 /* Force immediate rather than delayed transmission */ 04156 now = 1; 04157 /* Mark that mini-style frame is appropriate */ 04158 sendmini = 1; 04159 } 04160 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 04161 (f->frametype == AST_FRAME_VIDEO) && 04162 ((f->subclass & ~0x1) == pvt->svideoformat)) { 04163 now = 1; 04164 sendmini = 1; 04165 } 04166 /* Allocate an iax_frame */ 04167 if (now) { 04168 fr = &frb.fr2; 04169 } else 04170 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 04171 if (!fr) { 04172 ast_log(LOG_WARNING, "Out of memory\n"); 04173 return -1; 04174 } 04175 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04176 iax_frame_wrap(fr, f); 04177 04178 fr->ts = fts; 04179 fr->callno = pvt->callno; 04180 fr->transfer = transfer; 04181 fr->final = final; 04182 if (!sendmini) { 04183 /* We need a full frame */ 04184 if (seqno > -1) 04185 fr->oseqno = seqno; 04186 else 04187 fr->oseqno = pvt->oseqno++; 04188 fr->iseqno = pvt->iseqno; 04189 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04190 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04191 fh->ts = htonl(fr->ts); 04192 fh->oseqno = fr->oseqno; 04193 if (transfer) { 04194 fh->iseqno = 0; 04195 } else 04196 fh->iseqno = fr->iseqno; 04197 /* Keep track of the last thing we've acknowledged */ 04198 if (!transfer) 04199 pvt->aseqno = fr->iseqno; 04200 fh->type = fr->af.frametype & 0xFF; 04201 if (fr->af.frametype == AST_FRAME_VIDEO) 04202 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04203 else 04204 fh->csub = compress_subclass(fr->af.subclass); 04205 if (transfer) { 04206 fr->dcallno = pvt->transfercallno; 04207 } else 04208 fr->dcallno = pvt->peercallno; 04209 fh->dcallno = htons(fr->dcallno); 04210 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04211 fr->data = fh; 04212 fr->retries = 0; 04213 /* Retry after 2x the ping time has passed */ 04214 fr->retrytime = pvt->pingtime * 2; 04215 if (fr->retrytime < MIN_RETRY_TIME) 04216 fr->retrytime = MIN_RETRY_TIME; 04217 if (fr->retrytime > MAX_RETRY_TIME) 04218 fr->retrytime = MAX_RETRY_TIME; 04219 /* Acks' don't get retried */ 04220 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04221 fr->retries = -1; 04222 else if (f->frametype == AST_FRAME_VOICE) 04223 pvt->svoiceformat = f->subclass; 04224 else if (f->frametype == AST_FRAME_VIDEO) 04225 pvt->svideoformat = f->subclass & ~0x1; 04226 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04227 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04228 if (iaxdebug) { 04229 if (fr->transfer) 04230 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04231 else 04232 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04233 } 04234 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04235 } else 04236 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04237 } 04238 04239 if (now) { 04240 res = send_packet(fr); 04241 } else 04242 res = iax2_transmit(fr); 04243 } else { 04244 if (ast_test_flag(pvt, IAX_TRUNK)) { 04245 iax2_trunk_queue(pvt, fr); 04246 res = 0; 04247 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04248 /* Video frame have no sequence number */ 04249 fr->oseqno = -1; 04250 fr->iseqno = -1; 04251 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04252 vh->zeros = 0; 04253 vh->callno = htons(0x8000 | fr->callno); 04254 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04255 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04256 fr->data = vh; 04257 fr->retries = -1; 04258 res = send_packet(fr); 04259 } else { 04260 /* Mini-frames have no sequence number */ 04261 fr->oseqno = -1; 04262 fr->iseqno = -1; 04263 /* Mini frame will do */ 04264 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04265 mh->callno = htons(fr->callno); 04266 mh->ts = htons(fr->ts & 0xFFFF); 04267 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04268 fr->data = mh; 04269 fr->retries = -1; 04270 if (pvt->transferring == TRANSFER_MEDIAPASS) 04271 fr->transfer = 1; 04272 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04273 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04274 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04275 } else 04276 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04277 } 04278 res = send_packet(fr); 04279 } 04280 } 04281 return res; 04282 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2657 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02658 { 02659 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02660 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2652 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.
02653 { 02654 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02655 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Definition at line 2645 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02646 { 02647 02648 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02649 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02650 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3272 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_option_header::data, errno, ast_option_header::flag, free, ast_option_header::option, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03273 { 03274 struct ast_option_header *h; 03275 int res; 03276 03277 switch (option) { 03278 case AST_OPTION_TXGAIN: 03279 case AST_OPTION_RXGAIN: 03280 /* these two cannot be sent, because they require a result */ 03281 errno = ENOSYS; 03282 return -1; 03283 default: 03284 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03285 return -1; 03286 03287 h->flag = AST_OPTION_FLAG_REQUEST; 03288 h->option = htons(option); 03289 memcpy(h->data, data, datalen); 03290 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03291 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03292 datalen + sizeof(*h), -1); 03293 free(h); 03294 return res; 03295 } 03296 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2336 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.
02337 { 02338 struct iax2_dpcache *dp; 02339 char tmp[1024], *pc; 02340 int s; 02341 int x,y; 02342 struct timeval tv; 02343 gettimeofday(&tv, NULL); 02344 ast_mutex_lock(&dpcache_lock); 02345 dp = dpcache; 02346 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02347 while(dp) { 02348 s = dp->expiry.tv_sec - tv.tv_sec; 02349 tmp[0] = '\0'; 02350 if (dp->flags & CACHE_FLAG_EXISTS) 02351 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02352 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02353 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02354 if (dp->flags & CACHE_FLAG_CANEXIST) 02355 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02356 if (dp->flags & CACHE_FLAG_PENDING) 02357 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02358 if (dp->flags & CACHE_FLAG_TIMEOUT) 02359 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02360 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02361 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02362 if (dp->flags & CACHE_FLAG_MATCHMORE) 02363 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02364 if (dp->flags & CACHE_FLAG_UNKNOWN) 02365 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02366 /* Trim trailing pipe */ 02367 if (!ast_strlen_zero(tmp)) 02368 tmp[strlen(tmp) - 1] = '\0'; 02369 else 02370 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02371 y=0; 02372 pc = strchr(dp->peercontext, '@'); 02373 if (!pc) 02374 pc = dp->peercontext; 02375 else 02376 pc++; 02377 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02378 if (dp->waiters[x] > -1) 02379 y++; 02380 if (s > 0) 02381 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02382 else 02383 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02384 dp = dp->next; 02385 } 02386 ast_mutex_unlock(&dpcache_lock); 02387 return RESULT_SUCCESS; 02388 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4626 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04627 { 04628 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04629 #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" 04630 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04631 int x; 04632 int numchans = 0; 04633 04634 if (argc != 3) 04635 return RESULT_SHOWUSAGE; 04636 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04637 for (x=0;x<IAX_MAX_CALLS;x++) { 04638 ast_mutex_lock(&iaxsl[x]); 04639 if (iaxs[x]) { 04640 int lag, jitter, localdelay; 04641 jb_info jbinfo; 04642 04643 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04644 jb_getinfo(iaxs[x]->jb, &jbinfo); 04645 jitter = jbinfo.jitter; 04646 localdelay = jbinfo.current - jbinfo.min; 04647 } else { 04648 jitter = -1; 04649 localdelay = 0; 04650 } 04651 lag = iaxs[x]->remote_rr.delay; 04652 ast_cli(fd, FORMAT, 04653 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04654 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04655 S_OR(iaxs[x]->username, "(None)"), 04656 iaxs[x]->callno, iaxs[x]->peercallno, 04657 iaxs[x]->oseqno, iaxs[x]->iseqno, 04658 lag, 04659 jitter, 04660 localdelay, 04661 ast_getformatname(iaxs[x]->voiceformat) ); 04662 numchans++; 04663 } 04664 ast_mutex_unlock(&iaxsl[x]); 04665 } 04666 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04667 return RESULT_SUCCESS; 04668 #undef FORMAT 04669 #undef FORMAT2 04670 #undef FORMATB 04671 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4537 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.
04538 { 04539 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04540 #if !defined(__FreeBSD__) 04541 #define FORMAT "%-15.15s %-15d %-15d\n" 04542 #else /* __FreeBSD__ */ 04543 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04544 #endif /* __FreeBSD__ */ 04545 struct iax_firmware *cur; 04546 if ((argc != 3) && (argc != 4)) 04547 return RESULT_SHOWUSAGE; 04548 ast_mutex_lock(&waresl.lock); 04549 04550 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04551 for (cur = waresl.wares;cur;cur = cur->next) { 04552 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04553 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04554 (int)ntohl(cur->fwh->datalen)); 04555 } 04556 ast_mutex_unlock(&waresl.lock); 04557 return RESULT_SUCCESS; 04558 #undef FORMAT 04559 #undef FORMAT2 04560 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4749 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04750 { 04751 int numchans = 0; 04752 if (argc != 3) 04753 return RESULT_SHOWUSAGE; 04754 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04755 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04756 numchans = ast_cli_netstats(NULL, fd, 1); 04757 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04758 return RESULT_SUCCESS; 04759 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2226 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::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02227 { 02228 char status[30]; 02229 char cbuf[256]; 02230 struct iax2_peer *peer; 02231 char codec_buf[512]; 02232 int x = 0, codec = 0, load_realtime = 0; 02233 02234 if (argc < 4) 02235 return RESULT_SHOWUSAGE; 02236 02237 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02238 02239 peer = find_peer(argv[3], load_realtime); 02240 if (peer) { 02241 ast_cli(fd,"\n\n"); 02242 ast_cli(fd, " * Name : %s\n", peer->name); 02243 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02244 ast_cli(fd, " Context : %s\n", peer->context); 02245 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02246 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02247 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02248 ast_cli(fd, " Expire : %d\n", peer->expire); 02249 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02250 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 02251 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02252 ast_cli(fd, " Username : %s\n", peer->username); 02253 ast_cli(fd, " Codecs : "); 02254 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02255 ast_cli(fd, "%s\n", codec_buf); 02256 02257 ast_cli(fd, " Codec Order : ("); 02258 for(x = 0; x < 32 ; x++) { 02259 codec = ast_codec_pref_index(&peer->prefs,x); 02260 if(!codec) 02261 break; 02262 ast_cli(fd, "%s", ast_getformatname(codec)); 02263 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02264 ast_cli(fd, "|"); 02265 } 02266 02267 if (!x) 02268 ast_cli(fd, "none"); 02269 ast_cli(fd, ")\n"); 02270 02271 ast_cli(fd, " Status : "); 02272 peer_status(peer, status, sizeof(status)); 02273 ast_cli(fd, "%s\n",status); 02274 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02275 ast_cli(fd,"\n"); 02276 peer_unref(peer); 02277 } else { 02278 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02279 ast_cli(fd,"\n"); 02280 } 02281 02282 return RESULT_SUCCESS; 02283 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4526 of file chan_iax2.c.
References __iax2_show_peers().
04527 { 04528 return __iax2_show_peers(0, fd, NULL, argc, argv); 04529 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4598 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
04599 { 04600 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04601 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04602 struct iax2_registry *reg = NULL; 04603 04604 char host[80]; 04605 char perceived[80]; 04606 if (argc != 3) 04607 return RESULT_SHOWUSAGE; 04608 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04609 AST_LIST_LOCK(®istrations); 04610 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04611 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04612 if (reg->us.sin_addr.s_addr) 04613 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04614 else 04615 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04616 ast_cli(fd, FORMAT, host, 04617 (reg->dnsmgr) ? "Y" : "N", 04618 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04619 } 04620 AST_LIST_UNLOCK(®istrations); 04621 return RESULT_SUCCESS; 04622 #undef FORMAT 04623 #undef FORMAT2 04624 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2310 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02311 { 02312 struct iax_frame *cur; 02313 int cnt = 0, dead=0, final=0; 02314 02315 if (argc != 3) 02316 return RESULT_SHOWUSAGE; 02317 02318 AST_LIST_LOCK(&iaxq.queue); 02319 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02320 if (cur->retries < 0) 02321 dead++; 02322 if (cur->final) 02323 final++; 02324 cnt++; 02325 } 02326 AST_LIST_UNLOCK(&iaxq.queue); 02327 02328 ast_cli(fd, " IAX Statistics\n"); 02329 ast_cli(fd, "---------------------\n"); 02330 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02331 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02332 02333 return RESULT_SUCCESS; 02334 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4467 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.
04468 { 04469 struct iax2_thread *thread = NULL; 04470 time_t t; 04471 int threadcount = 0, dynamiccount = 0; 04472 char type; 04473 04474 if (argc != 3) 04475 return RESULT_SHOWUSAGE; 04476 04477 ast_cli(fd, "IAX2 Thread Information\n"); 04478 time(&t); 04479 ast_cli(fd, "Idle Threads:\n"); 04480 AST_LIST_LOCK(&idle_list); 04481 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04482 #ifdef DEBUG_SCHED_MULTITHREAD 04483 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04484 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04485 #else 04486 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04487 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04488 #endif 04489 threadcount++; 04490 } 04491 AST_LIST_UNLOCK(&idle_list); 04492 ast_cli(fd, "Active Threads:\n"); 04493 AST_LIST_LOCK(&active_list); 04494 AST_LIST_TRAVERSE(&active_list, thread, list) { 04495 if (thread->type == IAX_TYPE_DYNAMIC) 04496 type = 'D'; 04497 else 04498 type = 'P'; 04499 #ifdef DEBUG_SCHED_MULTITHREAD 04500 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04501 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04502 #else 04503 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04504 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04505 #endif 04506 threadcount++; 04507 } 04508 AST_LIST_UNLOCK(&active_list); 04509 ast_cli(fd, "Dynamic Threads:\n"); 04510 AST_LIST_LOCK(&dynamic_list); 04511 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04512 #ifdef DEBUG_SCHED_MULTITHREAD 04513 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04514 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04515 #else 04516 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04517 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04518 #endif 04519 dynamiccount++; 04520 } 04521 AST_LIST_UNLOCK(&dynamic_list); 04522 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04523 return RESULT_SUCCESS; 04524 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4284 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, RESULT_SHOWUSAGE, RESULT_SUCCESS, user_unref(), and users.
04285 { 04286 regex_t regexbuf; 04287 int havepattern = 0; 04288 04289 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04290 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04291 04292 struct iax2_user *user = NULL; 04293 char auth[90]; 04294 char *pstr = ""; 04295 struct ao2_iterator i; 04296 04297 switch (argc) { 04298 case 5: 04299 if (!strcasecmp(argv[3], "like")) { 04300 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04301 return RESULT_SHOWUSAGE; 04302 havepattern = 1; 04303 } else 04304 return RESULT_SHOWUSAGE; 04305 case 3: 04306 break; 04307 default: 04308 return RESULT_SHOWUSAGE; 04309 } 04310 04311 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04312 i = ao2_iterator_init(users, 0); 04313 for (user = ao2_iterator_next(&i); user; 04314 user_unref(user), user = ao2_iterator_next(&i)) { 04315 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04316 continue; 04317 04318 if (!ast_strlen_zero(user->secret)) { 04319 ast_copy_string(auth,user->secret,sizeof(auth)); 04320 } else if (!ast_strlen_zero(user->inkeys)) { 04321 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04322 } else 04323 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04324 04325 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04326 pstr = "REQ Only"; 04327 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04328 pstr = "Disabled"; 04329 else 04330 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04331 04332 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04333 user->contexts ? user->contexts->context : context, 04334 user->ha ? "Yes" : "No", pstr); 04335 } 04336 04337 if (havepattern) 04338 regfree(®exbuf); 04339 04340 return RESULT_SUCCESS; 04341 #undef FORMAT 04342 #undef FORMAT2 04343 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3305 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_random(), iax_ie_data::buf, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, iaxs, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
03306 { 03307 int res; 03308 struct iax_ie_data ied0; 03309 struct iax_ie_data ied1; 03310 unsigned int transferid = (unsigned int)ast_random(); 03311 memset(&ied0, 0, sizeof(ied0)); 03312 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03313 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03314 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03315 03316 memset(&ied1, 0, sizeof(ied1)); 03317 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03318 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03319 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03320 03321 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03322 if (res) 03323 return -1; 03324 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03325 if (res) 03326 return -1; 03327 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03328 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03329 return 0; 03330 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2157 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02158 { 02159 if (argc != 4) 02160 return RESULT_SHOWUSAGE; 02161 02162 test_losspct = atoi(argv[3]); 02163 02164 return RESULT_SUCCESS; 02165 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3540 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, LOG_DEBUG, option_debug, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03541 { 03542 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03543 struct iax_ie_data ied; 03544 char tmp[256], *context; 03545 ast_copy_string(tmp, dest, sizeof(tmp)); 03546 context = strchr(tmp, '@'); 03547 if (context) { 03548 *context = '\0'; 03549 context++; 03550 } 03551 memset(&ied, 0, sizeof(ied)); 03552 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03553 if (context) 03554 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03555 if (option_debug) 03556 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03557 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03558 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2616 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iaxq, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02617 { 02618 /* Lock the queue and place this packet at the end */ 02619 /* By setting this to 0, the network thread will send it for us, and 02620 queue retransmission if necessary */ 02621 fr->sentyet = 0; 02622 AST_LIST_LOCK(&iaxq.queue); 02623 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02624 iaxq.count++; 02625 AST_LIST_UNLOCK(&iaxq.queue); 02626 /* Wake up the network and scheduler thread */ 02627 if (netthreadid != AST_PTHREADT_NULL) 02628 pthread_kill(netthreadid, SIGURG); 02629 signal_condition(&sched_lock, &sched_cond); 02630 return 0; 02631 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6345 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06346 { 06347 /* Drop when trunk is about 5 seconds idle */ 06348 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06349 return 1; 06350 return 0; 06351 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3884 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_realloc, 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, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, 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().
03885 { 03886 struct ast_frame *f; 03887 struct iax2_trunk_peer *tpeer; 03888 void *tmp, *ptr; 03889 struct ast_iax2_meta_trunk_entry *met; 03890 struct ast_iax2_meta_trunk_mini *mtm; 03891 03892 f = &fr->af; 03893 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03894 if (tpeer) { 03895 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03896 /* Need to reallocate space */ 03897 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03898 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03899 ast_mutex_unlock(&tpeer->lock); 03900 return -1; 03901 } 03902 03903 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03904 tpeer->trunkdata = tmp; 03905 if (option_debug) 03906 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 03907 } else { 03908 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03909 ast_mutex_unlock(&tpeer->lock); 03910 return -1; 03911 } 03912 } 03913 03914 /* Append to meta frame */ 03915 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03916 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03917 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03918 mtm->len = htons(f->datalen); 03919 mtm->mini.callno = htons(pvt->callno); 03920 mtm->mini.ts = htons(0xffff & fr->ts); 03921 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03922 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03923 } else { 03924 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03925 /* Store call number and length in meta header */ 03926 met->callno = htons(pvt->callno); 03927 met->len = htons(f->datalen); 03928 /* Advance pointers/decrease length past trunk entry header */ 03929 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03930 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03931 } 03932 /* Copy actual trunk data */ 03933 memcpy(ptr, f->data, f->datalen); 03934 tpeer->trunkdatalen += f->datalen; 03935 03936 tpeer->calls++; 03937 ast_mutex_unlock(&tpeer->lock); 03938 } 03939 return 0; 03940 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6262 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06263 { 06264 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06265 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4816 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, errno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, LOG_DEBUG, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04817 { 04818 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04819 int res = -1; 04820 ast_mutex_lock(&iaxsl[callno]); 04821 if (iaxs[callno]) { 04822 /* If there's an outstanding error, return failure now */ 04823 if (!iaxs[callno]->error) { 04824 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04825 res = 0; 04826 /* Don't waste bandwidth sending null frames */ 04827 else if (f->frametype == AST_FRAME_NULL) 04828 res = 0; 04829 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04830 res = 0; 04831 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04832 res = 0; 04833 else 04834 /* Simple, just queue for transmission */ 04835 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04836 } else { 04837 if (option_debug) 04838 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04839 } 04840 } 04841 /* If it's already gone, just return */ 04842 ast_mutex_unlock(&iaxsl[callno]); 04843 return res; 04844 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1683 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().
01684 { 01685 int res = 0; 01686 struct iax_firmware *cur; 01687 if (!ast_strlen_zero(dev)) { 01688 ast_mutex_lock(&waresl.lock); 01689 cur = waresl.wares; 01690 while(cur) { 01691 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01692 res = ntohs(cur->fwh->version); 01693 break; 01694 } 01695 cur = cur->next; 01696 } 01697 ast_mutex_unlock(&waresl.lock); 01698 } 01699 return res; 01700 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 766 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00767 { 00768 if (iaxdebug) 00769 ast_verbose("%s", data); 00770 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 772 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00773 { 00774 ast_log(LOG_WARNING, "%s", data); 00775 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1702 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_process().
01703 { 01704 int res = -1; 01705 unsigned int bs = desc & 0xff; 01706 unsigned int start = (desc >> 8) & 0xffffff; 01707 unsigned int bytes; 01708 struct iax_firmware *cur; 01709 if (!ast_strlen_zero((char *)dev) && bs) { 01710 start *= bs; 01711 ast_mutex_lock(&waresl.lock); 01712 cur = waresl.wares; 01713 while(cur) { 01714 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01715 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01716 if (start < ntohl(cur->fwh->datalen)) { 01717 bytes = ntohl(cur->fwh->datalen) - start; 01718 if (bytes > bs) 01719 bytes = bs; 01720 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01721 } else { 01722 bytes = 0; 01723 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01724 } 01725 if (bytes == bs) 01726 res = 0; 01727 else 01728 res = 1; 01729 break; 01730 } 01731 cur = cur->next; 01732 } 01733 ast_mutex_unlock(&waresl.lock); 01734 } 01735 return res; 01736 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6528 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06529 { 06530 struct iax_dual *d; 06531 struct ast_channel *chan1m, *chan2m; 06532 pthread_t th; 06533 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06534 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06535 if (chan2m && chan1m) { 06536 /* Make formats okay */ 06537 chan1m->readformat = chan1->readformat; 06538 chan1m->writeformat = chan1->writeformat; 06539 ast_channel_masquerade(chan1m, chan1); 06540 /* Setup the extensions and such */ 06541 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06542 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06543 chan1m->priority = chan1->priority; 06544 06545 /* We make a clone of the peer channel too, so we can play 06546 back the announcement */ 06547 /* Make formats okay */ 06548 chan2m->readformat = chan2->readformat; 06549 chan2m->writeformat = chan2->writeformat; 06550 ast_channel_masquerade(chan2m, chan2); 06551 /* Setup the extensions and such */ 06552 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06553 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06554 chan2m->priority = chan2->priority; 06555 if (ast_do_masquerade(chan2m)) { 06556 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06557 ast_hangup(chan2m); 06558 return -1; 06559 } 06560 } else { 06561 if (chan1m) 06562 ast_hangup(chan1m); 06563 if (chan2m) 06564 ast_hangup(chan2m); 06565 return -1; 06566 } 06567 if ((d = ast_calloc(1, sizeof(*d)))) { 06568 pthread_attr_t attr; 06569 06570 pthread_attr_init(&attr); 06571 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06572 06573 d->chan1 = chan1m; 06574 d->chan2 = chan2m; 06575 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06576 pthread_attr_destroy(&attr); 06577 return 0; 06578 } 06579 pthread_attr_destroy(&attr); 06580 free(d); 06581 } 06582 return -1; 06583 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6508 of file chan_iax2.c.
References ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, free, and LOG_NOTICE.
Referenced by iax_park().
06509 { 06510 struct ast_channel *chan1, *chan2; 06511 struct iax_dual *d; 06512 struct ast_frame *f; 06513 int ext; 06514 int res; 06515 d = stuff; 06516 chan1 = d->chan1; 06517 chan2 = d->chan2; 06518 free(d); 06519 f = ast_read(chan1); 06520 if (f) 06521 ast_frfree(f); 06522 res = ast_park_call(chan1, chan2, 0, &ext); 06523 ast_hangup(chan2); 06524 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06525 return NULL; 06526 }
Definition at line 1223 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process().
01224 { 01225 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01226 if (new) { 01227 size_t afdatalen = new->afdatalen; 01228 memcpy(new, fr, sizeof(*new)); 01229 iax_frame_wrap(new, &fr->af); 01230 new->afdatalen = afdatalen; 01231 new->data = NULL; 01232 new->datalen = 0; 01233 new->direction = DIRECTION_INGRESS; 01234 new->retrans = -1; 01235 } 01236 return new; 01237 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 878 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
00879 { 00880 if (thread->type == IAX_TYPE_DYNAMIC) { 00881 AST_LIST_LOCK(&dynamic_list); 00882 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00883 AST_LIST_UNLOCK(&dynamic_list); 00884 } else { 00885 AST_LIST_LOCK(&idle_list); 00886 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00887 AST_LIST_UNLOCK(&idle_list); 00888 } 00889 00890 return; 00891 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 801 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00802 { 00803 va_list args; 00804 char buf[1024]; 00805 00806 va_start(args, fmt); 00807 vsnprintf(buf, 1024, fmt, args); 00808 va_end(args); 00809 00810 ast_verbose(buf); 00811 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 777 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00778 { 00779 va_list args; 00780 char buf[1024]; 00781 00782 va_start(args, fmt); 00783 vsnprintf(buf, 1024, fmt, args); 00784 va_end(args); 00785 00786 ast_log(LOG_ERROR, buf); 00787 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 789 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00790 { 00791 va_list args; 00792 char buf[1024]; 00793 00794 va_start(args, fmt); 00795 vsnprintf(buf, 1024, fmt, args); 00796 va_end(args); 00797 00798 ast_log(LOG_WARNING, buf); 00799 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 10811 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, errno, iax2_do_register(), iax2_poke_peer_cb(), 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, iaxs, iaxsl, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, option_verbose, papp, pdescrip, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, psyn, reload_firmware(), sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
10812 { 10813 char *config = "iax.conf"; 10814 int res = 0; 10815 int x; 10816 struct iax2_registry *reg = NULL; 10817 10818 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 10819 if (!peers) 10820 return AST_MODULE_LOAD_FAILURE; 10821 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 10822 if (!users) { 10823 ao2_ref(peers, -1); 10824 return AST_MODULE_LOAD_FAILURE; 10825 } 10826 10827 ast_custom_function_register(&iaxpeer_function); 10828 10829 iax_set_output(iax_debug_output); 10830 iax_set_error(iax_error_output); 10831 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10832 10833 #ifdef HAVE_ZAPTEL 10834 #ifdef ZT_TIMERACK 10835 timingfd = open("/dev/zap/timer", O_RDWR); 10836 if (timingfd < 0) 10837 #endif 10838 timingfd = open("/dev/zap/pseudo", O_RDWR); 10839 if (timingfd < 0) 10840 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10841 #endif 10842 10843 memset(iaxs, 0, sizeof(iaxs)); 10844 10845 for (x=0;x<IAX_MAX_CALLS;x++) 10846 ast_mutex_init(&iaxsl[x]); 10847 10848 ast_cond_init(&sched_cond, NULL); 10849 10850 io = io_context_create(); 10851 sched = sched_context_create(); 10852 10853 if (!io || !sched) { 10854 ast_log(LOG_ERROR, "Out of memory\n"); 10855 return -1; 10856 } 10857 10858 netsock = ast_netsock_list_alloc(); 10859 if (!netsock) { 10860 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10861 return -1; 10862 } 10863 ast_netsock_init(netsock); 10864 10865 outsock = ast_netsock_list_alloc(); 10866 if (!outsock) { 10867 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10868 return -1; 10869 } 10870 ast_netsock_init(outsock); 10871 10872 ast_mutex_init(&waresl.lock); 10873 10874 AST_LIST_HEAD_INIT(&iaxq.queue); 10875 10876 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10877 10878 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10879 10880 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10881 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10882 10883 if(set_config(config, 0) == -1) 10884 return AST_MODULE_LOAD_DECLINE; 10885 10886 if (ast_channel_register(&iax2_tech)) { 10887 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10888 __unload_module(); 10889 return -1; 10890 } 10891 10892 if (ast_register_switch(&iax2_switch)) 10893 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10894 10895 res = start_network_thread(); 10896 if (!res) { 10897 if (option_verbose > 1) 10898 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10899 } else { 10900 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10901 ast_netsock_release(netsock); 10902 ast_netsock_release(outsock); 10903 } 10904 10905 AST_LIST_LOCK(®istrations); 10906 AST_LIST_TRAVERSE(®istrations, reg, entry) 10907 iax2_do_register(reg); 10908 AST_LIST_UNLOCK(®istrations); 10909 10910 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 10911 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 10912 10913 reload_firmware(0); 10914 iax_provision_reload(); 10915 return res; 10916 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3332 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03333 { 03334 ast_mutex_lock(&iaxsl[callno0]); 03335 while (ast_mutex_trylock(&iaxsl[callno1])) { 03336 ast_mutex_unlock(&iaxsl[callno0]); 03337 usleep(10); 03338 ast_mutex_lock(&iaxsl[callno0]); 03339 } 03340 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1291 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), chan_iax2_pvt::callno, iax2_sched_add(), IAX_MAX_CALLS, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01292 { 01293 int x; 01294 int res= 0; 01295 struct timeval now; 01296 if (iaxs[callno]->oseqno) { 01297 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01298 return -1; 01299 } 01300 if (callno & TRUNK_CALL_START) { 01301 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01302 return -1; 01303 } 01304 gettimeofday(&now, NULL); 01305 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01306 ast_mutex_lock(&iaxsl[x]); 01307 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01308 iaxs[x] = iaxs[callno]; 01309 iaxs[x]->callno = x; 01310 iaxs[callno] = NULL; 01311 /* Update the two timers that should have been started */ 01312 if (iaxs[x]->pingid > -1) 01313 ast_sched_del(sched, iaxs[x]->pingid); 01314 if (iaxs[x]->lagid > -1) 01315 ast_sched_del(sched, iaxs[x]->lagid); 01316 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01317 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01318 if (locked) 01319 ast_mutex_unlock(&iaxsl[callno]); 01320 res = x; 01321 if (!locked) 01322 ast_mutex_unlock(&iaxsl[x]); 01323 break; 01324 } 01325 ast_mutex_unlock(&iaxsl[x]); 01326 } 01327 if (x >= IAX_MAX_CALLS - 1) { 01328 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01329 return -1; 01330 } 01331 if (option_debug) 01332 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01333 /* We move this call from a non-trunked to a trunked call */ 01334 update_max_trunk(); 01335 update_max_nontrunk(); 01336 return res; 01337 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4530 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
04531 { 04532 ast_cli_netstats(s, -1, 0); 04533 astman_append(s, "\r\n"); 04534 return RESULT_SUCCESS; 04535 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4563 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by load_module().
04564 { 04565 char *a[] = { "iax2", "show", "users" }; 04566 int ret; 04567 const char *id = astman_get_header(m,"ActionID"); 04568 04569 if (!ast_strlen_zero(id)) 04570 astman_append(s, "ActionID: %s\r\n",id); 04571 ret = __iax2_show_peers(1, -1, s, 3, a ); 04572 astman_append(s, "\r\n\r\n" ); 04573 return ret; 04574 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur | |||
) | [static] |
Definition at line 1243 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by ao2_callback(), ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01244 { 01245 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01246 (cur->addr.sin_port == sin->sin_port)) { 01247 /* This is the main host */ 01248 if ((cur->peercallno == callno) || 01249 ((dcallno == cur->callno) && !cur->peercallno)) { 01250 /* That's us. Be sure we keep track of the peer call number */ 01251 return 1; 01252 } 01253 } 01254 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01255 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01256 /* We're transferring */ 01257 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01258 return 1; 01259 } 01260 return 0; 01261 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3948 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03949 { 03950 #if 0 03951 /* Debug with "fake encryption" */ 03952 int x; 03953 if (len % 16) 03954 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03955 for (x=0;x<len;x++) 03956 dst[x] = src[x] ^ 0xff; 03957 #else 03958 unsigned char lastblock[16] = { 0 }; 03959 int x; 03960 while(len > 0) { 03961 aes_decrypt(src, dst, dcx); 03962 for (x=0;x<16;x++) 03963 dst[x] ^= lastblock[x]; 03964 memcpy(lastblock, src, sizeof(lastblock)); 03965 dst += 16; 03966 src += 16; 03967 len -= 16; 03968 } 03969 #endif 03970 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3972 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03973 { 03974 #if 0 03975 /* Debug with "fake encryption" */ 03976 int x; 03977 if (len % 16) 03978 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03979 for (x=0;x<len;x++) 03980 dst[x] = src[x] ^ 0xff; 03981 #else 03982 unsigned char curblock[16] = { 0 }; 03983 int x; 03984 while(len > 0) { 03985 for (x=0;x<16;x++) 03986 curblock[x] ^= src[x]; 03987 aes_encrypt(curblock, dst, ecx); 03988 memcpy(curblock, dst, sizeof(curblock)); 03989 dst += 16; 03990 src += 16; 03991 len -= 16; 03992 } 03993 #endif 03994 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5141 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05142 { 05143 /* Select exactly one common encryption if there are any */ 05144 p->encmethods &= enc; 05145 if (p->encmethods) { 05146 if (p->encmethods & IAX_ENCRYPT_AES128) 05147 p->encmethods = IAX_ENCRYPT_AES128; 05148 else 05149 p->encmethods = 0; 05150 } 05151 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8812 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, LOG_DEBUG, option_debug, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, and timing_read().
Referenced by start_network_thread().
08813 { 08814 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08815 from the network, and queue them for delivery to the channels */ 08816 int res, count, wakeup; 08817 struct iax_frame *f; 08818 08819 if (timingfd > -1) 08820 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08821 08822 for(;;) { 08823 pthread_testcancel(); 08824 08825 /* Go through the queue, sending messages which have not yet been 08826 sent, and scheduling retransmissions if appropriate */ 08827 AST_LIST_LOCK(&iaxq.queue); 08828 count = 0; 08829 wakeup = -1; 08830 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08831 if (f->sentyet) 08832 continue; 08833 08834 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08835 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08836 wakeup = 1; 08837 continue; 08838 } 08839 08840 f->sentyet++; 08841 08842 if (iaxs[f->callno]) { 08843 send_packet(f); 08844 count++; 08845 } 08846 08847 ast_mutex_unlock(&iaxsl[f->callno]); 08848 08849 if (f->retries < 0) { 08850 /* This is not supposed to be retransmitted */ 08851 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 08852 iaxq.count--; 08853 /* Free the iax frame */ 08854 iax_frame_free(f); 08855 } else { 08856 /* We need reliable delivery. Schedule a retransmission */ 08857 f->retries++; 08858 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 08859 } 08860 } 08861 AST_LIST_TRAVERSE_SAFE_END 08862 AST_LIST_UNLOCK(&iaxq.queue); 08863 08864 pthread_testcancel(); 08865 08866 if (option_debug && count >= 20) 08867 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08868 08869 /* Now do the IO, and run scheduled tasks */ 08870 res = ast_io_wait(io, wakeup); 08871 if (res >= 0) { 08872 if (option_debug && res >= 20) 08873 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08874 } 08875 } 08876 return NULL; 08877 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1185 of file chan_iax2.c.
References ast_calloc, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, exten, free, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno.
Referenced by find_callno().
01186 { 01187 struct chan_iax2_pvt *tmp; 01188 jb_conf jbconf; 01189 01190 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01191 return NULL; 01192 01193 if (ast_string_field_init(tmp, 32)) { 01194 free(tmp); 01195 tmp = NULL; 01196 return NULL; 01197 } 01198 01199 tmp->prefs = prefs; 01200 tmp->callno = 0; 01201 tmp->peercallno = 0; 01202 tmp->transfercallno = 0; 01203 tmp->bridgecallno = 0; 01204 tmp->pingid = -1; 01205 tmp->lagid = -1; 01206 tmp->autoid = -1; 01207 tmp->authid = -1; 01208 tmp->initid = -1; 01209 01210 ast_string_field_set(tmp,exten, "s"); 01211 ast_string_field_set(tmp,host, host); 01212 01213 tmp->jb = jb_new(); 01214 tmp->jbid = -1; 01215 jbconf.max_jitterbuf = maxjitterbuffer; 01216 jbconf.resync_threshold = resyncthreshold; 01217 jbconf.max_contig_interp = maxjitterinterps; 01218 jb_setconf(tmp->jb,&jbconf); 01219 01220 return tmp; 01221 }
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 3056 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().
03057 { 03058 if (ast_strlen_zero(data)) 03059 return; 03060 03061 pds->peer = strsep(&data, "/"); 03062 pds->exten = strsep(&data, "/"); 03063 pds->options = data; 03064 03065 if (pds->exten) { 03066 data = pds->exten; 03067 pds->exten = strsep(&data, "@"); 03068 pds->context = data; 03069 } 03070 03071 if (strchr(pds->peer, '@')) { 03072 data = pds->peer; 03073 pds->username = strsep(&data, "@"); 03074 pds->peer = data; 03075 } 03076 03077 if (pds->username) { 03078 data = pds->username; 03079 pds->username = strsep(&data, ":"); 03080 pds->password = data; 03081 } 03082 03083 data = pds->peer; 03084 pds->peer = strsep(&data, ":"); 03085 pds->port = data; 03086 03087 /* check for a key name wrapped in [] in the secret position, if found, 03088 move it to the key field instead 03089 */ 03090 if (pds->password && (pds->password[0] == '[')) { 03091 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03092 pds->password = NULL; 03093 } 03094 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1084 of file chan_iax2.c.
Referenced by load_module().
01085 { 01086 struct iax2_peer *peer = obj, *peer2 = arg; 01087 01088 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01089 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9512 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09513 { 09514 struct iax2_peer *peer = obj; 09515 09516 ast_set_flag(peer, IAX_DELME); 09517 09518 return 0; 09519 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9035 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, and register_peer_exten().
Referenced by build_peer().
09036 { 09037 struct iax2_peer *peer = obj; 09038 09039 ast_free_ha(peer->ha); 09040 09041 if (peer->callno > 0) { 09042 ast_mutex_lock(&iaxsl[peer->callno]); 09043 iax2_destroy(peer->callno); 09044 ast_mutex_unlock(&iaxsl[peer->callno]); 09045 } 09046 09047 register_peer_exten(peer, 0); 09048 09049 if (peer->dnsmgr) 09050 ast_dnsmgr_release(peer->dnsmgr); 09051 09052 ast_string_field_free_memory(peer); 09053 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1074 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01075 { 01076 const struct iax2_peer *peer = obj; 01077 01078 return ast_str_hash(peer->name); 01079 }
Definition at line 1131 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01132 { 01133 ao2_ref(peer, +1); 01134 return peer; 01135 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10800 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
10801 { 10802 struct iax2_peer *peer = obj; 10803 10804 if (peer->sockfd < 0) 10805 peer->sockfd = defaultsockfd; 10806 10807 return 0; 10808 }
static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
const char * | srcaddr | |||
) | [static] |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
Definition at line 8962 of file chan_iax2.c.
References iax2_registry::addr, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_DEBUG, LOG_WARNING, option_debug, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
08963 { 08964 struct sockaddr_in sin; 08965 int nonlocal = 1; 08966 int port = IAX_DEFAULT_PORTNO; 08967 int sockfd = defaultsockfd; 08968 char *tmp; 08969 char *addr; 08970 char *portstr; 08971 08972 if (!(tmp = ast_strdupa(srcaddr))) 08973 return -1; 08974 08975 addr = strsep(&tmp, ":"); 08976 portstr = tmp; 08977 08978 if (portstr) { 08979 port = atoi(portstr); 08980 if (port < 1) 08981 port = IAX_DEFAULT_PORTNO; 08982 } 08983 08984 if (!ast_get_ip(&sin, addr)) { 08985 struct ast_netsock *sock; 08986 int res; 08987 08988 sin.sin_port = 0; 08989 sin.sin_family = AF_INET; 08990 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08991 if (res == 0) { 08992 /* ip address valid. */ 08993 sin.sin_port = htons(port); 08994 if (!(sock = ast_netsock_find(netsock, &sin))) 08995 sock = ast_netsock_find(outsock, &sin); 08996 if (sock) { 08997 sockfd = ast_netsock_sockfd(sock); 08998 nonlocal = 0; 08999 } else { 09000 unsigned int orig_saddr = sin.sin_addr.s_addr; 09001 /* INADDR_ANY matches anyway! */ 09002 sin.sin_addr.s_addr = INADDR_ANY; 09003 if (ast_netsock_find(netsock, &sin)) { 09004 sin.sin_addr.s_addr = orig_saddr; 09005 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09006 if (sock) { 09007 sockfd = ast_netsock_sockfd(sock); 09008 ast_netsock_unref(sock); 09009 nonlocal = 0; 09010 } else { 09011 nonlocal = 2; 09012 } 09013 } 09014 } 09015 } 09016 } 09017 09018 peer->sockfd = sockfd; 09019 09020 if (nonlocal == 1) { 09021 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09022 srcaddr, peer->name); 09023 return -1; 09024 } else if (nonlocal == 2) { 09025 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09026 srcaddr, peer->name); 09027 return -1; 09028 } else { 09029 if (option_debug) 09030 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09031 return 0; 09032 } 09033 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2203 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().
02204 { 02205 int res = 0; 02206 if (peer->maxms) { 02207 if (peer->lastms < 0) { 02208 ast_copy_string(status, "UNREACHABLE", statuslen); 02209 } else if (peer->lastms > peer->maxms) { 02210 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02211 res = 1; 02212 } else if (peer->lastms) { 02213 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02214 res = 1; 02215 } else { 02216 ast_copy_string(status, "UNKNOWN", statuslen); 02217 } 02218 } else { 02219 ast_copy_string(status, "Unmonitored", statuslen); 02220 res = -1; 02221 } 02222 return res; 02223 }
Definition at line 1137 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01138 { 01139 ao2_ref(peer, -1); 01140 return NULL; 01141 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 9972 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
09973 { 09974 struct ao2_iterator i; 09975 struct iax2_peer *peer; 09976 09977 i = ao2_iterator_init(peers, 0); 09978 while ((peer = ao2_iterator_next(&i))) { 09979 iax2_poke_peer(peer, 0); 09980 peer_unref(peer); 09981 } 09982 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9571 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09572 { 09573 struct iax2_peer *peer; 09574 struct ao2_iterator i; 09575 09576 i = ao2_iterator_init(peers, 0); 09577 while ((peer = ao2_iterator_next(&i))) { 09578 if (ast_test_flag(peer, IAX_DELME)) 09579 unlink_peer(peer); 09580 peer_unref(peer); 09581 } 09582 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9557 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, user_unref(), and users.
Referenced by reload_config().
09558 { 09559 struct iax2_user *user; 09560 struct ao2_iterator i; 09561 09562 i = ao2_iterator_init(users, 0); 09563 while ((user = ao2_iterator_next(&i))) { 09564 if (ast_test_flag(user, IAX_DELME)) 09565 ao2_unlink(users, user); 09566 user_unref(user); 09567 } 09568 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5123 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, LOG_DEBUG, 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_process().
05124 { 05125 struct ast_iax2_full_hdr fh; 05126 fh.scallno = htons(src | IAX_FLAG_FULL); 05127 fh.dcallno = htons(dst); 05128 fh.ts = 0; 05129 fh.oseqno = 0; 05130 fh.iseqno = 0; 05131 fh.type = AST_FRAME_IAX; 05132 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05133 if (iaxdebug) 05134 iax_showframe(NULL, &fh, 0, sin, 0); 05135 if (option_debug) 05136 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05137 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05138 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05139 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2678 of file chan_iax2.c.
References iax2_peer::addr, ast_copy_flags, ast_dnsmgr_lookup(), ast_get_time_t(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_registry::dnsmgr, iax2_peer::expire, expire_registry(), iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_DEBUG, ast_variable::name, ast_variable::next, option_debug, peer_ref(), peer_unref(), peers, realtime_update_peer(), reg_source_db(), ast_variable::value, and var.
02679 { 02680 struct ast_variable *var = NULL; 02681 struct ast_variable *tmp; 02682 struct iax2_peer *peer=NULL; 02683 time_t regseconds = 0, nowtime; 02684 int dynamic=0; 02685 02686 if (peername) { 02687 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02688 if (!var && sin) 02689 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr)); 02690 } else if (sin) { 02691 char porta[25]; 02692 sprintf(porta, "%d", ntohs(sin->sin_port)); 02693 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02694 if (var) { 02695 /* We'll need the peer name in order to build the structure! */ 02696 for (tmp = var; tmp; tmp = tmp->next) { 02697 if (!strcasecmp(tmp->name, "name")) 02698 peername = tmp->value; 02699 } 02700 } 02701 } 02702 if (!var && peername) { /* Last ditch effort */ 02703 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02704 /*!\note 02705 * If this one loaded something, then we need to ensure that the host 02706 * field matched. The only reason why we can't have this as a criteria 02707 * is because we only have the IP address and the host field might be 02708 * set as a name (and the reverse PTR might not match). 02709 */ 02710 if (var && sin) { 02711 for (tmp = var; tmp; tmp = tmp->next) { 02712 if (!strcasecmp(tmp->name, "host")) { 02713 struct in_addr sin2 = { 0, }; 02714 struct ast_dnsmgr_entry *dnsmgr = NULL; 02715 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02716 /* No match */ 02717 ast_variables_destroy(var); 02718 var = NULL; 02719 } 02720 break; 02721 } 02722 } 02723 } 02724 } 02725 if (!var) 02726 return NULL; 02727 02728 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02729 02730 if (!peer) { 02731 ast_variables_destroy(var); 02732 return NULL; 02733 } 02734 02735 for (tmp = var; tmp; tmp = tmp->next) { 02736 /* Make sure it's not a user only... */ 02737 if (!strcasecmp(tmp->name, "type")) { 02738 if (strcasecmp(tmp->value, "friend") && 02739 strcasecmp(tmp->value, "peer")) { 02740 /* Whoops, we weren't supposed to exist! */ 02741 peer = peer_unref(peer); 02742 break; 02743 } 02744 } else if (!strcasecmp(tmp->name, "regseconds")) { 02745 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02746 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02747 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02748 } else if (!strcasecmp(tmp->name, "port")) { 02749 peer->addr.sin_port = htons(atoi(tmp->value)); 02750 } else if (!strcasecmp(tmp->name, "host")) { 02751 if (!strcasecmp(tmp->value, "dynamic")) 02752 dynamic = 1; 02753 } 02754 } 02755 02756 ast_variables_destroy(var); 02757 02758 if (!peer) 02759 return NULL; 02760 02761 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02762 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02763 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02764 if (peer->expire > -1) { 02765 if (!ast_sched_del(sched, peer->expire)) { 02766 peer->expire = -1; 02767 peer_unref(peer); 02768 } 02769 } 02770 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02771 if (peer->expire == -1) 02772 peer_unref(peer); 02773 } 02774 ao2_link(peers, peer); 02775 if (ast_test_flag(peer, IAX_DYNAMIC)) 02776 reg_source_db(peer); 02777 } else { 02778 ast_set_flag(peer, IAX_TEMPONLY); 02779 } 02780 02781 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02782 time(&nowtime); 02783 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02784 memset(&peer->addr, 0, sizeof(peer->addr)); 02785 realtime_update_peer(peer->name, &peer->addr, 0); 02786 if (option_debug) 02787 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02788 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02789 } 02790 else { 02791 if (option_debug) 02792 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02793 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02794 } 02795 } 02796 02797 return peer; 02798 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2871 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
02872 { 02873 char port[10]; 02874 char regseconds[20]; 02875 02876 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02877 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02878 ast_update_realtime("iaxpeers", "name", peername, 02879 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02880 "regseconds", regseconds, NULL); 02881 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2800 of file chan_iax2.c.
References ast_dnsmgr_lookup(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), iax2_registry::dnsmgr, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, users, ast_variable::value, and var.
02801 { 02802 struct ast_variable *var; 02803 struct ast_variable *tmp; 02804 struct iax2_user *user=NULL; 02805 02806 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02807 if (!var) 02808 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr)); 02809 if (!var && sin) { 02810 char porta[6]; 02811 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02812 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02813 if (!var) 02814 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02815 } 02816 if (!var) { /* Last ditch effort */ 02817 var = ast_load_realtime("iaxusers", "name", username, NULL); 02818 /*!\note 02819 * If this one loaded something, then we need to ensure that the host 02820 * field matched. The only reason why we can't have this as a criteria 02821 * is because we only have the IP address and the host field might be 02822 * set as a name (and the reverse PTR might not match). 02823 */ 02824 if (var) { 02825 for (tmp = var; tmp; tmp = tmp->next) { 02826 if (!strcasecmp(tmp->name, "host")) { 02827 struct in_addr sin2 = { 0, }; 02828 struct ast_dnsmgr_entry *dnsmgr = NULL; 02829 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02830 /* No match */ 02831 ast_variables_destroy(var); 02832 var = NULL; 02833 } 02834 break; 02835 } 02836 } 02837 } 02838 } 02839 if (!var) 02840 return NULL; 02841 02842 tmp = var; 02843 while(tmp) { 02844 /* Make sure it's not a peer only... */ 02845 if (!strcasecmp(tmp->name, "type")) { 02846 if (strcasecmp(tmp->value, "friend") && 02847 strcasecmp(tmp->value, "user")) { 02848 return NULL; 02849 } 02850 } 02851 tmp = tmp->next; 02852 } 02853 02854 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02855 02856 ast_variables_destroy(var); 02857 02858 if (!user) 02859 return NULL; 02860 02861 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02862 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02863 ao2_link(users, user); 02864 } else { 02865 ast_set_flag(user, IAX_TEMPONLY); 02866 } 02867 02868 return user; 02869 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5899 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), and VERBOSE_PREFIX_3.
Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().
05900 { 05901 char data[80]; 05902 struct in_addr in; 05903 char *c, *d; 05904 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05905 c = strchr(data, ':'); 05906 if (c) { 05907 *c = '\0'; 05908 c++; 05909 if (inet_aton(data, &in)) { 05910 d = strchr(c, ':'); 05911 if (d) { 05912 *d = '\0'; 05913 d++; 05914 if (option_verbose > 2) 05915 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05916 ast_inet_ntoa(in), atoi(c), atoi(d)); 05917 iax2_poke_peer(p, 0); 05918 p->expiry = atoi(d); 05919 memset(&p->addr, 0, sizeof(p->addr)); 05920 p->addr.sin_family = AF_INET; 05921 p->addr.sin_addr = in; 05922 p->addr.sin_port = htons(atoi(c)); 05923 if (p->expire > -1) { 05924 if (!ast_sched_del(sched, p->expire)) { 05925 p->expire = -1; 05926 peer_unref(p); 05927 } 05928 } 05929 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05930 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 05931 if (p->expire == -1) 05932 peer_unref(p); 05933 if (iax2_regfunk) 05934 iax2_regfunk(p->name, 1); 05935 register_peer_exten(p, 1); 05936 } 05937 05938 } 05939 } 05940 } 05941 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5819 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_free, ast_strdup, ast_strlen_zero(), ext, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
05820 { 05821 char multi[256]; 05822 char *stringp, *ext; 05823 if (!ast_strlen_zero(regcontext)) { 05824 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05825 stringp = multi; 05826 while((ext = strsep(&stringp, "&"))) { 05827 if (onoff) { 05828 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05829 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05830 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05831 } else 05832 ast_context_remove_extension(regcontext, ext, 1, NULL); 05833 } 05834 } 05835 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5287 of file chan_iax2.c.
References iax2_peer::addr, 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_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, iax2_registry::expire, chan_iax2_pvt::expiry, expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, iaxs, iaxsl, inaddrcmp(), key(), LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_registry::secret, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
05288 { 05289 char requeststr[256] = ""; 05290 char peer[256] = ""; 05291 char md5secret[256] = ""; 05292 char rsasecret[256] = ""; 05293 char secret[256] = ""; 05294 struct iax2_peer *p = NULL; 05295 struct ast_key *key; 05296 char *keyn; 05297 int x; 05298 int expire = 0; 05299 int res = -1; 05300 05301 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05302 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05303 if (ies->username) 05304 ast_copy_string(peer, ies->username, sizeof(peer)); 05305 if (ies->password) 05306 ast_copy_string(secret, ies->password, sizeof(secret)); 05307 if (ies->md5_result) 05308 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05309 if (ies->rsa_result) 05310 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05311 if (ies->refresh) 05312 expire = ies->refresh; 05313 05314 if (ast_strlen_zero(peer)) { 05315 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05316 return -1; 05317 } 05318 05319 /* SLD: first call to lookup peer during registration */ 05320 ast_mutex_unlock(&iaxsl[callno]); 05321 p = find_peer(peer, 1); 05322 ast_mutex_lock(&iaxsl[callno]); 05323 if (!p || !iaxs[callno]) { 05324 if (authdebug && !p) 05325 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05326 goto return_unref; 05327 } 05328 05329 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05330 if (authdebug) 05331 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05332 goto return_unref; 05333 } 05334 05335 if (!ast_apply_ha(p->ha, sin)) { 05336 if (authdebug) 05337 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05338 goto return_unref; 05339 } 05340 if (!inaddrcmp(&p->addr, sin)) 05341 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05342 ast_string_field_set(iaxs[callno], secret, p->secret); 05343 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05344 /* Check secret against what we have on file */ 05345 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05346 if (!ast_strlen_zero(p->inkeys)) { 05347 char tmpkeys[256]; 05348 char *stringp=NULL; 05349 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05350 stringp=tmpkeys; 05351 keyn = strsep(&stringp, ":"); 05352 while(keyn) { 05353 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05354 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05355 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05356 break; 05357 } else if (!key) 05358 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05359 keyn = strsep(&stringp, ":"); 05360 } 05361 if (!keyn) { 05362 if (authdebug) 05363 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05364 goto return_unref; 05365 } 05366 } else { 05367 if (authdebug) 05368 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05369 goto return_unref; 05370 } 05371 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05372 struct MD5Context md5; 05373 unsigned char digest[16]; 05374 char *tmppw, *stringp; 05375 05376 tmppw = ast_strdupa(p->secret); 05377 stringp = tmppw; 05378 while((tmppw = strsep(&stringp, ";"))) { 05379 MD5Init(&md5); 05380 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05381 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05382 MD5Final(digest, &md5); 05383 for (x=0;x<16;x++) 05384 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05385 if (!strcasecmp(requeststr, md5secret)) 05386 break; 05387 } 05388 if (tmppw) { 05389 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05390 } else { 05391 if (authdebug) 05392 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05393 goto return_unref; 05394 } 05395 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05396 /* They've provided a plain text password and we support that */ 05397 if (strcmp(secret, p->secret)) { 05398 if (authdebug) 05399 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05400 goto return_unref; 05401 } else 05402 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05403 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05404 if (authdebug) 05405 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05406 goto return_unref; 05407 } 05408 ast_string_field_set(iaxs[callno], peer, peer); 05409 /* Choose lowest expiry number */ 05410 if (expire && (expire < iaxs[callno]->expiry)) 05411 iaxs[callno]->expiry = expire; 05412 05413 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05414 05415 res = 0; 05416 05417 return_unref: 05418 if (p) 05419 peer_unref(p); 05420 05421 return res; 05422 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6078 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, iax2_peer::authmethods, iax_ie_data::buf, 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, iaxs, iaxsl, LOG_WARNING, peer_unref(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
06079 { 06080 struct iax_ie_data ied; 06081 struct iax2_peer *p; 06082 char challenge[10]; 06083 const char *peer_name; 06084 int res = -1; 06085 06086 peer_name = ast_strdupa(iaxs[callno]->peer); 06087 06088 /* SLD: third call to find_peer in registration */ 06089 ast_mutex_unlock(&iaxsl[callno]); 06090 p = find_peer(peer_name, 1); 06091 ast_mutex_lock(&iaxsl[callno]); 06092 if (!iaxs[callno]) 06093 goto return_unref; 06094 if (!p) { 06095 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06096 goto return_unref; 06097 } 06098 06099 memset(&ied, 0, sizeof(ied)); 06100 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06101 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06102 /* Build the challenge */ 06103 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06104 ast_string_field_set(iaxs[callno], challenge, challenge); 06105 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06106 } 06107 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06108 06109 res = 0; 06110 06111 return_unref: 06112 peer_unref(p); 06113 06114 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 06115 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6117 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
06118 { 06119 struct iax2_registry *reg; 06120 /* Start pessimistic */ 06121 struct iax_ie_data ied; 06122 char peer[256] = ""; 06123 char challenge[256] = ""; 06124 int res; 06125 int authmethods = 0; 06126 if (ies->authmethods) 06127 authmethods = ies->authmethods; 06128 if (ies->username) 06129 ast_copy_string(peer, ies->username, sizeof(peer)); 06130 if (ies->challenge) 06131 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06132 memset(&ied, 0, sizeof(ied)); 06133 reg = iaxs[callno]->reg; 06134 if (reg) { 06135 if (inaddrcmp(®->addr, sin)) { 06136 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06137 return -1; 06138 } 06139 if (ast_strlen_zero(reg->secret)) { 06140 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06141 reg->regstate = REG_STATE_NOAUTH; 06142 return -1; 06143 } 06144 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06145 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06146 if (reg->secret[0] == '[') { 06147 char tmpkey[256]; 06148 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06149 tmpkey[strlen(tmpkey) - 1] = '\0'; 06150 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06151 } else 06152 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06153 if (!res) { 06154 reg->regstate = REG_STATE_AUTHSENT; 06155 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06156 } else 06157 return -1; 06158 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06159 } else 06160 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06161 return -1; 06162 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4576 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().
04577 { 04578 switch(regstate) { 04579 case REG_STATE_UNREGISTERED: 04580 return "Unregistered"; 04581 case REG_STATE_REGSENT: 04582 return "Request Sent"; 04583 case REG_STATE_AUTHSENT: 04584 return "Auth. Sent"; 04585 case REG_STATE_REGISTERED: 04586 return "Registered"; 04587 case REG_STATE_REJECTED: 04588 return "Rejected"; 04589 case REG_STATE_TIMEOUT: 04590 return "Timeout"; 04591 case REG_STATE_NOAUTH: 04592 return "No Authentication"; 04593 default: 04594 return "Unknown"; 04595 } 04596 }
static int reload | ( | void | ) | [static] |
Definition at line 10009 of file chan_iax2.c.
References reload_config().
10010 { 10011 return reload_config(); 10012 }
static int reload_config | ( | void | ) | [static] |
Definition at line 9983 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, iax2_do_register(), iax_provision_reload(), poke_all_peers(), prune_peers(), prune_users(), reload_firmware(), and set_config().
09984 { 09985 char *config = "iax.conf"; 09986 struct iax2_registry *reg; 09987 09988 if (set_config(config, 1) > 0) { 09989 prune_peers(); 09990 prune_users(); 09991 AST_LIST_LOCK(®istrations); 09992 AST_LIST_TRAVERSE(®istrations, reg, entry) 09993 iax2_do_register(reg); 09994 AST_LIST_UNLOCK(®istrations); 09995 /* Qualify hosts, too */ 09996 poke_all_peers(); 09997 } 09998 reload_firmware(0); 09999 iax_provision_reload(); 10000 10001 return 0; 10002 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1739 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), errno, ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by __unload_module(), load_module(), and reload_config().
01740 { 01741 struct iax_firmware *cur, *curl, *curp; 01742 DIR *fwd; 01743 struct dirent *de; 01744 char dir[256]; 01745 char fn[256]; 01746 /* Mark all as dead */ 01747 ast_mutex_lock(&waresl.lock); 01748 cur = waresl.wares; 01749 while(cur) { 01750 cur->dead = 1; 01751 cur = cur->next; 01752 } 01753 01754 /* Now that we've freed them, load the new ones */ 01755 if (!unload) { 01756 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01757 fwd = opendir(dir); 01758 if (fwd) { 01759 while((de = readdir(fwd))) { 01760 if (de->d_name[0] != '.') { 01761 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01762 if (!try_firmware(fn)) { 01763 if (option_verbose > 1) 01764 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01765 } 01766 } 01767 } 01768 closedir(fwd); 01769 } else 01770 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01771 } 01772 01773 /* Clean up leftovers */ 01774 cur = waresl.wares; 01775 curp = NULL; 01776 while(cur) { 01777 curl = cur; 01778 cur = cur->next; 01779 if (curl->dead) { 01780 if (curp) { 01781 curp->next = cur; 01782 } else { 01783 waresl.wares = cur; 01784 } 01785 destroy_firmware(curl); 01786 } else { 01787 curp = cur; 01788 } 01789 } 01790 ast_mutex_unlock(&waresl.lock); 01791 }
Definition at line 6618 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
06619 { 06620 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06621 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06622 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06623 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06624 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06625 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06626 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06627 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8784 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), LOG_DEBUG, and option_debug.
Referenced by start_network_thread().
08785 { 08786 int count; 08787 int res; 08788 struct timeval tv; 08789 struct timespec ts; 08790 08791 for (;;) { 08792 res = ast_sched_wait(sched); 08793 if ((res > 1000) || (res < 0)) 08794 res = 1000; 08795 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08796 ts.tv_sec = tv.tv_sec; 08797 ts.tv_nsec = tv.tv_usec * 1000; 08798 08799 pthread_testcancel(); 08800 ast_mutex_lock(&sched_lock); 08801 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08802 ast_mutex_unlock(&sched_lock); 08803 pthread_testcancel(); 08804 08805 count = ast_sched_runq(sched); 08806 if (option_debug && count >= 20) 08807 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08808 } 08809 return NULL; 08810 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 2531 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02532 { 02533 int type, len; 02534 int ret; 02535 int needfree = 0; 02536 02537 /* Attempt to recover wrapped timestamps */ 02538 unwrap_timestamp(fr); 02539 02540 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02541 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02542 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02543 else { 02544 #if 0 02545 if (option_debug) 02546 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02547 #endif 02548 fr->af.delivery = ast_tv(0,0); 02549 } 02550 02551 type = JB_TYPE_CONTROL; 02552 len = 0; 02553 02554 if(fr->af.frametype == AST_FRAME_VOICE) { 02555 type = JB_TYPE_VOICE; 02556 len = ast_codec_get_samples(&fr->af) / 8; 02557 } else if(fr->af.frametype == AST_FRAME_CNG) { 02558 type = JB_TYPE_SILENCE; 02559 } 02560 02561 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02562 if (tsout) 02563 *tsout = fr->ts; 02564 __do_deliver(fr); 02565 return -1; 02566 } 02567 02568 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02569 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02570 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02571 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02572 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02573 jb_frame frame; 02574 02575 /* deliver any frames in the jb */ 02576 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02577 __do_deliver(frame.data); 02578 /* __do_deliver() can make the call disappear */ 02579 if (!iaxs[fr->callno]) 02580 return -1; 02581 } 02582 02583 jb_reset(iaxs[fr->callno]->jb); 02584 02585 if (iaxs[fr->callno]->jbid > -1) 02586 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02587 02588 iaxs[fr->callno]->jbid = -1; 02589 02590 /* deliver this frame now */ 02591 if (tsout) 02592 *tsout = fr->ts; 02593 __do_deliver(fr); 02594 return -1; 02595 } 02596 02597 /* insert into jitterbuffer */ 02598 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02599 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02600 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02601 if (ret == JB_DROP) { 02602 needfree++; 02603 } else if (ret == JB_SCHED) { 02604 update_jbsched(iaxs[fr->callno]); 02605 } 02606 if (tsout) 02607 *tsout = fr->ts; 02608 if (needfree) { 02609 /* Free our iax frame */ 02610 iax2_frame_free(fr); 02611 return -1; 02612 } 02613 return 0; 02614 }
static int send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4860 of file chan_iax2.c.
References __send_command().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), send_command_locked(), and socket_process().
04861 { 04862 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04863 }
static int send_command_final | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4879 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
04880 { 04881 int call_num = i->callno; 04882 /* It is assumed that the callno has already been locked */ 04883 iax2_predestroy(i->callno); 04884 if (!iaxs[call_num]) 04885 return -1; 04886 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04887 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4889 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04890 { 04891 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04892 }
static int send_command_locked | ( | unsigned short | callno, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4865 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
04866 { 04867 int res; 04868 ast_mutex_lock(&iaxsl[callno]); 04869 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04870 ast_mutex_unlock(&iaxsl[callno]); 04871 return res; 04872 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4894 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04895 { 04896 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04897 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1028 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
01029 { 01030 #ifdef SCHED_MULTITHREADED 01031 if (schedule_action(__send_lagrq, data)) 01032 #endif 01033 __send_lagrq(data); 01034 return 0; 01035 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1864 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_registry::addr, ast_inet_ntoa(), ast_log(), iax_frame::callno, iax2_registry::callno, iax_frame::data, iax_frame::datalen, errno, error(), handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01865 { 01866 int res; 01867 int callno = f->callno; 01868 01869 /* Don't send if there was an error, but return error instead */ 01870 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01871 return -1; 01872 01873 /* Called with iaxsl held */ 01874 if (option_debug > 2 && iaxdebug) 01875 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 01876 if (f->transfer) { 01877 if (iaxdebug) 01878 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01879 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01880 sizeof(iaxs[callno]->transfer)); 01881 } else { 01882 if (iaxdebug) 01883 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01884 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01885 sizeof(iaxs[callno]->addr)); 01886 } 01887 if (res < 0) { 01888 if (option_debug && iaxdebug) 01889 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01890 handle_error(); 01891 } else 01892 res = 0; 01893 return res; 01894 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 993 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00994 { 00995 #ifdef SCHED_MULTITHREADED 00996 if (schedule_action(__send_ping, data)) 00997 #endif 00998 __send_ping(data); 00999 return 0; 01000 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6301 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, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, LOG_DEBUG, ast_iax2_meta_hdr::metacmd, option_debug, 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().
06302 { 06303 int res = 0; 06304 struct iax_frame *fr; 06305 struct ast_iax2_meta_hdr *meta; 06306 struct ast_iax2_meta_trunk_hdr *mth; 06307 int calls = 0; 06308 06309 /* Point to frame */ 06310 fr = (struct iax_frame *)tpeer->trunkdata; 06311 /* Point to meta data */ 06312 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06313 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06314 if (tpeer->trunkdatalen) { 06315 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06316 meta->zeros = 0; 06317 meta->metacmd = IAX_META_TRUNK; 06318 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06319 meta->cmddata = IAX_META_TRUNK_MINI; 06320 else 06321 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06322 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06323 /* And the rest of the ast_iax2 header */ 06324 fr->direction = DIRECTION_OUTGRESS; 06325 fr->retrans = -1; 06326 fr->transfer = 0; 06327 /* Any appropriate call will do */ 06328 fr->data = fr->afdata; 06329 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06330 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06331 calls = tpeer->calls; 06332 #if 0 06333 if (option_debug) 06334 ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts)); 06335 #endif 06336 /* Reset transmit trunk side data */ 06337 tpeer->trunkdatalen = 0; 06338 tpeer->calls = 0; 06339 } 06340 if (res < 0) 06341 return res; 06342 return calls; 06343 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9615 of file chan_iax2.c.
References __ao2_link(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), 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_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, ast_variable::next, option_verbose, peer_unref(), peers, portno, prefs, reg_source_db(), iax2_registry::secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09616 { 09617 struct ast_config *cfg, *ucfg; 09618 int capability=iax2_capability; 09619 struct ast_variable *v; 09620 char *cat; 09621 const char *utype; 09622 const char *tosval; 09623 int format; 09624 int portno = IAX_DEFAULT_PORTNO; 09625 int x; 09626 struct iax2_user *user; 09627 struct iax2_peer *peer; 09628 struct ast_netsock *ns; 09629 #if 0 09630 static unsigned short int last_port=0; 09631 #endif 09632 09633 cfg = ast_config_load(config_file); 09634 09635 if (!cfg) { 09636 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09637 return -1; 09638 } 09639 09640 if (reload) { 09641 set_config_destroy(); 09642 } 09643 09644 /* Reset global codec prefs */ 09645 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09646 09647 /* Reset Global Flags */ 09648 memset(&globalflags, 0, sizeof(globalflags)); 09649 ast_set_flag(&globalflags, IAX_RTUPDATE); 09650 09651 #ifdef SO_NO_CHECK 09652 nochecksums = 0; 09653 #endif 09654 09655 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09656 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09657 09658 maxauthreq = 3; 09659 09660 v = ast_variable_browse(cfg, "general"); 09661 09662 /* Seed initial tos value */ 09663 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09664 if (tosval) { 09665 if (ast_str2tos(tosval, &tos)) 09666 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09667 } 09668 while(v) { 09669 if (!strcasecmp(v->name, "bindport")){ 09670 if (reload) 09671 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09672 else 09673 portno = atoi(v->value); 09674 } else if (!strcasecmp(v->name, "pingtime")) 09675 ping_time = atoi(v->value); 09676 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09677 if (reload) { 09678 if (atoi(v->value) != iaxthreadcount) 09679 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09680 } else { 09681 iaxthreadcount = atoi(v->value); 09682 if (iaxthreadcount < 1) { 09683 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09684 iaxthreadcount = 1; 09685 } else if (iaxthreadcount > 256) { 09686 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09687 iaxthreadcount = 256; 09688 } 09689 } 09690 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09691 if (reload) { 09692 AST_LIST_LOCK(&dynamic_list); 09693 iaxmaxthreadcount = atoi(v->value); 09694 AST_LIST_UNLOCK(&dynamic_list); 09695 } else { 09696 iaxmaxthreadcount = atoi(v->value); 09697 if (iaxmaxthreadcount < 0) { 09698 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09699 iaxmaxthreadcount = 0; 09700 } else if (iaxmaxthreadcount > 256) { 09701 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09702 iaxmaxthreadcount = 256; 09703 } 09704 } 09705 } else if (!strcasecmp(v->name, "nochecksums")) { 09706 #ifdef SO_NO_CHECK 09707 if (ast_true(v->value)) 09708 nochecksums = 1; 09709 else 09710 nochecksums = 0; 09711 #else 09712 if (ast_true(v->value)) 09713 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09714 #endif 09715 } 09716 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09717 maxjitterbuffer = atoi(v->value); 09718 else if (!strcasecmp(v->name, "resyncthreshold")) 09719 resyncthreshold = atoi(v->value); 09720 else if (!strcasecmp(v->name, "maxjitterinterps")) 09721 maxjitterinterps = atoi(v->value); 09722 else if (!strcasecmp(v->name, "lagrqtime")) 09723 lagrq_time = atoi(v->value); 09724 else if (!strcasecmp(v->name, "maxregexpire")) 09725 max_reg_expire = atoi(v->value); 09726 else if (!strcasecmp(v->name, "minregexpire")) 09727 min_reg_expire = atoi(v->value); 09728 else if (!strcasecmp(v->name, "bindaddr")) { 09729 if (reload) { 09730 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09731 } else { 09732 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09733 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09734 } else { 09735 if (option_verbose > 1) { 09736 if (strchr(v->value, ':')) 09737 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09738 else 09739 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09740 } 09741 if (defaultsockfd < 0) 09742 defaultsockfd = ast_netsock_sockfd(ns); 09743 ast_netsock_unref(ns); 09744 } 09745 } 09746 } else if (!strcasecmp(v->name, "authdebug")) 09747 authdebug = ast_true(v->value); 09748 else if (!strcasecmp(v->name, "encryption")) 09749 iax2_encryption = get_encrypt_methods(v->value); 09750 else if (!strcasecmp(v->name, "notransfer")) { 09751 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09752 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09753 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09754 } else if (!strcasecmp(v->name, "transfer")) { 09755 if (!strcasecmp(v->value, "mediaonly")) { 09756 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09757 } else if (ast_true(v->value)) { 09758 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09759 } else 09760 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09761 } else if (!strcasecmp(v->name, "codecpriority")) { 09762 if(!strcasecmp(v->value, "caller")) 09763 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09764 else if(!strcasecmp(v->value, "disabled")) 09765 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09766 else if(!strcasecmp(v->value, "reqonly")) { 09767 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09768 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09769 } 09770 } else if (!strcasecmp(v->name, "jitterbuffer")) 09771 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09772 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09773 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09774 else if (!strcasecmp(v->name, "delayreject")) 09775 delayreject = ast_true(v->value); 09776 else if (!strcasecmp(v->name, "rtcachefriends")) 09777 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09778 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09779 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09780 else if (!strcasecmp(v->name, "rtupdate")) 09781 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09782 else if (!strcasecmp(v->name, "trunktimestamps")) 09783 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09784 else if (!strcasecmp(v->name, "rtautoclear")) { 09785 int i = atoi(v->value); 09786 if(i > 0) 09787 global_rtautoclear = i; 09788 else 09789 i = 0; 09790 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09791 } else if (!strcasecmp(v->name, "trunkfreq")) { 09792 trunkfreq = atoi(v->value); 09793 if (trunkfreq < 10) 09794 trunkfreq = 10; 09795 } else if (!strcasecmp(v->name, "autokill")) { 09796 if (sscanf(v->value, "%d", &x) == 1) { 09797 if (x >= 0) 09798 autokill = x; 09799 else 09800 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09801 } else if (ast_true(v->value)) { 09802 autokill = DEFAULT_MAXMS; 09803 } else { 09804 autokill = 0; 09805 } 09806 } else if (!strcasecmp(v->name, "bandwidth")) { 09807 if (!strcasecmp(v->value, "low")) { 09808 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09809 } else if (!strcasecmp(v->value, "medium")) { 09810 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09811 } else if (!strcasecmp(v->value, "high")) { 09812 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09813 } else 09814 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09815 } else if (!strcasecmp(v->name, "allow")) { 09816 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09817 } else if (!strcasecmp(v->name, "disallow")) { 09818 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09819 } else if (!strcasecmp(v->name, "register")) { 09820 iax2_register(v->value, v->lineno); 09821 } else if (!strcasecmp(v->name, "iaxcompat")) { 09822 iaxcompat = ast_true(v->value); 09823 } else if (!strcasecmp(v->name, "regcontext")) { 09824 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09825 /* Create context if it doesn't exist already */ 09826 if (!ast_context_find(regcontext)) 09827 ast_context_create(NULL, regcontext, "IAX2"); 09828 } else if (!strcasecmp(v->name, "tos")) { 09829 if (ast_str2tos(v->value, &tos)) 09830 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09831 } else if (!strcasecmp(v->name, "accountcode")) { 09832 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09833 } else if (!strcasecmp(v->name, "mohinterpret")) { 09834 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09835 } else if (!strcasecmp(v->name, "mohsuggest")) { 09836 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09837 } else if (!strcasecmp(v->name, "amaflags")) { 09838 format = ast_cdr_amaflags2int(v->value); 09839 if (format < 0) { 09840 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09841 } else { 09842 amaflags = format; 09843 } 09844 } else if (!strcasecmp(v->name, "language")) { 09845 ast_copy_string(language, v->value, sizeof(language)); 09846 } else if (!strcasecmp(v->name, "maxauthreq")) { 09847 maxauthreq = atoi(v->value); 09848 if (maxauthreq < 0) 09849 maxauthreq = 0; 09850 } else if (!strcasecmp(v->name, "adsi")) { 09851 adsi = ast_true(v->value); 09852 } /*else if (strcasecmp(v->name,"type")) */ 09853 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09854 v = v->next; 09855 } 09856 09857 if (defaultsockfd < 0) { 09858 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09859 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09860 } else { 09861 if (option_verbose > 1) 09862 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09863 defaultsockfd = ast_netsock_sockfd(ns); 09864 ast_netsock_unref(ns); 09865 } 09866 } 09867 if (reload) { 09868 ast_netsock_release(outsock); 09869 outsock = ast_netsock_list_alloc(); 09870 if (!outsock) { 09871 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09872 return -1; 09873 } 09874 ast_netsock_init(outsock); 09875 } 09876 09877 if (min_reg_expire > max_reg_expire) { 09878 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09879 min_reg_expire, max_reg_expire, max_reg_expire); 09880 min_reg_expire = max_reg_expire; 09881 } 09882 iax2_capability = capability; 09883 09884 ucfg = ast_config_load("users.conf"); 09885 if (ucfg) { 09886 struct ast_variable *gen; 09887 int genhasiax; 09888 int genregisteriax; 09889 const char *hasiax, *registeriax; 09890 09891 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09892 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09893 gen = ast_variable_browse(ucfg, "general"); 09894 cat = ast_category_browse(ucfg, NULL); 09895 while (cat) { 09896 if (strcasecmp(cat, "general")) { 09897 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09898 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09899 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09900 /* Start with general parameters, then specific parameters, user and peer */ 09901 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09902 if (user) { 09903 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09904 user = user_unref(user); 09905 } 09906 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09907 if (peer) { 09908 if (ast_test_flag(peer, IAX_DYNAMIC)) 09909 reg_source_db(peer); 09910 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09911 peer = peer_unref(peer); 09912 } 09913 } 09914 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09915 char tmp[256]; 09916 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09917 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09918 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09919 if (!host) 09920 host = ast_variable_retrieve(ucfg, "general", "host"); 09921 if (!username) 09922 username = ast_variable_retrieve(ucfg, "general", "username"); 09923 if (!secret) 09924 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09925 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09926 if (!ast_strlen_zero(secret)) 09927 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09928 else 09929 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09930 iax2_register(tmp, 0); 09931 } 09932 } 09933 } 09934 cat = ast_category_browse(ucfg, cat); 09935 } 09936 ast_config_destroy(ucfg); 09937 } 09938 09939 cat = ast_category_browse(cfg, NULL); 09940 while(cat) { 09941 if (strcasecmp(cat, "general")) { 09942 utype = ast_variable_retrieve(cfg, cat, "type"); 09943 if (utype) { 09944 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 09945 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 09946 if (user) { 09947 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09948 user = user_unref(user); 09949 } 09950 } 09951 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 09952 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 09953 if (peer) { 09954 if (ast_test_flag(peer, IAX_DYNAMIC)) 09955 reg_source_db(peer); 09956 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09957 peer = peer_unref(peer); 09958 } 09959 } else if (strcasecmp(utype, "user")) { 09960 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 09961 } 09962 } else 09963 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 09964 } 09965 cat = ast_category_browse(cfg, cat); 09966 } 09967 ast_config_destroy(cfg); 09968 set_timing(); 09969 return 1; 09970 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9599 of file chan_iax2.c.
References ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09600 { 09601 strcpy(accountcode, ""); 09602 strcpy(language, ""); 09603 strcpy(mohinterpret, "default"); 09604 strcpy(mohsuggest, ""); 09605 amaflags = 0; 09606 delayreject = 0; 09607 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09608 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09609 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09610 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09611 delete_users(); 09612 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9584 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09585 { 09586 #ifdef HAVE_ZAPTEL 09587 int bs = trunkfreq * 8; 09588 if (timingfd > -1) { 09589 if ( 09590 #ifdef ZT_TIMERACK 09591 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09592 #endif 09593 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09594 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09595 } 09596 #endif 09597 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 759 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_sched_add(), iax2_transmit(), and socket_read().
00760 { 00761 ast_mutex_lock(lock); 00762 ast_cond_signal(cond); 00763 ast_mutex_unlock(lock); 00764 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6770 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, 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_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, iax2_registry::callno, iax_frame::callno, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_num, ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_sched_add(), 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_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, 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_STATE_UNCHANGED, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxq, iaxs, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_frame::len, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, ast_channel::nativeformats, NEW_ALLOW, NEW_PREVENT, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, ast_frame::samples, save_rr(), schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
06771 { 06772 struct sockaddr_in sin; 06773 int res; 06774 int updatehistory=1; 06775 int new = NEW_PREVENT; 06776 void *ptr; 06777 int dcallno = 0; 06778 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06779 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06780 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06781 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06782 struct ast_iax2_meta_trunk_hdr *mth; 06783 struct ast_iax2_meta_trunk_entry *mte; 06784 struct ast_iax2_meta_trunk_mini *mtm; 06785 struct iax_frame *fr; 06786 struct iax_frame *cur; 06787 struct ast_frame f = { 0, }; 06788 struct ast_channel *c; 06789 struct iax2_dpcache *dp; 06790 struct iax2_peer *peer; 06791 struct iax2_trunk_peer *tpeer; 06792 struct timeval rxtrunktime; 06793 struct iax_ies ies; 06794 struct iax_ie_data ied0, ied1; 06795 int format; 06796 int fd; 06797 int exists; 06798 int minivid = 0; 06799 unsigned int ts; 06800 char empty[32]=""; /* Safety measure */ 06801 struct iax_frame *duped_fr; 06802 char host_pref_buf[128]; 06803 char caller_pref_buf[128]; 06804 struct ast_codec_pref pref; 06805 char *using_prefs = "mine"; 06806 06807 /* allocate an iax_frame with 4096 bytes of data buffer */ 06808 fr = alloca(sizeof(*fr) + 4096); 06809 fr->callno = 0; 06810 fr->afdatalen = 4096; /* From alloca() above */ 06811 06812 /* Copy frequently used parameters to the stack */ 06813 res = thread->buf_len; 06814 fd = thread->iofd; 06815 memcpy(&sin, &thread->iosin, sizeof(sin)); 06816 06817 if (res < sizeof(*mh)) { 06818 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06819 return 1; 06820 } 06821 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06822 if (res < sizeof(*vh)) { 06823 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06824 return 1; 06825 } 06826 06827 /* This is a video frame, get call number */ 06828 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd); 06829 minivid = 1; 06830 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06831 unsigned char metatype; 06832 06833 if (res < sizeof(*meta)) { 06834 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06835 return 1; 06836 } 06837 06838 /* This is a meta header */ 06839 switch(meta->metacmd) { 06840 case IAX_META_TRUNK: 06841 if (res < (sizeof(*meta) + sizeof(*mth))) { 06842 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06843 sizeof(*meta) + sizeof(*mth)); 06844 return 1; 06845 } 06846 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06847 ts = ntohl(mth->ts); 06848 metatype = meta->cmddata; 06849 res -= (sizeof(*meta) + sizeof(*mth)); 06850 ptr = mth->data; 06851 tpeer = find_tpeer(&sin, fd); 06852 if (!tpeer) { 06853 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06854 return 1; 06855 } 06856 tpeer->trunkact = ast_tvnow(); 06857 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06858 tpeer->rxtrunktime = tpeer->trunkact; 06859 rxtrunktime = tpeer->rxtrunktime; 06860 ast_mutex_unlock(&tpeer->lock); 06861 while(res >= sizeof(*mte)) { 06862 /* Process channels */ 06863 unsigned short callno, trunked_ts, len; 06864 06865 if (metatype == IAX_META_TRUNK_MINI) { 06866 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06867 ptr += sizeof(*mtm); 06868 res -= sizeof(*mtm); 06869 len = ntohs(mtm->len); 06870 callno = ntohs(mtm->mini.callno); 06871 trunked_ts = ntohs(mtm->mini.ts); 06872 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06873 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06874 ptr += sizeof(*mte); 06875 res -= sizeof(*mte); 06876 len = ntohs(mte->len); 06877 callno = ntohs(mte->callno); 06878 trunked_ts = 0; 06879 } else { 06880 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06881 break; 06882 } 06883 /* Stop if we don't have enough data */ 06884 if (len > res) 06885 break; 06886 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd); 06887 if (fr->callno) { 06888 ast_mutex_lock(&iaxsl[fr->callno]); 06889 /* If it's a valid call, deliver the contents. If not, we 06890 drop it, since we don't have a scallno to use for an INVAL */ 06891 /* Process as a mini frame */ 06892 memset(&f, 0, sizeof(f)); 06893 f.frametype = AST_FRAME_VOICE; 06894 if (iaxs[fr->callno]) { 06895 if (iaxs[fr->callno]->voiceformat > 0) { 06896 f.subclass = iaxs[fr->callno]->voiceformat; 06897 f.datalen = len; 06898 if (f.datalen >= 0) { 06899 if (f.datalen) 06900 f.data = ptr; 06901 if(trunked_ts) { 06902 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06903 } else 06904 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06905 /* Don't pass any packets until we're started */ 06906 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06907 /* Common things */ 06908 f.src = "IAX2"; 06909 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06910 f.samples = ast_codec_get_samples(&f); 06911 iax_frame_wrap(fr, &f); 06912 duped_fr = iaxfrdup2(fr); 06913 if (duped_fr) { 06914 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06915 } 06916 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06917 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06918 iaxs[fr->callno]->last = fr->ts; 06919 #if 1 06920 if (option_debug && iaxdebug) 06921 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06922 #endif 06923 } 06924 } 06925 } else { 06926 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06927 } 06928 } else { 06929 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06930 iax2_vnak(fr->callno); 06931 } 06932 } 06933 ast_mutex_unlock(&iaxsl[fr->callno]); 06934 } 06935 ptr += len; 06936 res -= len; 06937 } 06938 06939 } 06940 return 1; 06941 } 06942 06943 #ifdef DEBUG_SUPPORT 06944 if (iaxdebug && (res >= sizeof(*fh))) 06945 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06946 #endif 06947 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06948 if (res < sizeof(*fh)) { 06949 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06950 return 1; 06951 } 06952 06953 /* Get the destination call number */ 06954 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06955 /* Retrieve the type and subclass */ 06956 f.frametype = fh->type; 06957 if (f.frametype == AST_FRAME_VIDEO) { 06958 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06959 } else { 06960 f.subclass = uncompress_subclass(fh->csub); 06961 } 06962 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06963 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06964 (f.subclass == IAX_COMMAND_REGREL))) 06965 new = NEW_ALLOW; 06966 } else { 06967 /* Don't know anything about it yet */ 06968 f.frametype = AST_FRAME_NULL; 06969 f.subclass = 0; 06970 } 06971 06972 if (!fr->callno) 06973 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd); 06974 06975 if (fr->callno > 0) 06976 ast_mutex_lock(&iaxsl[fr->callno]); 06977 06978 if (!fr->callno || !iaxs[fr->callno]) { 06979 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06980 frame, reply with an inval */ 06981 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06982 /* We can only raw hangup control frames */ 06983 if (((f.subclass != IAX_COMMAND_INVAL) && 06984 (f.subclass != IAX_COMMAND_TXCNT) && 06985 (f.subclass != IAX_COMMAND_TXACC) && 06986 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06987 (f.frametype != AST_FRAME_IAX)) 06988 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06989 fd); 06990 } 06991 if (fr->callno > 0) 06992 ast_mutex_unlock(&iaxsl[fr->callno]); 06993 return 1; 06994 } 06995 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06996 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06997 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06998 ast_mutex_unlock(&iaxsl[fr->callno]); 06999 return 1; 07000 } 07001 #ifdef DEBUG_SUPPORT 07002 else if (iaxdebug) 07003 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07004 #endif 07005 } 07006 07007 /* count this frame */ 07008 iaxs[fr->callno]->frames_received++; 07009 07010 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07011 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07012 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 07013 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 07014 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07015 if (option_debug && iaxdebug) 07016 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07017 /* Check if it's out of order (and not an ACK or INVAL) */ 07018 fr->oseqno = fh->oseqno; 07019 fr->iseqno = fh->iseqno; 07020 fr->ts = ntohl(fh->ts); 07021 #ifdef IAXTESTS 07022 if (test_resync) { 07023 if (option_debug) 07024 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07025 fr->ts += test_resync; 07026 } 07027 #endif /* IAXTESTS */ 07028 #if 0 07029 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07030 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07031 (f.subclass == IAX_COMMAND_NEW || 07032 f.subclass == IAX_COMMAND_AUTHREQ || 07033 f.subclass == IAX_COMMAND_ACCEPT || 07034 f.subclass == IAX_COMMAND_REJECT)) ) ) 07035 #endif 07036 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07037 updatehistory = 0; 07038 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07039 (iaxs[fr->callno]->iseqno || 07040 ((f.subclass != IAX_COMMAND_TXCNT) && 07041 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07042 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07043 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07044 (f.subclass != IAX_COMMAND_TXACC)) || 07045 (f.frametype != AST_FRAME_IAX))) { 07046 if ( 07047 ((f.subclass != IAX_COMMAND_ACK) && 07048 (f.subclass != IAX_COMMAND_INVAL) && 07049 (f.subclass != IAX_COMMAND_TXCNT) && 07050 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07051 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07052 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07053 (f.subclass != IAX_COMMAND_TXACC) && 07054 (f.subclass != IAX_COMMAND_VNAK)) || 07055 (f.frametype != AST_FRAME_IAX)) { 07056 /* If it's not an ACK packet, it's out of order. */ 07057 if (option_debug) 07058 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07059 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07060 /* Check to see if we need to request retransmission, 07061 * and take sequence number wraparound into account */ 07062 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07063 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07064 if ((f.frametype != AST_FRAME_IAX) || 07065 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07066 if (option_debug) 07067 ast_log(LOG_DEBUG, "Acking anyway\n"); 07068 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07069 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07070 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07071 } 07072 } else { 07073 /* Send a VNAK requesting retransmission */ 07074 iax2_vnak(fr->callno); 07075 } 07076 ast_mutex_unlock(&iaxsl[fr->callno]); 07077 return 1; 07078 } 07079 } else { 07080 /* Increment unless it's an ACK or VNAK */ 07081 if (((f.subclass != IAX_COMMAND_ACK) && 07082 (f.subclass != IAX_COMMAND_INVAL) && 07083 (f.subclass != IAX_COMMAND_TXCNT) && 07084 (f.subclass != IAX_COMMAND_TXACC) && 07085 (f.subclass != IAX_COMMAND_VNAK)) || 07086 (f.frametype != AST_FRAME_IAX)) 07087 iaxs[fr->callno]->iseqno++; 07088 } 07089 /* A full frame */ 07090 if (res < sizeof(*fh)) { 07091 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07092 ast_mutex_unlock(&iaxsl[fr->callno]); 07093 return 1; 07094 } 07095 /* Ensure text frames are NULL-terminated */ 07096 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07097 if (res < thread->buf_size) 07098 thread->buf[res++] = '\0'; 07099 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07100 thread->buf[res - 1] = '\0'; 07101 } 07102 f.datalen = res - sizeof(*fh); 07103 07104 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07105 from the real peer, not the transfer peer */ 07106 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07107 ((f.subclass != IAX_COMMAND_INVAL) || 07108 (f.frametype != AST_FRAME_IAX))) { 07109 unsigned char x; 07110 int call_to_destroy; 07111 /* XXX This code is not very efficient. Surely there is a better way which still 07112 properly handles boundary conditions? XXX */ 07113 /* First we have to qualify that the ACKed value is within our window */ 07114 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07115 if (fr->iseqno == x) 07116 break; 07117 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07118 /* The acknowledgement is within our window. Time to acknowledge everything 07119 that it says to */ 07120 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07121 /* Ack the packet with the given timestamp */ 07122 if (option_debug && iaxdebug) 07123 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07124 call_to_destroy = 0; 07125 AST_LIST_LOCK(&iaxq.queue); 07126 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07127 /* If it's our call, and our timestamp, mark -1 retries */ 07128 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07129 cur->retries = -1; 07130 /* Destroy call if this is the end */ 07131 if (cur->final) 07132 call_to_destroy = fr->callno; 07133 } 07134 } 07135 AST_LIST_UNLOCK(&iaxq.queue); 07136 if (call_to_destroy) { 07137 if (iaxdebug && option_debug) 07138 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07139 iax2_destroy(call_to_destroy); 07140 } 07141 } 07142 /* Note how much we've received acknowledgement for */ 07143 if (iaxs[fr->callno]) 07144 iaxs[fr->callno]->rseqno = fr->iseqno; 07145 else { 07146 /* Stop processing now */ 07147 ast_mutex_unlock(&iaxsl[fr->callno]); 07148 return 1; 07149 } 07150 } else if (option_debug) 07151 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07152 } 07153 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07154 ((f.frametype != AST_FRAME_IAX) || 07155 ((f.subclass != IAX_COMMAND_TXACC) && 07156 (f.subclass != IAX_COMMAND_TXCNT)))) { 07157 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07158 ast_mutex_unlock(&iaxsl[fr->callno]); 07159 return 1; 07160 } 07161 07162 if (f.datalen) { 07163 if (f.frametype == AST_FRAME_IAX) { 07164 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07165 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07166 ast_mutex_unlock(&iaxsl[fr->callno]); 07167 return 1; 07168 } 07169 f.data = NULL; 07170 f.datalen = 0; 07171 } else 07172 f.data = thread->buf + sizeof(*fh); 07173 } else { 07174 if (f.frametype == AST_FRAME_IAX) 07175 f.data = NULL; 07176 else 07177 f.data = empty; 07178 memset(&ies, 0, sizeof(ies)); 07179 } 07180 07181 /* when we receive the first full frame for a new incoming channel, 07182 it is safe to start the PBX on the channel because we have now 07183 completed a 3-way handshake with the peer */ 07184 if ((f.frametype == AST_FRAME_VOICE) || 07185 (f.frametype == AST_FRAME_VIDEO) || 07186 (f.frametype == AST_FRAME_IAX)) { 07187 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07188 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07189 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07190 ast_mutex_unlock(&iaxsl[fr->callno]); 07191 return 1; 07192 } 07193 } 07194 } 07195 07196 if (f.frametype == AST_FRAME_VOICE) { 07197 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07198 iaxs[fr->callno]->voiceformat = f.subclass; 07199 if (option_debug) 07200 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07201 if (iaxs[fr->callno]->owner) { 07202 int orignative; 07203 retryowner: 07204 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07205 ast_mutex_unlock(&iaxsl[fr->callno]); 07206 usleep(1); 07207 ast_mutex_lock(&iaxsl[fr->callno]); 07208 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07209 } 07210 if (iaxs[fr->callno]) { 07211 if (iaxs[fr->callno]->owner) { 07212 orignative = iaxs[fr->callno]->owner->nativeformats; 07213 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07214 if (iaxs[fr->callno]->owner->readformat) 07215 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07216 iaxs[fr->callno]->owner->nativeformats = orignative; 07217 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07218 } 07219 } else { 07220 if (option_debug) 07221 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07222 ast_mutex_unlock(&iaxsl[fr->callno]); 07223 return 1; 07224 } 07225 } 07226 } 07227 } 07228 if (f.frametype == AST_FRAME_VIDEO) { 07229 if (f.subclass != iaxs[fr->callno]->videoformat) { 07230 if (option_debug) 07231 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07232 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07233 } 07234 } 07235 if (f.frametype == AST_FRAME_IAX) { 07236 if (iaxs[fr->callno]->initid > -1) { 07237 /* Don't auto congest anymore since we've gotten something usefulb ack */ 07238 ast_sched_del(sched, iaxs[fr->callno]->initid); 07239 iaxs[fr->callno]->initid = -1; 07240 } 07241 /* Handle the IAX pseudo frame itself */ 07242 if (option_debug && iaxdebug) 07243 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07244 07245 /* Update last ts unless the frame's timestamp originated with us. */ 07246 if (iaxs[fr->callno]->last < fr->ts && 07247 f.subclass != IAX_COMMAND_ACK && 07248 f.subclass != IAX_COMMAND_PONG && 07249 f.subclass != IAX_COMMAND_LAGRP) { 07250 iaxs[fr->callno]->last = fr->ts; 07251 if (option_debug && iaxdebug) 07252 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07253 } 07254 07255 switch(f.subclass) { 07256 case IAX_COMMAND_ACK: 07257 /* Do nothing */ 07258 break; 07259 case IAX_COMMAND_QUELCH: 07260 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07261 /* Generate Manager Hold event, if necessary*/ 07262 if (iaxs[fr->callno]->owner) { 07263 manager_event(EVENT_FLAG_CALL, "Hold", 07264 "Channel: %s\r\n" 07265 "Uniqueid: %s\r\n", 07266 iaxs[fr->callno]->owner->name, 07267 iaxs[fr->callno]->owner->uniqueid); 07268 } 07269 07270 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07271 if (ies.musiconhold) { 07272 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07273 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07274 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07275 S_OR(mohsuggest, NULL), 07276 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07277 if (!iaxs[fr->callno]) { 07278 ast_mutex_unlock(&iaxsl[fr->callno]); 07279 return 1; 07280 } 07281 } 07282 } 07283 } 07284 break; 07285 case IAX_COMMAND_UNQUELCH: 07286 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07287 /* Generate Manager Unhold event, if necessary*/ 07288 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07289 manager_event(EVENT_FLAG_CALL, "Unhold", 07290 "Channel: %s\r\n" 07291 "Uniqueid: %s\r\n", 07292 iaxs[fr->callno]->owner->name, 07293 iaxs[fr->callno]->owner->uniqueid); 07294 } 07295 07296 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07297 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07298 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07299 if (!iaxs[fr->callno]) { 07300 ast_mutex_unlock(&iaxsl[fr->callno]); 07301 return 1; 07302 } 07303 } 07304 } 07305 break; 07306 case IAX_COMMAND_TXACC: 07307 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07308 /* Ack the packet with the given timestamp */ 07309 AST_LIST_LOCK(&iaxq.queue); 07310 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07311 /* Cancel any outstanding txcnt's */ 07312 if ((fr->callno == cur->callno) && (cur->transfer)) 07313 cur->retries = -1; 07314 } 07315 AST_LIST_UNLOCK(&iaxq.queue); 07316 memset(&ied1, 0, sizeof(ied1)); 07317 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07318 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07319 iaxs[fr->callno]->transferring = TRANSFER_READY; 07320 } 07321 break; 07322 case IAX_COMMAND_NEW: 07323 /* Ignore if it's already up */ 07324 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07325 break; 07326 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07327 ast_mutex_unlock(&iaxsl[fr->callno]); 07328 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07329 ast_mutex_lock(&iaxsl[fr->callno]); 07330 if (!iaxs[fr->callno]) { 07331 ast_mutex_unlock(&iaxsl[fr->callno]); 07332 return 1; 07333 } 07334 } 07335 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07336 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07337 int new_callno; 07338 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07339 fr->callno = new_callno; 07340 } 07341 /* For security, always ack immediately */ 07342 if (delayreject) 07343 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07344 if (check_access(fr->callno, &sin, &ies)) { 07345 /* They're not allowed on */ 07346 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07347 if (authdebug) 07348 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07349 break; 07350 } 07351 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07352 const char *context, *exten, *cid_num; 07353 07354 context = ast_strdupa(iaxs[fr->callno]->context); 07355 exten = ast_strdupa(iaxs[fr->callno]->exten); 07356 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07357 07358 /* This might re-enter the IAX code and need the lock */ 07359 ast_mutex_unlock(&iaxsl[fr->callno]); 07360 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07361 ast_mutex_lock(&iaxsl[fr->callno]); 07362 07363 if (!iaxs[fr->callno]) { 07364 ast_mutex_unlock(&iaxsl[fr->callno]); 07365 return 1; 07366 } 07367 } else 07368 exists = 0; 07369 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07370 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07371 memset(&ied0, 0, sizeof(ied0)); 07372 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07373 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07374 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07375 if (!iaxs[fr->callno]) { 07376 ast_mutex_unlock(&iaxsl[fr->callno]); 07377 return 1; 07378 } 07379 if (authdebug) 07380 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07381 } else { 07382 /* Select an appropriate format */ 07383 07384 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07385 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07386 using_prefs = "reqonly"; 07387 } else { 07388 using_prefs = "disabled"; 07389 } 07390 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07391 memset(&pref, 0, sizeof(pref)); 07392 strcpy(caller_pref_buf, "disabled"); 07393 strcpy(host_pref_buf, "disabled"); 07394 } else { 07395 using_prefs = "mine"; 07396 /* If the information elements are in here... use them */ 07397 if (ies.codec_prefs) 07398 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07399 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07400 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07401 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07402 pref = iaxs[fr->callno]->rprefs; 07403 using_prefs = "caller"; 07404 } else { 07405 pref = iaxs[fr->callno]->prefs; 07406 } 07407 } else 07408 pref = iaxs[fr->callno]->prefs; 07409 07410 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07411 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07412 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07413 } 07414 if (!format) { 07415 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07416 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07417 if (!format) { 07418 memset(&ied0, 0, sizeof(ied0)); 07419 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07420 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07421 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07422 if (!iaxs[fr->callno]) { 07423 ast_mutex_unlock(&iaxsl[fr->callno]); 07424 return 1; 07425 } 07426 if (authdebug) { 07427 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07428 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07429 else 07430 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07431 } 07432 } else { 07433 /* Pick one... */ 07434 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07435 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07436 format = 0; 07437 } else { 07438 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07439 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07440 memset(&pref, 0, sizeof(pref)); 07441 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07442 strcpy(caller_pref_buf,"disabled"); 07443 strcpy(host_pref_buf,"disabled"); 07444 } else { 07445 using_prefs = "mine"; 07446 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07447 /* Do the opposite of what we tried above. */ 07448 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07449 pref = iaxs[fr->callno]->prefs; 07450 } else { 07451 pref = iaxs[fr->callno]->rprefs; 07452 using_prefs = "caller"; 07453 } 07454 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07455 07456 } else /* if no codec_prefs IE do it the old way */ 07457 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07458 } 07459 } 07460 07461 if (!format) { 07462 memset(&ied0, 0, sizeof(ied0)); 07463 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07464 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07465 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07466 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07467 if (!iaxs[fr->callno]) { 07468 ast_mutex_unlock(&iaxsl[fr->callno]); 07469 return 1; 07470 } 07471 if (authdebug) 07472 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07473 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07474 break; 07475 } 07476 } 07477 } 07478 if (format) { 07479 /* No authentication required, let them in */ 07480 memset(&ied1, 0, sizeof(ied1)); 07481 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07482 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07483 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07484 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07485 if (option_verbose > 2) 07486 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07487 "%srequested format = %s,\n" 07488 "%srequested prefs = %s,\n" 07489 "%sactual format = %s,\n" 07490 "%shost prefs = %s,\n" 07491 "%spriority = %s\n", 07492 ast_inet_ntoa(sin.sin_addr), 07493 VERBOSE_PREFIX_4, 07494 ast_getformatname(iaxs[fr->callno]->peerformat), 07495 VERBOSE_PREFIX_4, 07496 caller_pref_buf, 07497 VERBOSE_PREFIX_4, 07498 ast_getformatname(format), 07499 VERBOSE_PREFIX_4, 07500 host_pref_buf, 07501 VERBOSE_PREFIX_4, 07502 using_prefs); 07503 07504 iaxs[fr->callno]->chosenformat = format; 07505 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07506 } else { 07507 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07508 /* If this is a TBD call, we're ready but now what... */ 07509 if (option_verbose > 2) 07510 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07511 } 07512 } 07513 } 07514 break; 07515 } 07516 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07517 merge_encryption(iaxs[fr->callno],ies.encmethods); 07518 else 07519 iaxs[fr->callno]->encmethods = 0; 07520 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07521 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07522 if (!iaxs[fr->callno]) { 07523 ast_mutex_unlock(&iaxsl[fr->callno]); 07524 return 1; 07525 } 07526 break; 07527 case IAX_COMMAND_DPREQ: 07528 /* Request status in the dialplan */ 07529 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07530 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07531 if (iaxcompat) { 07532 /* Spawn a thread for the lookup */ 07533 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07534 } else { 07535 /* Just look it up */ 07536 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07537 } 07538 } 07539 break; 07540 case IAX_COMMAND_HANGUP: 07541 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07542 if (option_debug) 07543 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07544 /* Set hangup cause according to remote */ 07545 if (ies.causecode && iaxs[fr->callno]->owner) 07546 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07547 /* Send ack immediately, before we destroy */ 07548 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07549 iax2_destroy(fr->callno); 07550 break; 07551 case IAX_COMMAND_REJECT: 07552 /* Set hangup cause according to remote */ 07553 if (ies.causecode && iaxs[fr->callno]->owner) 07554 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07555 07556 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07557 if (iaxs[fr->callno]->owner && authdebug) 07558 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07559 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07560 ies.cause ? ies.cause : "<Unknown>"); 07561 if (option_debug) 07562 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07563 fr->callno); 07564 } 07565 /* Send ack immediately, before we destroy */ 07566 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07567 fr->ts, NULL, 0, fr->iseqno); 07568 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07569 iaxs[fr->callno]->error = EPERM; 07570 iax2_destroy(fr->callno); 07571 break; 07572 case IAX_COMMAND_TRANSFER: 07573 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07574 /* Set BLINDTRANSFER channel variables */ 07575 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07576 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07577 if (!strcmp(ies.called_number, ast_parking_ext())) { 07578 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07579 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07580 } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) 07581 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07582 } else { 07583 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07584 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07585 ies.called_number, iaxs[fr->callno]->context); 07586 else 07587 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07588 ies.called_number, iaxs[fr->callno]->context); 07589 } 07590 } else 07591 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07592 break; 07593 case IAX_COMMAND_ACCEPT: 07594 /* Ignore if call is already up or needs authentication or is a TBD */ 07595 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07596 break; 07597 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07598 /* Send ack immediately, before we destroy */ 07599 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07600 iax2_destroy(fr->callno); 07601 break; 07602 } 07603 if (ies.format) { 07604 iaxs[fr->callno]->peerformat = ies.format; 07605 } else { 07606 if (iaxs[fr->callno]->owner) 07607 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07608 else 07609 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07610 } 07611 if (option_verbose > 2) 07612 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); 07613 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07614 memset(&ied0, 0, sizeof(ied0)); 07615 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07616 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07617 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07618 if (!iaxs[fr->callno]) { 07619 ast_mutex_unlock(&iaxsl[fr->callno]); 07620 return 1; 07621 } 07622 if (authdebug) 07623 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07624 } else { 07625 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07626 if (iaxs[fr->callno]->owner) { 07627 /* Switch us to use a compatible format */ 07628 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07629 if (option_verbose > 2) 07630 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07631 retryowner2: 07632 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07633 ast_mutex_unlock(&iaxsl[fr->callno]); 07634 usleep(1); 07635 ast_mutex_lock(&iaxsl[fr->callno]); 07636 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07637 } 07638 07639 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07640 /* Setup read/write formats properly. */ 07641 if (iaxs[fr->callno]->owner->writeformat) 07642 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07643 if (iaxs[fr->callno]->owner->readformat) 07644 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07645 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07646 } 07647 } 07648 } 07649 if (iaxs[fr->callno]) { 07650 ast_mutex_lock(&dpcache_lock); 07651 dp = iaxs[fr->callno]->dpentries; 07652 while(dp) { 07653 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07654 iax2_dprequest(dp, fr->callno); 07655 } 07656 dp = dp->peer; 07657 } 07658 ast_mutex_unlock(&dpcache_lock); 07659 } 07660 break; 07661 case IAX_COMMAND_POKE: 07662 /* Send back a pong packet with the original timestamp */ 07663 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07664 if (!iaxs[fr->callno]) { 07665 ast_mutex_unlock(&iaxsl[fr->callno]); 07666 return 1; 07667 } 07668 break; 07669 case IAX_COMMAND_PING: 07670 { 07671 struct iax_ie_data pingied; 07672 construct_rr(iaxs[fr->callno], &pingied); 07673 /* Send back a pong packet with the original timestamp */ 07674 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07675 } 07676 break; 07677 case IAX_COMMAND_PONG: 07678 /* Calculate ping time */ 07679 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07680 /* save RR info */ 07681 save_rr(fr, &ies); 07682 07683 if (iaxs[fr->callno]->peerpoke) { 07684 peer = iaxs[fr->callno]->peerpoke; 07685 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07686 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07687 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07688 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07689 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07690 } 07691 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07692 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07693 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07694 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07695 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07696 } 07697 } 07698 peer->lastms = iaxs[fr->callno]->pingtime; 07699 if (peer->smoothing && (peer->lastms > -1)) 07700 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07701 else if (peer->smoothing && peer->lastms < 0) 07702 peer->historicms = (0 + peer->historicms) / 2; 07703 else 07704 peer->historicms = iaxs[fr->callno]->pingtime; 07705 07706 /* Remove scheduled iax2_poke_noanswer */ 07707 if (peer->pokeexpire > -1) { 07708 if (!ast_sched_del(sched, peer->pokeexpire)) { 07709 peer_unref(peer); 07710 peer->pokeexpire = -1; 07711 } 07712 } 07713 /* Schedule the next cycle */ 07714 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07715 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07716 else 07717 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07718 if (peer->pokeexpire == -1) 07719 peer_unref(peer); 07720 /* and finally send the ack */ 07721 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07722 /* And wrap up the qualify call */ 07723 iax2_destroy(fr->callno); 07724 peer->callno = 0; 07725 if (option_debug) 07726 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07727 } 07728 break; 07729 case IAX_COMMAND_LAGRQ: 07730 case IAX_COMMAND_LAGRP: 07731 f.src = "LAGRQ"; 07732 f.mallocd = 0; 07733 f.offset = 0; 07734 f.samples = 0; 07735 iax_frame_wrap(fr, &f); 07736 if(f.subclass == IAX_COMMAND_LAGRQ) { 07737 /* Received a LAGRQ - echo back a LAGRP */ 07738 fr->af.subclass = IAX_COMMAND_LAGRP; 07739 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07740 } else { 07741 /* Received LAGRP in response to our LAGRQ */ 07742 unsigned int ts; 07743 /* This is a reply we've been given, actually measure the difference */ 07744 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07745 iaxs[fr->callno]->lag = ts - fr->ts; 07746 if (option_debug && iaxdebug) 07747 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07748 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07749 } 07750 break; 07751 case IAX_COMMAND_AUTHREQ: 07752 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07753 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>"); 07754 break; 07755 } 07756 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07757 ast_log(LOG_WARNING, 07758 "I don't know how to authenticate %s to %s\n", 07759 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07760 } 07761 if (!iaxs[fr->callno]) { 07762 ast_mutex_unlock(&iaxsl[fr->callno]); 07763 return 1; 07764 } 07765 break; 07766 case IAX_COMMAND_AUTHREP: 07767 /* For security, always ack immediately */ 07768 if (delayreject) 07769 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07770 /* Ignore once we've started */ 07771 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07772 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>"); 07773 break; 07774 } 07775 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07776 if (authdebug) 07777 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); 07778 memset(&ied0, 0, sizeof(ied0)); 07779 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07780 break; 07781 } 07782 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07783 /* This might re-enter the IAX code and need the lock */ 07784 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07785 } else 07786 exists = 0; 07787 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07788 if (authdebug) 07789 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07790 memset(&ied0, 0, sizeof(ied0)); 07791 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07792 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07793 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07794 if (!iaxs[fr->callno]) { 07795 ast_mutex_unlock(&iaxsl[fr->callno]); 07796 return 1; 07797 } 07798 } else { 07799 /* Select an appropriate format */ 07800 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07801 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07802 using_prefs = "reqonly"; 07803 } else { 07804 using_prefs = "disabled"; 07805 } 07806 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07807 memset(&pref, 0, sizeof(pref)); 07808 strcpy(caller_pref_buf, "disabled"); 07809 strcpy(host_pref_buf, "disabled"); 07810 } else { 07811 using_prefs = "mine"; 07812 if (ies.codec_prefs) 07813 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07814 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07815 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07816 pref = iaxs[fr->callno]->rprefs; 07817 using_prefs = "caller"; 07818 } else { 07819 pref = iaxs[fr->callno]->prefs; 07820 } 07821 } else /* if no codec_prefs IE do it the old way */ 07822 pref = iaxs[fr->callno]->prefs; 07823 07824 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07825 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07826 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07827 } 07828 if (!format) { 07829 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07830 if (option_debug) 07831 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); 07832 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07833 } 07834 if (!format) { 07835 if (authdebug) { 07836 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07837 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07838 else 07839 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07840 } 07841 memset(&ied0, 0, sizeof(ied0)); 07842 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07843 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07844 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07845 if (!iaxs[fr->callno]) { 07846 ast_mutex_unlock(&iaxsl[fr->callno]); 07847 return 1; 07848 } 07849 } else { 07850 /* Pick one... */ 07851 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07852 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07853 format = 0; 07854 } else { 07855 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07856 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07857 memset(&pref, 0, sizeof(pref)); 07858 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07859 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07860 strcpy(caller_pref_buf,"disabled"); 07861 strcpy(host_pref_buf,"disabled"); 07862 } else { 07863 using_prefs = "mine"; 07864 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07865 /* Do the opposite of what we tried above. */ 07866 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07867 pref = iaxs[fr->callno]->prefs; 07868 } else { 07869 pref = iaxs[fr->callno]->rprefs; 07870 using_prefs = "caller"; 07871 } 07872 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07873 } else /* if no codec_prefs IE do it the old way */ 07874 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07875 } 07876 } 07877 if (!format) { 07878 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07879 if (authdebug) { 07880 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07881 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07882 else 07883 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07884 } 07885 memset(&ied0, 0, sizeof(ied0)); 07886 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07887 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07888 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07889 if (!iaxs[fr->callno]) { 07890 ast_mutex_unlock(&iaxsl[fr->callno]); 07891 return 1; 07892 } 07893 } 07894 } 07895 } 07896 if (format) { 07897 /* Authentication received */ 07898 memset(&ied1, 0, sizeof(ied1)); 07899 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07900 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07901 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07902 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07903 if (option_verbose > 2) 07904 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07905 "%srequested format = %s,\n" 07906 "%srequested prefs = %s,\n" 07907 "%sactual format = %s,\n" 07908 "%shost prefs = %s,\n" 07909 "%spriority = %s\n", 07910 ast_inet_ntoa(sin.sin_addr), 07911 VERBOSE_PREFIX_4, 07912 ast_getformatname(iaxs[fr->callno]->peerformat), 07913 VERBOSE_PREFIX_4, 07914 caller_pref_buf, 07915 VERBOSE_PREFIX_4, 07916 ast_getformatname(format), 07917 VERBOSE_PREFIX_4, 07918 host_pref_buf, 07919 VERBOSE_PREFIX_4, 07920 using_prefs); 07921 07922 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07923 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07924 iax2_destroy(fr->callno); 07925 } else { 07926 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07927 /* If this is a TBD call, we're ready but now what... */ 07928 if (option_verbose > 2) 07929 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07930 } 07931 } 07932 } 07933 break; 07934 case IAX_COMMAND_DIAL: 07935 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07936 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07937 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07938 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07939 if (authdebug) 07940 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07941 memset(&ied0, 0, sizeof(ied0)); 07942 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07943 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07944 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07945 if (!iaxs[fr->callno]) { 07946 ast_mutex_unlock(&iaxsl[fr->callno]); 07947 return 1; 07948 } 07949 } else { 07950 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07951 if (option_verbose > 2) 07952 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 07953 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07954 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07955 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07956 iax2_destroy(fr->callno); 07957 } 07958 } 07959 break; 07960 case IAX_COMMAND_INVAL: 07961 iaxs[fr->callno]->error = ENOTCONN; 07962 if (option_debug) 07963 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07964 iax2_destroy(fr->callno); 07965 if (option_debug) 07966 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07967 break; 07968 case IAX_COMMAND_VNAK: 07969 if (option_debug) 07970 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07971 /* Force retransmission */ 07972 vnak_retransmit(fr->callno, fr->iseqno); 07973 break; 07974 case IAX_COMMAND_REGREQ: 07975 case IAX_COMMAND_REGREL: 07976 /* For security, always ack immediately */ 07977 if (delayreject) 07978 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07979 if (register_verify(fr->callno, &sin, &ies)) { 07980 if (!iaxs[fr->callno]) { 07981 ast_mutex_unlock(&iaxsl[fr->callno]); 07982 return 1; 07983 } 07984 /* Send delayed failure */ 07985 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07986 break; 07987 } 07988 if (!iaxs[fr->callno]) { 07989 ast_mutex_unlock(&iaxsl[fr->callno]); 07990 return 1; 07991 } 07992 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 07993 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 07994 if (f.subclass == IAX_COMMAND_REGREL) 07995 memset(&sin, 0, sizeof(sin)); 07996 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07997 ast_log(LOG_WARNING, "Registry error\n"); 07998 if (!iaxs[fr->callno]) { 07999 ast_mutex_unlock(&iaxsl[fr->callno]); 08000 return 1; 08001 } 08002 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08003 ast_mutex_unlock(&iaxsl[fr->callno]); 08004 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08005 ast_mutex_lock(&iaxsl[fr->callno]); 08006 if (!iaxs[fr->callno]) { 08007 ast_mutex_unlock(&iaxsl[fr->callno]); 08008 return 1; 08009 } 08010 } 08011 break; 08012 } 08013 registry_authrequest(fr->callno); 08014 if (!iaxs[fr->callno]) { 08015 ast_mutex_unlock(&iaxsl[fr->callno]); 08016 return 1; 08017 } 08018 break; 08019 case IAX_COMMAND_REGACK: 08020 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08021 ast_log(LOG_WARNING, "Registration failure\n"); 08022 /* Send ack immediately, before we destroy */ 08023 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08024 iax2_destroy(fr->callno); 08025 break; 08026 case IAX_COMMAND_REGREJ: 08027 if (iaxs[fr->callno]->reg) { 08028 if (authdebug) { 08029 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(sin.sin_addr)); 08030 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 08031 } 08032 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08033 } 08034 /* Send ack immediately, before we destroy */ 08035 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08036 iax2_destroy(fr->callno); 08037 break; 08038 case IAX_COMMAND_REGAUTH: 08039 /* Authentication request */ 08040 if (registry_rerequest(&ies, fr->callno, &sin)) { 08041 memset(&ied0, 0, sizeof(ied0)); 08042 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08043 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08044 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08045 if (!iaxs[fr->callno]) { 08046 ast_mutex_unlock(&iaxsl[fr->callno]); 08047 return 1; 08048 } 08049 } 08050 break; 08051 case IAX_COMMAND_TXREJ: 08052 iaxs[fr->callno]->transferring = 0; 08053 if (option_verbose > 2) 08054 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08055 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08056 if (iaxs[fr->callno]->bridgecallno) { 08057 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08058 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08059 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08060 } 08061 } 08062 break; 08063 case IAX_COMMAND_TXREADY: 08064 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08065 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08066 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08067 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08068 else 08069 iaxs[fr->callno]->transferring = TRANSFER_READY; 08070 if (option_verbose > 2) 08071 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08072 if (iaxs[fr->callno]->bridgecallno) { 08073 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08074 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08075 /* They're both ready, now release them. */ 08076 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08077 if (option_verbose > 2) 08078 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08079 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08080 08081 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08082 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08083 08084 memset(&ied0, 0, sizeof(ied0)); 08085 memset(&ied1, 0, sizeof(ied1)); 08086 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08087 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08088 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08089 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08090 } else { 08091 if (option_verbose > 2) 08092 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08093 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08094 08095 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08096 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08097 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08098 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08099 08100 /* Stop doing lag & ping requests */ 08101 stop_stuff(fr->callno); 08102 stop_stuff(iaxs[fr->callno]->bridgecallno); 08103 08104 memset(&ied0, 0, sizeof(ied0)); 08105 memset(&ied1, 0, sizeof(ied1)); 08106 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08107 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08108 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08109 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08110 } 08111 08112 } 08113 } 08114 } 08115 break; 08116 case IAX_COMMAND_TXREQ: 08117 try_transfer(iaxs[fr->callno], &ies); 08118 break; 08119 case IAX_COMMAND_TXCNT: 08120 if (iaxs[fr->callno]->transferring) 08121 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08122 break; 08123 case IAX_COMMAND_TXREL: 08124 /* Send ack immediately, rather than waiting until we've changed addresses */ 08125 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08126 complete_transfer(fr->callno, &ies); 08127 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08128 break; 08129 case IAX_COMMAND_TXMEDIA: 08130 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08131 AST_LIST_LOCK(&iaxq.queue); 08132 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08133 /* Cancel any outstanding frames and start anew */ 08134 if ((fr->callno == cur->callno) && (cur->transfer)) { 08135 cur->retries = -1; 08136 } 08137 } 08138 AST_LIST_UNLOCK(&iaxq.queue); 08139 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08140 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08141 } 08142 break; 08143 case IAX_COMMAND_DPREP: 08144 complete_dpreply(iaxs[fr->callno], &ies); 08145 break; 08146 case IAX_COMMAND_UNSUPPORT: 08147 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08148 break; 08149 case IAX_COMMAND_FWDOWNL: 08150 /* Firmware download */ 08151 memset(&ied0, 0, sizeof(ied0)); 08152 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08153 if (res < 0) 08154 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08155 else if (res > 0) 08156 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08157 else 08158 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08159 if (!iaxs[fr->callno]) { 08160 ast_mutex_unlock(&iaxsl[fr->callno]); 08161 return 1; 08162 } 08163 break; 08164 default: 08165 if (option_debug) 08166 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08167 memset(&ied0, 0, sizeof(ied0)); 08168 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08169 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08170 } 08171 /* Don't actually pass these frames along */ 08172 if ((f.subclass != IAX_COMMAND_ACK) && 08173 (f.subclass != IAX_COMMAND_TXCNT) && 08174 (f.subclass != IAX_COMMAND_TXACC) && 08175 (f.subclass != IAX_COMMAND_INVAL) && 08176 (f.subclass != IAX_COMMAND_VNAK)) { 08177 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08178 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08179 } 08180 ast_mutex_unlock(&iaxsl[fr->callno]); 08181 return 1; 08182 } 08183 /* Unless this is an ACK or INVAL frame, ack it */ 08184 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08185 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08186 } else if (minivid) { 08187 f.frametype = AST_FRAME_VIDEO; 08188 if (iaxs[fr->callno]->videoformat > 0) 08189 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08190 else { 08191 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08192 iax2_vnak(fr->callno); 08193 ast_mutex_unlock(&iaxsl[fr->callno]); 08194 return 1; 08195 } 08196 f.datalen = res - sizeof(*vh); 08197 if (f.datalen) 08198 f.data = thread->buf + sizeof(*vh); 08199 else 08200 f.data = NULL; 08201 #ifdef IAXTESTS 08202 if (test_resync) { 08203 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08204 } else 08205 #endif /* IAXTESTS */ 08206 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08207 } else { 08208 /* A mini frame */ 08209 f.frametype = AST_FRAME_VOICE; 08210 if (iaxs[fr->callno]->voiceformat > 0) 08211 f.subclass = iaxs[fr->callno]->voiceformat; 08212 else { 08213 if (option_debug) 08214 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08215 iax2_vnak(fr->callno); 08216 ast_mutex_unlock(&iaxsl[fr->callno]); 08217 return 1; 08218 } 08219 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08220 if (f.datalen < 0) { 08221 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08222 ast_mutex_unlock(&iaxsl[fr->callno]); 08223 return 1; 08224 } 08225 if (f.datalen) 08226 f.data = thread->buf + sizeof(*mh); 08227 else 08228 f.data = NULL; 08229 #ifdef IAXTESTS 08230 if (test_resync) { 08231 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08232 } else 08233 #endif /* IAXTESTS */ 08234 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08235 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08236 } 08237 /* Don't pass any packets until we're started */ 08238 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08239 ast_mutex_unlock(&iaxsl[fr->callno]); 08240 return 1; 08241 } 08242 /* Common things */ 08243 f.src = "IAX2"; 08244 f.mallocd = 0; 08245 f.offset = 0; 08246 f.len = 0; 08247 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08248 f.samples = ast_codec_get_samples(&f); 08249 /* We need to byteswap incoming slinear samples from network byte order */ 08250 if (f.subclass == AST_FORMAT_SLINEAR) 08251 ast_frame_byteswap_be(&f); 08252 } else 08253 f.samples = 0; 08254 iax_frame_wrap(fr, &f); 08255 08256 /* If this is our most recent packet, use it as our basis for timestamping */ 08257 if (iaxs[fr->callno]->last < fr->ts) { 08258 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08259 fr->outoforder = 0; 08260 } else { 08261 if (option_debug && iaxdebug) 08262 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); 08263 fr->outoforder = -1; 08264 } 08265 duped_fr = iaxfrdup2(fr); 08266 if (duped_fr) { 08267 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08268 } 08269 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08270 iaxs[fr->callno]->last = fr->ts; 08271 #if 1 08272 if (option_debug && iaxdebug) 08273 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08274 #endif 08275 } 08276 08277 /* Always run again */ 08278 ast_mutex_unlock(&iaxsl[fr->callno]); 08279 return 1; 08280 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6692 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_registry::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len, LOG_NOTICE, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06693 { 06694 struct iax2_thread *thread; 06695 socklen_t len; 06696 time_t t; 06697 static time_t last_errtime = 0; 06698 struct ast_iax2_full_hdr *fh; 06699 06700 if (!(thread = find_idle_thread())) { 06701 time(&t); 06702 if (t != last_errtime) 06703 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n"); 06704 last_errtime = t; 06705 usleep(1); 06706 return 1; 06707 } 06708 06709 len = sizeof(thread->iosin); 06710 thread->iofd = fd; 06711 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06712 thread->buf_size = sizeof(thread->readbuf); 06713 thread->buf = thread->readbuf; 06714 if (thread->buf_len < 0) { 06715 if (errno != ECONNREFUSED && errno != EAGAIN) 06716 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06717 handle_error(); 06718 thread->iostate = IAX_IOSTATE_IDLE; 06719 signal_condition(&thread->lock, &thread->cond); 06720 return 1; 06721 } 06722 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06723 thread->iostate = IAX_IOSTATE_IDLE; 06724 signal_condition(&thread->lock, &thread->cond); 06725 return 1; 06726 } 06727 06728 /* Determine if this frame is a full frame; if so, and any thread is currently 06729 processing a full frame for the same callno from this peer, then drop this 06730 frame (and the peer will retransmit it) */ 06731 fh = (struct ast_iax2_full_hdr *) thread->buf; 06732 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06733 struct iax2_thread *cur = NULL; 06734 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06735 06736 AST_LIST_LOCK(&active_list); 06737 AST_LIST_TRAVERSE(&active_list, cur, list) { 06738 if ((cur->ffinfo.callno == callno) && 06739 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06740 break; 06741 } 06742 if (cur) { 06743 /* we found another thread processing a full frame for this call, 06744 so queue it up for processing later. */ 06745 defer_full_frame(thread, cur); 06746 AST_LIST_UNLOCK(&active_list); 06747 thread->iostate = IAX_IOSTATE_IDLE; 06748 signal_condition(&thread->lock, &thread->cond); 06749 return 1; 06750 } else { 06751 /* this thread is going to process this frame, so mark it */ 06752 thread->ffinfo.callno = callno; 06753 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06754 thread->ffinfo.type = fh->type; 06755 thread->ffinfo.csub = fh->csub; 06756 } 06757 AST_LIST_UNLOCK(&active_list); 06758 } 06759 06760 /* Mark as ready and send on its way */ 06761 thread->iostate = IAX_IOSTATE_READY; 06762 #ifdef DEBUG_SCHED_MULTITHREAD 06763 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06764 #endif 06765 signal_condition(&thread->lock, &thread->cond); 06766 06767 return 1; 06768 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6479 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06480 { 06481 pthread_t newthread; 06482 struct dpreq_data *dpr; 06483 pthread_attr_t attr; 06484 06485 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06486 return; 06487 06488 pthread_attr_init(&attr); 06489 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06490 06491 dpr->callno = callno; 06492 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06493 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06494 if (callerid) 06495 dpr->callerid = ast_strdup(callerid); 06496 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06497 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06498 } 06499 06500 pthread_attr_destroy(&attr); 06501 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8879 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create, ast_pthread_create_background, ast_verbose(), free, iax2_process_thread(), IAX_TYPE_POOL, iaxthreadcount, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
08880 { 08881 pthread_attr_t attr; 08882 int threadcount = 0; 08883 int x; 08884 for (x = 0; x < iaxthreadcount; x++) { 08885 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08886 if (thread) { 08887 thread->type = IAX_TYPE_POOL; 08888 thread->threadnum = ++threadcount; 08889 ast_mutex_init(&thread->lock); 08890 ast_cond_init(&thread->cond, NULL); 08891 pthread_attr_init(&attr); 08892 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08893 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08894 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08895 free(thread); 08896 thread = NULL; 08897 } 08898 AST_LIST_LOCK(&idle_list); 08899 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08900 AST_LIST_UNLOCK(&idle_list); 08901 } 08902 } 08903 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08904 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08905 if (option_verbose > 1) 08906 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08907 return 0; 08908 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6164 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06165 { 06166 iax2_destroy_helper(iaxs[callno]); 06167 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6353 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, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06354 { 06355 char buf[1024]; 06356 int res; 06357 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06358 int processed = 0; 06359 int totalcalls = 0; 06360 #ifdef ZT_TIMERACK 06361 int x = 1; 06362 #endif 06363 struct timeval now; 06364 if (iaxtrunkdebug) 06365 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06366 gettimeofday(&now, NULL); 06367 if (events & AST_IO_PRI) { 06368 #ifdef ZT_TIMERACK 06369 /* Great, this is a timing interface, just call the ioctl */ 06370 if (ioctl(fd, ZT_TIMERACK, &x)) 06371 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06372 res = 0; 06373 #endif 06374 } else { 06375 /* Read and ignore from the pseudo channel for timing */ 06376 res = read(fd, buf, sizeof(buf)); 06377 if (res < 1) { 06378 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06379 return 1; 06380 } 06381 } 06382 /* For each peer that supports trunking... */ 06383 ast_mutex_lock(&tpeerlock); 06384 tpeer = tpeers; 06385 while(tpeer) { 06386 processed++; 06387 res = 0; 06388 ast_mutex_lock(&tpeer->lock); 06389 /* We can drop a single tpeer per pass. That makes all this logic 06390 substantially easier */ 06391 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06392 /* Take it out of the list, but don't free it yet, because it 06393 could be in use */ 06394 if (prev) 06395 prev->next = tpeer->next; 06396 else 06397 tpeers = tpeer->next; 06398 drop = tpeer; 06399 } else { 06400 res = send_trunk(tpeer, &now); 06401 if (iaxtrunkdebug) 06402 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(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 06403 } 06404 totalcalls += res; 06405 res = 0; 06406 ast_mutex_unlock(&tpeer->lock); 06407 prev = tpeer; 06408 tpeer = tpeer->next; 06409 } 06410 ast_mutex_unlock(&tpeerlock); 06411 if (drop) { 06412 ast_mutex_lock(&drop->lock); 06413 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06414 because by the time they could get tpeerlock, we've already grabbed it */ 06415 if (option_debug) 06416 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06417 free(drop->trunkdata); 06418 ast_mutex_unlock(&drop->lock); 06419 ast_mutex_destroy(&drop->lock); 06420 free(drop); 06421 06422 } 06423 if (iaxtrunkdebug) 06424 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06425 iaxtrunkdebug =0; 06426 return 1; 06427 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1850 of file chan_iax2.c.
References ast_log(), iax_frame::data, iax_frame::datalen, errno, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01851 { 01852 int res; 01853 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01854 sizeof(*sin)); 01855 if (res < 0) { 01856 if (option_debug) 01857 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01858 handle_error(); 01859 } else 01860 res = 0; 01861 return res; 01862 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1538 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), 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, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, len, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01539 { 01540 struct stat stbuf; 01541 struct iax_firmware *cur; 01542 int ifd; 01543 int fd; 01544 int res; 01545 01546 struct ast_iax2_firmware_header *fwh, fwh2; 01547 struct MD5Context md5; 01548 unsigned char sum[16]; 01549 unsigned char buf[1024]; 01550 int len, chunk; 01551 char *s2; 01552 char *last; 01553 s2 = alloca(strlen(s) + 100); 01554 if (!s2) { 01555 ast_log(LOG_WARNING, "Alloca failed!\n"); 01556 return -1; 01557 } 01558 last = strrchr(s, '/'); 01559 if (last) 01560 last++; 01561 else 01562 last = s; 01563 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01564 res = stat(s, &stbuf); 01565 if (res < 0) { 01566 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01567 return -1; 01568 } 01569 /* Make sure it's not a directory */ 01570 if (S_ISDIR(stbuf.st_mode)) 01571 return -1; 01572 ifd = open(s, O_RDONLY); 01573 if (ifd < 0) { 01574 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01575 return -1; 01576 } 01577 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01578 if (fd < 0) { 01579 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01580 close(ifd); 01581 return -1; 01582 } 01583 /* Unlink our newly created file */ 01584 unlink(s2); 01585 01586 /* Now copy the firmware into it */ 01587 len = stbuf.st_size; 01588 while(len) { 01589 chunk = len; 01590 if (chunk > sizeof(buf)) 01591 chunk = sizeof(buf); 01592 res = read(ifd, buf, chunk); 01593 if (res != chunk) { 01594 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01595 close(ifd); 01596 close(fd); 01597 return -1; 01598 } 01599 res = write(fd, buf, chunk); 01600 if (res != chunk) { 01601 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01602 close(ifd); 01603 close(fd); 01604 return -1; 01605 } 01606 len -= chunk; 01607 } 01608 close(ifd); 01609 /* Return to the beginning */ 01610 lseek(fd, 0, SEEK_SET); 01611 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01612 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01613 close(fd); 01614 return -1; 01615 } 01616 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01617 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01618 close(fd); 01619 return -1; 01620 } 01621 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01622 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01623 close(fd); 01624 return -1; 01625 } 01626 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01627 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01628 close(fd); 01629 return -1; 01630 } 01631 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01632 if (fwh == (void *) -1) { 01633 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01634 close(fd); 01635 return -1; 01636 } 01637 MD5Init(&md5); 01638 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01639 MD5Final(sum, &md5); 01640 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01641 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01642 munmap((void*)fwh, stbuf.st_size); 01643 close(fd); 01644 return -1; 01645 } 01646 cur = waresl.wares; 01647 while(cur) { 01648 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01649 /* Found a candidate */ 01650 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01651 /* The version we have on loaded is older, load this one instead */ 01652 break; 01653 /* This version is no newer than what we have. Don't worry about it. 01654 We'll consider it a proper load anyhow though */ 01655 munmap((void*)fwh, stbuf.st_size); 01656 close(fd); 01657 return 0; 01658 } 01659 cur = cur->next; 01660 } 01661 if (!cur) { 01662 /* Allocate a new one and link it */ 01663 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01664 cur->fd = -1; 01665 cur->next = waresl.wares; 01666 waresl.wares = cur; 01667 } 01668 } 01669 if (cur) { 01670 if (cur->fwh) { 01671 munmap((void*)cur->fwh, cur->mmaplen); 01672 } 01673 if (cur->fd > -1) 01674 close(cur->fd); 01675 cur->fwh = fwh; 01676 cur->fd = fd; 01677 cur->mmaplen = stbuf.st_size; 01678 cur->dead = 0; 01679 } 01680 return 0; 01681 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5571 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05572 { 05573 int newcall = 0; 05574 char newip[256]; 05575 struct iax_ie_data ied; 05576 struct sockaddr_in new; 05577 05578 05579 memset(&ied, 0, sizeof(ied)); 05580 if (ies->apparent_addr) 05581 bcopy(ies->apparent_addr, &new, sizeof(new)); 05582 if (ies->callno) 05583 newcall = ies->callno; 05584 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05585 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05586 return -1; 05587 } 05588 pvt->transfercallno = newcall; 05589 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05590 inet_aton(newip, &pvt->transfer.sin_addr); 05591 pvt->transfer.sin_family = AF_INET; 05592 pvt->transferring = TRANSFER_BEGIN; 05593 pvt->transferid = ies->transferid; 05594 if (ies->transferid) 05595 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05596 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05597 return 0; 05598 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1057 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01058 { 01059 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01060 if (csub & IAX_FLAG_SC_LOG) { 01061 /* special case for 'compressed' -1 */ 01062 if (csub == 0xff) 01063 return -1; 01064 else 01065 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01066 } 01067 else 01068 return csub; 01069 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 5838 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
05839 { 05840 if (peer->expire > -1) { 05841 if (!ast_sched_del(sched, peer->expire)) { 05842 peer->expire = -1; 05843 peer_unref(peer); 05844 } 05845 } 05846 05847 if (peer->pokeexpire > -1) { 05848 if (!ast_sched_del(sched, peer->pokeexpire)) { 05849 peer->pokeexpire = -1; 05850 peer_unref(peer); 05851 } 05852 } 05853 05854 ao2_unlink(peers, peer); 05855 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10794 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
10795 { 10796 ast_custom_function_unregister(&iaxpeer_function); 10797 return __unload_module(); 10798 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3342 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03343 { 03344 ast_mutex_unlock(&iaxsl[callno1]); 03345 ast_mutex_unlock(&iaxsl[callno0]); 03346 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2392 of file chan_iax2.c.
References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02393 { 02394 int x; 02395 02396 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02397 x = fr->ts - iaxs[fr->callno]->last; 02398 if (x < -50000) { 02399 /* Sudden big jump backwards in timestamp: 02400 What likely happened here is that miniframe timestamp has circled but we haven't 02401 gotten the update from the main packet. We'll just pretend that we did, and 02402 update the timestamp appropriately. */ 02403 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02404 if (option_debug && iaxdebug) 02405 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02406 } 02407 if (x > 50000) { 02408 /* Sudden apparent big jump forwards in timestamp: 02409 What's likely happened is this is an old miniframe belonging to the previous 02410 top-16-bit timestamp that has turned up out of order. 02411 Adjust the timestamp appropriately. */ 02412 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02413 if (option_debug && iaxdebug) 02414 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02415 } 02416 } 02417 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2421 of file chan_iax2.c.
References ast_sched_del(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
02422 { 02423 int when; 02424 02425 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02426 02427 when = jb_next(pvt->jb) - when; 02428 02429 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02430 02431 if(when <= 0) { 02432 /* XXX should really just empty until when > 0.. */ 02433 when = 1; 02434 } 02435 02436 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02437 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1277 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno(), and make_trunk().
01278 { 01279 int max = 1; 01280 int x; 01281 /* XXX Prolly don't need locks here XXX */ 01282 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01283 if (iaxs[x]) 01284 max = x + 1; 01285 } 01286 maxnontrunkcall = max; 01287 if (option_debug && iaxdebug) 01288 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01289 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1263 of file chan_iax2.c.
References ast_log(), IAX_MAX_CALLS, iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01264 { 01265 int max = TRUNK_CALL_START; 01266 int x; 01267 /* XXX Prolly don't need locks here XXX */ 01268 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01269 if (iaxs[x]) 01270 max = x + 1; 01271 } 01272 maxtrunkcall = max; 01273 if (option_debug && iaxdebug) 01274 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01275 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2029 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().
02030 { 02031 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02032 struct ast_iax2_full_hdr *fh = f->data; 02033 /* Mark this as a retransmission */ 02034 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02035 /* Update iseqno */ 02036 f->iseqno = iaxs[f->callno]->iseqno; 02037 fh->iseqno = f->iseqno; 02038 return 0; 02039 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5949 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), iax_ie_data::buf, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), 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_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, peer_ref(), peer_unref(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05950 { 05951 /* Called from IAX thread only, with proper iaxsl lock */ 05952 struct iax_ie_data ied; 05953 struct iax2_peer *p; 05954 int msgcount; 05955 char data[80]; 05956 int version; 05957 const char *peer_name; 05958 int res = -1; 05959 05960 memset(&ied, 0, sizeof(ied)); 05961 05962 peer_name = ast_strdupa(iaxs[callno]->peer); 05963 05964 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05965 ast_mutex_unlock(&iaxsl[callno]); 05966 if (!(p = find_peer(peer_name, 1))) { 05967 ast_mutex_lock(&iaxsl[callno]); 05968 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 05969 return -1; 05970 } 05971 ast_mutex_lock(&iaxsl[callno]); 05972 if (!iaxs[callno]) 05973 goto return_unref; 05974 05975 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 05976 if (sin->sin_addr.s_addr) { 05977 time_t nowtime; 05978 time(&nowtime); 05979 realtime_update_peer(peer_name, sin, nowtime); 05980 } else { 05981 realtime_update_peer(peer_name, sin, 0); 05982 } 05983 } 05984 if (inaddrcmp(&p->addr, sin)) { 05985 if (iax2_regfunk) 05986 iax2_regfunk(p->name, 1); 05987 /* Stash the IP address from which they registered */ 05988 memcpy(&p->addr, sin, sizeof(p->addr)); 05989 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05990 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05991 ast_db_put("IAX/Registry", p->name, data); 05992 if (option_verbose > 2) 05993 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05994 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 05995 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05996 register_peer_exten(p, 1); 05997 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05998 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05999 if (option_verbose > 2) 06000 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06001 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06002 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06003 register_peer_exten(p, 0); 06004 ast_db_del("IAX/Registry", p->name); 06005 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06006 } 06007 /* Update the host */ 06008 /* Verify that the host is really there */ 06009 iax2_poke_peer(p, callno); 06010 } 06011 06012 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06013 if (!iaxs[callno]) { 06014 res = 0; 06015 goto return_unref; 06016 } 06017 06018 /* Store socket fd */ 06019 p->sockfd = fd; 06020 /* Setup the expiry */ 06021 if (p->expire > -1) { 06022 if (!ast_sched_del(sched, p->expire)) { 06023 p->expire = -1; 06024 peer_unref(p); 06025 } 06026 } 06027 /* treat an unspecified refresh interval as the minimum */ 06028 if (!refresh) 06029 refresh = min_reg_expire; 06030 if (refresh > max_reg_expire) { 06031 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06032 p->name, max_reg_expire, refresh); 06033 p->expiry = max_reg_expire; 06034 } else if (refresh < min_reg_expire) { 06035 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06036 p->name, min_reg_expire, refresh); 06037 p->expiry = min_reg_expire; 06038 } else { 06039 p->expiry = refresh; 06040 } 06041 if (p->expiry && sin->sin_addr.s_addr) { 06042 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06043 if (p->expire == -1) 06044 peer_unref(p); 06045 } 06046 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06047 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06048 if (sin->sin_addr.s_addr) { 06049 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06050 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06051 if (!ast_strlen_zero(p->mailbox)) { 06052 int new, old; 06053 ast_app_inboxcount(p->mailbox, &new, &old); 06054 if (new > 255) 06055 new = 255; 06056 if (old > 255) 06057 old = 255; 06058 msgcount = (old << 8) | new; 06059 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06060 } 06061 if (ast_test_flag(p, IAX_HASCALLERID)) { 06062 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06063 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06064 } 06065 } 06066 version = iax_check_version(devtype); 06067 if (version) 06068 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06069 06070 res = 0; 06071 06072 return_unref: 06073 peer_unref(p); 06074 06075 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06076 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1104 of file chan_iax2.c.
Referenced by load_module().
01105 { 01106 struct iax2_user *user = obj, *user2 = arg; 01107 01108 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01109 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9521 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09522 { 09523 struct iax2_user *user = obj; 09524 09525 ast_set_flag(user, IAX_DELME); 09526 09527 return 0; 09528 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9285 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
09286 { 09287 struct iax2_user *user = obj; 09288 09289 ast_free_ha(user->ha); 09290 free_context(user->contexts); 09291 if(user->vars) { 09292 ast_variables_destroy(user->vars); 09293 user->vars = NULL; 09294 } 09295 ast_string_field_free_memory(user); 09296 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1094 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01095 { 01096 const struct iax2_user *user = obj; 01097 01098 return ast_str_hash(user->name); 01099 }
Definition at line 1143 of file chan_iax2.c.
References ao2_ref().
01144 { 01145 ao2_ref(user, +1); 01146 return user; 01147 }
Definition at line 1149 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), prune_users(), and set_config().
01150 { 01151 ao2_ref(user, -1); 01152 return NULL; 01153 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6267 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::callno, f, iaxq, iaxs, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
06268 { 06269 struct iax_frame *f; 06270 06271 AST_LIST_LOCK(&iaxq.queue); 06272 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06273 /* Send a copy immediately */ 06274 if ((f->callno == callno) && iaxs[f->callno] && 06275 ((unsigned char ) (f->oseqno - last) < 128) && 06276 (f->retries >= 0)) { 06277 send_packet(f); 06278 } 06279 } 06280 AST_LIST_UNLOCK(&iaxq.queue); 06281 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 223 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), ast_channel_alloc(), begin_dial(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), sip_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
Definition at line 227 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 226 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 163 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 164 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 10594 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "debug", NULL }, iax2_no_debug, NULL, NULL }
Definition at line 10599 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "jb", "debug", NULL }, iax2_no_jb_debug, NULL, NULL }
Definition at line 10609 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "trunk", "debug", NULL }, iax2_no_trunk_debug, NULL, NULL }
Definition at line 10604 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug, NULL, NULL }
Definition at line 10589 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 148 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 10563 of file chan_iax2.c.
char debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk\n" " Requests current status of IAX trunking\n"
Definition at line 10555 of file chan_iax2.c.
char debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug\n" " Enables dumping of IAX packets for debugging purposes\n"
Definition at line 10547 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 180 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 228 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 281 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 231 of file chan_iax2.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), forward_message(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), sendmail(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 209 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 229 of file chan_iax2.c.
enum { ... } iax2_flags |
int(* iax2_regfunk)(const char *username, int onoff) = NULL |
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 10505 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 850 of file chan_iax2.c.
Referenced by __unload_module(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), 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 10571 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 457 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 211 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.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 456 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 814 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), find_callno(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[IAX_MAX_CALLS] [static] |
Definition at line 815 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), find_callno(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), and update_registry().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 454 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 213 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 206 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 156 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 150 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
Definition at line 816 of file chan_iax2.c.
Referenced by find_callno(), iax2_destroy(), and make_trunk().
int max_reg_expire [static] |
Definition at line 174 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 154 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 153 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 159 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 161 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 158 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 157 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 173 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 224 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 225 of file chan_iax2.c.
Referenced by check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 178 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 233 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 10567 of file chan_iax2.c.
char no_debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk off\n" " Requests current status of IAX trunking\n"
Definition at line 10559 of file chan_iax2.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug off\n" " Disables dumping of IAX packets for debugging purposes\n"
Definition at line 10551 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 179 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 8534 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peers [static] |
Definition at line 652 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), abort_request(), authenticate_reply(), build_peer(), build_transactions(), cancel_request(), chanavail_exec(), check_request(), complete_iax2_show_peer(), complete_peer_helper(), delete_users(), destroy_trans(), discover_transactions(), dundi_flush(), dundi_ie_append_eid_appropriately(), dundi_lookup_thread(), dundi_precache_internal(), dundi_precache_thread(), dundi_query_thread(), dundi_rexmit(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), dundi_show_trans(), find_peer(), handle_command_response(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), mark_mappings(), mark_peers(), network_thread(), optimize_transactions(), poke_all_peers(), precache_transactions(), prune_mappings(), prune_peers(), query_transactions(), realtime_peer(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 155 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 144 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10501 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 151 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 160 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 207 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 236 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 234 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 10493 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 10521 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 10539 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 10525 of file chan_iax2.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: iax2 show peer <name>\n" " Display details on specific IAX peer\n"
Definition at line 10497 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 10533 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10509 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 10543 of file chan_iax2.c.
char show_stats_usage[] [static] |
Initial value:
"Usage: iax2 show stats\n" " Display statistics on IAX channel driver.\n"
Definition at line 10489 of file chan_iax2.c.
char show_threads_usage[] [static] |
Initial value:
"Usage: iax2 show threads\n" " Lists status of IAX helper threads\n"
Definition at line 10529 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 10516 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 146 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 215 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 176 of file chan_iax2.c.
unsigned 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.
struct ao2_container* users [static] |
Definition at line 655 of file chan_iax2.c.
Referenced by __unload_module(), ast_get_manager_by_name_locked(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_voicemail_show_users(), delete_users(), find_or_create(), find_user(), handle_showmanager(), handle_showmanagers(), handle_voicemail_show_users(), iax2_destroy_helper(), iax2_show_users(), init_manager(), load_config(), load_module(), prune_users(), realtime_user(), reset_user_pw(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().