#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 ARRAY_LEN(iaxs) / 2 |
#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), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
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 int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
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 ast_channel *c, 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, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
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 *text) |
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, int check_dcallno) |
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 | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
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 | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
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_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno) |
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 void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
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 struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
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 |
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 [ARRAY_LEN(iaxs)] |
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 [ARRAY_LEN(iaxs)] |
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 662 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 658 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 672 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 660 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 664 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 666 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 668 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 670 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 123 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 131 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 196 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 195 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 194 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 439 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 136 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 177 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 185 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 190 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 179 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 695 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 699 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 114 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 436 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 644 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 442 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 440 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 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 437 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 1427 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 122 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 107 of file chan_iax2.c.
Definition at line 980 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 ARRAY_LEN(iaxs) / 2 |
Definition at line 826 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 445 of file chan_iax2.c.
anonymous enum |
Definition at line 230 of file chan_iax2.c.
00230 { 00231 IAX_STATE_STARTED = (1 << 0), 00232 IAX_STATE_AUTHENTICATED = (1 << 1), 00233 IAX_STATE_TBD = (1 << 2), 00234 IAX_STATE_UNCHANGED = (1 << 3), 00235 } iax2_state;
anonymous enum |
Definition at line 242 of file chan_iax2.c.
00242 { 00243 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00244 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00245 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00246 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00247 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00248 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00249 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00250 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00251 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00252 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00253 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00254 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00255 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00256 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00257 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00258 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00259 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00260 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00261 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00262 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00263 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00264 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00265 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00266 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00267 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00268 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00269 response, so that we've achieved a three-way handshake with 00270 them before sending voice or anything else*/ 00271 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00272 } 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 391 of file chan_iax2.c.
00391 { 00392 REG_STATE_UNREGISTERED = 0, 00393 REG_STATE_REGSENT, 00394 REG_STATE_AUTHSENT, 00395 REG_STATE_REGISTERED, 00396 REG_STATE_REJECTED, 00397 REG_STATE_TIMEOUT, 00398 REG_STATE_NOAUTH 00399 };
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 401 of file chan_iax2.c.
00401 { 00402 TRANSFER_NONE = 0, 00403 TRANSFER_BEGIN, 00404 TRANSFER_READY, 00405 TRANSFER_RELEASED, 00406 TRANSFER_PASSTHROUGH, 00407 TRANSFER_MBEGIN, 00408 TRANSFER_MREADY, 00409 TRANSFER_MRELEASED, 00410 TRANSFER_MPASSTHROUGH, 00411 TRANSFER_MEDIA, 00412 TRANSFER_MEDIAPASS 00413 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2146 of file chan_iax2.c.
References 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, chan_iax2_pvt::error, f, 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, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02147 { 02148 /* Attempt to transmit the frame to the remote peer... 02149 Called without iaxsl held. */ 02150 struct iax_frame *f = (struct iax_frame *)data; 02151 int freeme=0; 02152 int callno = f->callno; 02153 /* Make sure this call is still active */ 02154 if (callno) 02155 ast_mutex_lock(&iaxsl[callno]); 02156 if (callno && iaxs[callno]) { 02157 if ((f->retries < 0) /* Already ACK'd */ || 02158 (f->retries >= max_retries) /* Too many attempts */) { 02159 /* Record an error if we've transmitted too many times */ 02160 if (f->retries >= max_retries) { 02161 if (f->transfer) { 02162 /* Transfer timeout */ 02163 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02164 } else if (f->final) { 02165 if (f->final) 02166 iax2_destroy(callno); 02167 } else { 02168 if (iaxs[callno]->owner) 02169 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); 02170 iaxs[callno]->error = ETIMEDOUT; 02171 if (iaxs[callno]->owner) { 02172 struct ast_frame fr = { 0, }; 02173 /* Hangup the fd */ 02174 fr.frametype = AST_FRAME_CONTROL; 02175 fr.subclass = AST_CONTROL_HANGUP; 02176 iax2_queue_frame(callno, &fr); // XXX 02177 /* Remember, owner could disappear */ 02178 if (iaxs[callno] && iaxs[callno]->owner) 02179 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02180 } else { 02181 if (iaxs[callno]->reg) { 02182 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02183 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02184 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02185 } 02186 iax2_destroy(callno); 02187 } 02188 } 02189 02190 } 02191 freeme++; 02192 } else { 02193 /* Update it if it needs it */ 02194 update_packet(f); 02195 /* Attempt transmission */ 02196 send_packet(f); 02197 f->retries++; 02198 /* Try again later after 10 times as long */ 02199 f->retrytime *= 10; 02200 if (f->retrytime > MAX_RETRY_TIME) 02201 f->retrytime = MAX_RETRY_TIME; 02202 /* Transfer messages max out at one second */ 02203 if (f->transfer && (f->retrytime > 1000)) 02204 f->retrytime = 1000; 02205 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02206 } 02207 } else { 02208 /* Make sure it gets freed */ 02209 f->retries = -1; 02210 freeme++; 02211 } 02212 if (callno) 02213 ast_mutex_unlock(&iaxsl[callno]); 02214 /* Do not try again */ 02215 if (freeme) { 02216 /* Don't attempt delivery, just remove it from the queue */ 02217 AST_LIST_LOCK(&iaxq.queue); 02218 AST_LIST_REMOVE(&iaxq.queue, f, list); 02219 iaxq.count--; 02220 AST_LIST_UNLOCK(&iaxq.queue); 02221 f->retrans = -1; 02222 /* Free the IAX frame */ 02223 iax2_frame_free(f); 02224 } 02225 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6344 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
06345 { 06346 /* Called from IAX thread only, without iaxs lock */ 06347 int callno = (int)(long)(nothing); 06348 struct iax_ie_data ied; 06349 ast_mutex_lock(&iaxsl[callno]); 06350 if (iaxs[callno]) { 06351 memset(&ied, 0, sizeof(ied)); 06352 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06353 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06354 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06355 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06356 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06357 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06358 } 06359 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06360 } 06361 ast_mutex_unlock(&iaxsl[callno]); 06362 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3101 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03102 { 03103 int callno = PTR_TO_CALLNO(nothing); 03104 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03105 ast_mutex_lock(&iaxsl[callno]); 03106 if (iaxs[callno]) { 03107 iaxs[callno]->initid = -1; 03108 iax2_queue_frame(callno, &f); 03109 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03110 } 03111 ast_mutex_unlock(&iaxsl[callno]); 03112 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6393 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
06394 { 06395 /* Called from IAX thread only, without iaxs lock */ 06396 int callno = (int)(long)(nothing); 06397 struct iax_ie_data ied; 06398 ast_mutex_lock(&iaxsl[callno]); 06399 if (iaxs[callno]) { 06400 memset(&ied, 0, sizeof(ied)); 06401 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06402 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06403 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06404 } 06405 ast_mutex_unlock(&iaxsl[callno]); 06406 }
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 2013 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
02014 { 02015 /* Just deliver the packet by using queueing. This is called by 02016 the IAX thread with the iaxsl lock held. */ 02017 struct iax_frame *fr = data; 02018 fr->retrans = -1; 02019 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02020 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02021 iax2_queue_frame(fr->callno, &fr->af); 02022 /* Free our iax frame */ 02023 iax2_frame_free(fr); 02024 /* And don't run again */ 02025 return 0; 02026 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6032 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, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
06033 { 06034 struct iax2_peer *peer = (struct iax2_peer *) data; 06035 06036 if (!peer) 06037 return; 06038 06039 peer->expire = -1; 06040 06041 if (option_debug) 06042 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06043 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06044 realtime_update_peer(peer->name, &peer->addr, 0); 06045 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06046 /* Reset the address */ 06047 memset(&peer->addr, 0, sizeof(peer->addr)); 06048 /* Reset expiry value */ 06049 peer->expiry = min_reg_expire; 06050 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06051 ast_db_del("IAX/Registry", peer->name); 06052 register_peer_exten(peer, 0); 06053 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06054 if (iax2_regfunk) 06055 iax2_regfunk(peer->name, 0); 06056 06057 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06058 unlink_peer(peer); 06059 06060 peer_unref(peer); 06061 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1512 of file chan_iax2.c.
References chan_iax2_pvt::addr, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxsl, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, sched, send_lagrq(), send_ping(), store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01513 { 01514 int res = 0; 01515 int x; 01516 struct timeval now; 01517 char host[80]; 01518 01519 if (new <= NEW_ALLOW) { 01520 if (callno) { 01521 struct chan_iax2_pvt *pvt; 01522 struct chan_iax2_pvt tmp_pvt = { 01523 .callno = dcallno, 01524 .peercallno = callno, 01525 /* hack!! */ 01526 .frames_received = check_dcallno, 01527 }; 01528 01529 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01530 01531 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01532 if (return_locked) { 01533 ast_mutex_lock(&iaxsl[pvt->callno]); 01534 } 01535 res = pvt->callno; 01536 ao2_ref(pvt, -1); 01537 pvt = NULL; 01538 return res; 01539 } 01540 } 01541 01542 /* Look for an existing connection first */ 01543 for (x = 1; !res && x < maxnontrunkcall; x++) { 01544 ast_mutex_lock(&iaxsl[x]); 01545 if (iaxs[x]) { 01546 /* Look for an exact match */ 01547 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01548 res = x; 01549 } 01550 } 01551 if (!res || !return_locked) 01552 ast_mutex_unlock(&iaxsl[x]); 01553 } 01554 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01555 ast_mutex_lock(&iaxsl[x]); 01556 if (iaxs[x]) { 01557 /* Look for an exact match */ 01558 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01559 res = x; 01560 } 01561 } 01562 if (!res || !return_locked) 01563 ast_mutex_unlock(&iaxsl[x]); 01564 } 01565 } 01566 if (!res && (new >= NEW_ALLOW)) { 01567 int start, found = 0; 01568 01569 /* It may seem odd that we look through the peer list for a name for 01570 * this *incoming* call. Well, it is weird. However, users don't 01571 * have an IP address/port number that we can match against. So, 01572 * this is just checking for a peer that has that IP/port and 01573 * assuming that we have a user of the same name. This isn't always 01574 * correct, but it will be changed if needed after authentication. */ 01575 if (!iax2_getpeername(*sin, host, sizeof(host))) 01576 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01577 01578 now = ast_tvnow(); 01579 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01580 for (x = start; 1; x++) { 01581 if (x == TRUNK_CALL_START) { 01582 x = 1; 01583 continue; 01584 } 01585 01586 /* Find first unused call number that hasn't been used in a while */ 01587 ast_mutex_lock(&iaxsl[x]); 01588 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01589 found = 1; 01590 break; 01591 } 01592 ast_mutex_unlock(&iaxsl[x]); 01593 01594 if (x == start - 1) { 01595 break; 01596 } 01597 } 01598 /* We've still got lock held if we found a spot */ 01599 if (x == start - 1 && !found) { 01600 ast_log(LOG_WARNING, "No more space\n"); 01601 return 0; 01602 } 01603 iaxs[x] = new_iax(sin, host); 01604 update_max_nontrunk(); 01605 if (iaxs[x]) { 01606 if (option_debug && iaxdebug) 01607 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01608 iaxs[x]->sockfd = sockfd; 01609 iaxs[x]->addr.sin_port = sin->sin_port; 01610 iaxs[x]->addr.sin_family = sin->sin_family; 01611 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01612 iaxs[x]->peercallno = callno; 01613 iaxs[x]->callno = x; 01614 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01615 iaxs[x]->expiry = min_reg_expire; 01616 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01617 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01618 iaxs[x]->amaflags = amaflags; 01619 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01620 01621 ast_string_field_set(iaxs[x], accountcode, accountcode); 01622 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01623 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01624 01625 if (iaxs[x]->peercallno) { 01626 store_by_peercallno(iaxs[x]); 01627 } 01628 } else { 01629 ast_log(LOG_WARNING, "Out of resources\n"); 01630 ast_mutex_unlock(&iaxsl[x]); 01631 return 0; 01632 } 01633 if (!return_locked) 01634 ast_mutex_unlock(&iaxsl[x]); 01635 res = x; 01636 } 01637 return res; 01638 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2543 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(), 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().
02544 { 02545 int callno = PTR_TO_CALLNO(p); 02546 struct chan_iax2_pvt *pvt = NULL; 02547 struct iax_frame *fr; 02548 jb_frame frame; 02549 int ret; 02550 long now; 02551 long next; 02552 struct timeval tv; 02553 02554 /* Make sure we have a valid private structure before going on */ 02555 ast_mutex_lock(&iaxsl[callno]); 02556 pvt = iaxs[callno]; 02557 if (!pvt) { 02558 /* No go! */ 02559 ast_mutex_unlock(&iaxsl[callno]); 02560 return; 02561 } 02562 02563 pvt->jbid = -1; 02564 02565 gettimeofday(&tv,NULL); 02566 /* round up a millisecond since ast_sched_runq does; */ 02567 /* prevents us from spinning while waiting for our now */ 02568 /* to catch up with runq's now */ 02569 tv.tv_usec += 1000; 02570 02571 now = ast_tvdiff_ms(tv, pvt->rxcore); 02572 02573 if(now >= (next = jb_next(pvt->jb))) { 02574 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02575 switch(ret) { 02576 case JB_OK: 02577 fr = frame.data; 02578 __do_deliver(fr); 02579 /* __do_deliver() can cause the call to disappear */ 02580 pvt = iaxs[callno]; 02581 break; 02582 case JB_INTERP: 02583 { 02584 struct ast_frame af = { 0, }; 02585 02586 /* create an interpolation frame */ 02587 af.frametype = AST_FRAME_VOICE; 02588 af.subclass = pvt->voiceformat; 02589 af.samples = frame.ms * 8; 02590 af.src = "IAX2 JB interpolation"; 02591 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02592 af.offset = AST_FRIENDLY_OFFSET; 02593 02594 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02595 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02596 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02597 iax2_queue_frame(callno, &af); 02598 /* iax2_queue_frame() could cause the call to disappear */ 02599 pvt = iaxs[callno]; 02600 } 02601 } 02602 break; 02603 case JB_DROP: 02604 iax2_frame_free(frame.data); 02605 break; 02606 case JB_NOFRAME: 02607 case JB_EMPTY: 02608 /* do nothing */ 02609 break; 02610 default: 02611 /* shouldn't happen */ 02612 break; 02613 } 02614 } 02615 if (pvt) 02616 update_jbsched(pvt); 02617 ast_mutex_unlock(&iaxsl[callno]); 02618 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5725 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05726 { 05727 struct iax2_registry *reg = (struct iax2_registry *)data; 05728 reg->expire = -1; 05729 iax2_do_register(reg); 05730 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8826 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, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
08827 { 08828 struct iax2_peer *peer = (struct iax2_peer *)data; 08829 int callno; 08830 08831 if (peer->lastms > -1) { 08832 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08833 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08834 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08835 } 08836 if ((callno = peer->callno) > 0) { 08837 ast_mutex_lock(&iaxsl[callno]); 08838 iax2_destroy(callno); 08839 ast_mutex_unlock(&iaxsl[callno]); 08840 } 08841 peer->callno = 0; 08842 peer->lastms = -1; 08843 /* Try again quickly */ 08844 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08845 if (peer->pokeexpire == -1) 08846 peer_unref(peer); 08847 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6456 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06457 { 06458 struct iax2_peer *peer = (struct iax2_peer *)data; 06459 iax2_poke_peer(peer, 0); 06460 peer_unref(peer); 06461 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4515 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, RESULT_SUCCESS, and s.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04516 { 04517 regex_t regexbuf; 04518 int havepattern = 0; 04519 int total_peers = 0; 04520 int online_peers = 0; 04521 int offline_peers = 0; 04522 int unmonitored_peers = 0; 04523 struct ao2_iterator i; 04524 04525 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04526 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04527 04528 struct iax2_peer *peer = NULL; 04529 char name[256]; 04530 int registeredonly=0; 04531 char *term = manager ? "\r\n" : "\n"; 04532 04533 switch (argc) { 04534 case 6: 04535 if (!strcasecmp(argv[3], "registered")) 04536 registeredonly = 1; 04537 else 04538 return RESULT_SHOWUSAGE; 04539 if (!strcasecmp(argv[4], "like")) { 04540 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04541 return RESULT_SHOWUSAGE; 04542 havepattern = 1; 04543 } else 04544 return RESULT_SHOWUSAGE; 04545 break; 04546 case 5: 04547 if (!strcasecmp(argv[3], "like")) { 04548 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04549 return RESULT_SHOWUSAGE; 04550 havepattern = 1; 04551 } else 04552 return RESULT_SHOWUSAGE; 04553 break; 04554 case 4: 04555 if (!strcasecmp(argv[3], "registered")) 04556 registeredonly = 1; 04557 else 04558 return RESULT_SHOWUSAGE; 04559 break; 04560 case 3: 04561 break; 04562 default: 04563 return RESULT_SHOWUSAGE; 04564 } 04565 04566 04567 if (s) 04568 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04569 else 04570 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04571 04572 i = ao2_iterator_init(peers, 0); 04573 for (peer = ao2_iterator_next(&i); peer; 04574 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04575 char nm[20]; 04576 char status[20]; 04577 char srch[2000]; 04578 int retstatus; 04579 04580 if (registeredonly && !peer->addr.sin_addr.s_addr) 04581 continue; 04582 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04583 continue; 04584 04585 if (!ast_strlen_zero(peer->username)) 04586 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04587 else 04588 ast_copy_string(name, peer->name, sizeof(name)); 04589 04590 retstatus = peer_status(peer, status, sizeof(status)); 04591 if (retstatus > 0) 04592 online_peers++; 04593 else if (!retstatus) 04594 offline_peers++; 04595 else 04596 unmonitored_peers++; 04597 04598 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04599 04600 snprintf(srch, sizeof(srch), FORMAT, name, 04601 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04602 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04603 nm, 04604 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04605 peer->encmethods ? "(E)" : " ", status, term); 04606 04607 if (s) 04608 astman_append(s, FORMAT, name, 04609 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04610 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04611 nm, 04612 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04613 peer->encmethods ? "(E)" : " ", status, term); 04614 else 04615 ast_cli(fd, FORMAT, name, 04616 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04617 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04618 nm, 04619 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04620 peer->encmethods ? "(E)" : " ", status, term); 04621 total_peers++; 04622 } 04623 04624 if (s) 04625 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04626 else 04627 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04628 04629 if (havepattern) 04630 regfree(®exbuf); 04631 04632 return RESULT_SUCCESS; 04633 #undef FORMAT 04634 #undef FORMAT2 04635 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 955 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00956 { 00957 struct iax2_thread *thread = NULL; 00958 static time_t lasterror; 00959 static time_t t; 00960 00961 thread = find_idle_thread(); 00962 00963 if (thread != NULL) { 00964 thread->schedfunc = func; 00965 thread->scheddata = data; 00966 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00967 #ifdef DEBUG_SCHED_MULTITHREAD 00968 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00969 #endif 00970 signal_condition(&thread->lock, &thread->cond); 00971 return 0; 00972 } 00973 time(&t); 00974 if (t != lasterror && option_debug) 00975 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00976 lasterror = t; 00977 00978 return -1; 00979 }
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 5016 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05018 { 05019 struct ast_frame f = { 0, }; 05020 05021 f.frametype = type; 05022 f.subclass = command; 05023 f.datalen = datalen; 05024 f.src = __FUNCTION__; 05025 f.data = (void *) data; 05026 05027 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05028 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1035 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxsl, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01036 { 01037 int callno = (long) data; 01038 01039 ast_mutex_lock(&iaxsl[callno]); 01040 01041 while (iaxs[callno] && iaxs[callno]->lagid > -1) { 01042 if (iaxs[callno]->peercallno) { 01043 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01044 } 01045 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01046 break; 01047 } 01048 01049 ast_mutex_unlock(&iaxsl[callno]); 01050 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 995 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxsl, sched, send_command(), and send_ping().
Referenced by send_ping().
00996 { 00997 int callno = (long) data; 00998 00999 ast_mutex_lock(&iaxsl[callno]); 01000 01001 while (iaxs[callno] && iaxs[callno]->pingid != -1) { 01002 if (iaxs[callno]->peercallno) { 01003 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01004 } 01005 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01006 break; 01007 } 01008 01009 ast_mutex_unlock(&iaxsl[callno]); 01010 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10953 of file chan_iax2.c.
References ao2_ref(), ARRAY_LEN, 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_peercallno_pvts, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, netsock, outsock, peers, reload_firmware(), sched, sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10954 { 10955 struct iax2_thread *thread = NULL; 10956 int x; 10957 10958 /* Make sure threads do not hold shared resources when they are canceled */ 10959 10960 /* Grab the sched lock resource to keep it away from threads about to die */ 10961 /* Cancel the network thread, close the net socket */ 10962 if (netthreadid != AST_PTHREADT_NULL) { 10963 AST_LIST_LOCK(&iaxq.queue); 10964 ast_mutex_lock(&sched_lock); 10965 pthread_cancel(netthreadid); 10966 ast_cond_signal(&sched_cond); 10967 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10968 AST_LIST_UNLOCK(&iaxq.queue); 10969 pthread_join(netthreadid, NULL); 10970 } 10971 if (schedthreadid != AST_PTHREADT_NULL) { 10972 ast_mutex_lock(&sched_lock); 10973 pthread_cancel(schedthreadid); 10974 ast_cond_signal(&sched_cond); 10975 ast_mutex_unlock(&sched_lock); 10976 pthread_join(schedthreadid, NULL); 10977 } 10978 10979 /* Call for all threads to halt */ 10980 AST_LIST_LOCK(&idle_list); 10981 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10982 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10983 pthread_cancel(thread->threadid); 10984 } 10985 AST_LIST_TRAVERSE_SAFE_END 10986 AST_LIST_UNLOCK(&idle_list); 10987 10988 AST_LIST_LOCK(&active_list); 10989 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10990 AST_LIST_REMOVE_CURRENT(&active_list, list); 10991 pthread_cancel(thread->threadid); 10992 } 10993 AST_LIST_TRAVERSE_SAFE_END 10994 AST_LIST_UNLOCK(&active_list); 10995 10996 AST_LIST_LOCK(&dynamic_list); 10997 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10998 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10999 pthread_cancel(thread->threadid); 11000 } 11001 AST_LIST_TRAVERSE_SAFE_END 11002 AST_LIST_UNLOCK(&dynamic_list); 11003 11004 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11005 11006 /* Wait for threads to exit */ 11007 while(0 < iaxactivethreadcount) 11008 usleep(10000); 11009 11010 ast_netsock_release(netsock); 11011 ast_netsock_release(outsock); 11012 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11013 if (iaxs[x]) { 11014 iax2_destroy(x); 11015 } 11016 } 11017 ast_manager_unregister( "IAXpeers" ); 11018 ast_manager_unregister( "IAXnetstats" ); 11019 ast_unregister_application(papp); 11020 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11021 ast_unregister_switch(&iax2_switch); 11022 ast_channel_unregister(&iax2_tech); 11023 delete_users(); 11024 iax_provision_unload(); 11025 sched_context_destroy(sched); 11026 reload_firmware(1); 11027 11028 ast_mutex_destroy(&waresl.lock); 11029 11030 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11031 ast_mutex_destroy(&iaxsl[x]); 11032 } 11033 11034 ao2_ref(peers, -1); 11035 ao2_ref(users, -1); 11036 ao2_ref(iax_peercallno_pvts, -1); 11037 11038 return 0; 11039 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5069 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05070 { 05071 while(con) { 05072 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05073 return -1; 05074 con = con->next; 05075 } 05076 return 0; 05077 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4843 of file chan_iax2.c.
References ARRAY_LEN, 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_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, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04844 { 04845 int x; 04846 int numchans = 0; 04847 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04848 ast_mutex_lock(&iaxsl[x]); 04849 if (iaxs[x]) { 04850 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04851 char *fmt; 04852 jb_info jbinfo; 04853 04854 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04855 jb_getinfo(iaxs[x]->jb, &jbinfo); 04856 localjitter = jbinfo.jitter; 04857 localdelay = jbinfo.current - jbinfo.min; 04858 locallost = jbinfo.frames_lost; 04859 locallosspct = jbinfo.losspct/1000; 04860 localdropped = jbinfo.frames_dropped; 04861 localooo = jbinfo.frames_ooo; 04862 } else { 04863 localjitter = -1; 04864 localdelay = 0; 04865 locallost = -1; 04866 locallosspct = -1; 04867 localdropped = 0; 04868 localooo = -1; 04869 } 04870 if (limit_fmt) 04871 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04872 else 04873 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04874 if (s) 04875 04876 astman_append(s, fmt, 04877 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04878 iaxs[x]->pingtime, 04879 localjitter, 04880 localdelay, 04881 locallost, 04882 locallosspct, 04883 localdropped, 04884 localooo, 04885 iaxs[x]->frames_received/1000, 04886 iaxs[x]->remote_rr.jitter, 04887 iaxs[x]->remote_rr.delay, 04888 iaxs[x]->remote_rr.losscnt, 04889 iaxs[x]->remote_rr.losspct, 04890 iaxs[x]->remote_rr.dropped, 04891 iaxs[x]->remote_rr.ooo, 04892 iaxs[x]->remote_rr.packets/1000); 04893 else 04894 ast_cli(fd, fmt, 04895 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04896 iaxs[x]->pingtime, 04897 localjitter, 04898 localdelay, 04899 locallost, 04900 locallosspct, 04901 localdropped, 04902 localooo, 04903 iaxs[x]->frames_received/1000, 04904 iaxs[x]->remote_rr.jitter, 04905 iaxs[x]->remote_rr.delay, 04906 iaxs[x]->remote_rr.losscnt, 04907 iaxs[x]->remote_rr.losspct, 04908 iaxs[x]->remote_rr.dropped, 04909 iaxs[x]->remote_rr.ooo, 04910 iaxs[x]->remote_rr.packets/1000 04911 ); 04912 numchans++; 04913 } 04914 ast_mutex_unlock(&iaxsl[x]); 04915 } 04916 return numchans; 04917 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 3721 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_channel_free(), 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().
03722 { 03723 struct ast_channel *tmp; 03724 struct chan_iax2_pvt *i; 03725 struct ast_variable *v = NULL; 03726 03727 if (!(i = iaxs[callno])) { 03728 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03729 return NULL; 03730 } 03731 03732 /* Don't hold call lock */ 03733 ast_mutex_unlock(&iaxsl[callno]); 03734 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); 03735 ast_mutex_lock(&iaxsl[callno]); 03736 if (!iaxs[callno]) { 03737 if (tmp) { 03738 ast_channel_free(tmp); 03739 } 03740 ast_mutex_unlock(&iaxsl[callno]); 03741 return NULL; 03742 } 03743 03744 if (!tmp) 03745 return NULL; 03746 tmp->tech = &iax2_tech; 03747 /* We can support any format by default, until we get restricted */ 03748 tmp->nativeformats = capability; 03749 tmp->readformat = ast_best_codec(capability); 03750 tmp->writeformat = ast_best_codec(capability); 03751 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03752 03753 /* Don't use ast_set_callerid() here because it will 03754 * generate a NewCallerID event before the NewChannel event */ 03755 if (!ast_strlen_zero(i->ani)) 03756 tmp->cid.cid_ani = ast_strdup(i->ani); 03757 else 03758 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03759 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03760 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03761 tmp->cid.cid_pres = i->calling_pres; 03762 tmp->cid.cid_ton = i->calling_ton; 03763 tmp->cid.cid_tns = i->calling_tns; 03764 if (!ast_strlen_zero(i->language)) 03765 ast_string_field_set(tmp, language, i->language); 03766 if (!ast_strlen_zero(i->accountcode)) 03767 ast_string_field_set(tmp, accountcode, i->accountcode); 03768 if (i->amaflags) 03769 tmp->amaflags = i->amaflags; 03770 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03771 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03772 if (i->adsi) 03773 tmp->adsicpe = i->peeradsicpe; 03774 else 03775 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03776 i->owner = tmp; 03777 i->capability = capability; 03778 03779 for (v = i->vars ; v ; v = v->next) 03780 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03781 03782 if (state != AST_STATE_DOWN) { 03783 if (ast_pbx_start(tmp)) { 03784 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03785 ast_hangup(tmp); 03786 i->owner = NULL; 03787 return NULL; 03788 } 03789 } 03790 03791 ast_module_ref(ast_module_info->self); 03792 03793 return tmp; 03794 }
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 2227 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02228 { 02229 #ifdef SCHED_MULTITHREADED 02230 if (schedule_action(__attempt_transmit, data)) 02231 #endif 02232 __attempt_transmit(data); 02233 return 0; 02234 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6378 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), iaxs, and sched.
Referenced by socket_process().
06379 { 06380 /* Schedule sending the authentication failure in one second, to prevent 06381 guessing */ 06382 if (iaxs[callno]) { 06383 iaxs[callno]->authfail = failcode; 06384 if (delayreject) { 06385 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06386 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06387 } else 06388 auth_reject((void *)(long)callno); 06389 } 06390 return 0; 06391 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6364 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06365 { 06366 int callno = (int)(long)(data); 06367 ast_mutex_lock(&iaxsl[callno]); 06368 if (iaxs[callno]) 06369 iaxs[callno]->authid = -1; 06370 ast_mutex_unlock(&iaxsl[callno]); 06371 #ifdef SCHED_MULTITHREADED 06372 if (schedule_action(__auth_reject, data)) 06373 #endif 06374 __auth_reject(data); 06375 return 0; 06376 }
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 5594 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, LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05595 { 05596 int res = -1; 05597 int x; 05598 if (!ast_strlen_zero(keyn)) { 05599 if (!(authmethods & IAX_AUTH_RSA)) { 05600 if (ast_strlen_zero(secret)) 05601 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)); 05602 } else if (ast_strlen_zero(challenge)) { 05603 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05604 } else { 05605 char sig[256]; 05606 struct ast_key *key; 05607 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05608 if (!key) { 05609 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05610 } else { 05611 if (ast_sign(key, (char*)challenge, sig)) { 05612 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05613 res = -1; 05614 } else { 05615 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05616 res = 0; 05617 } 05618 } 05619 } 05620 } 05621 /* Fall back */ 05622 if (res && !ast_strlen_zero(secret)) { 05623 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05624 struct MD5Context md5; 05625 unsigned char digest[16]; 05626 char digres[128]; 05627 MD5Init(&md5); 05628 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05629 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05630 MD5Final(digest, &md5); 05631 /* If they support md5, authenticate with it. */ 05632 for (x=0;x<16;x++) 05633 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05634 if (ecx && dcx) 05635 build_enc_keys(digest, ecx, dcx); 05636 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05637 res = 0; 05638 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05639 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05640 res = 0; 05641 } else 05642 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05643 } 05644 return res; 05645 }
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 5651 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(), iax2_peer::authmethods, chan_iax2_pvt::callno, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, ies, iax2_peer::mask, merge_encryption(), peer_unref(), peers, realtime_peer(), and send_command().
Referenced by socket_process().
05652 { 05653 struct iax2_peer *peer = NULL; 05654 /* Start pessimistic */ 05655 int res = -1; 05656 int authmethods = 0; 05657 struct iax_ie_data ied; 05658 uint16_t callno = p->callno; 05659 05660 memset(&ied, 0, sizeof(ied)); 05661 05662 if (ies->username) 05663 ast_string_field_set(p, username, ies->username); 05664 if (ies->challenge) 05665 ast_string_field_set(p, challenge, ies->challenge); 05666 if (ies->authmethods) 05667 authmethods = ies->authmethods; 05668 if (authmethods & IAX_AUTH_MD5) 05669 merge_encryption(p, ies->encmethods); 05670 else 05671 p->encmethods = 0; 05672 05673 /* Check for override RSA authentication first */ 05674 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05675 /* Normal password authentication */ 05676 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05677 } else { 05678 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05679 while ((peer = ao2_iterator_next(&i))) { 05680 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05681 /* No peer specified at our end, or this is the peer */ 05682 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05683 /* No username specified in peer rule, or this is the right username */ 05684 && (!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))) 05685 /* No specified host, or this is our host */ 05686 ) { 05687 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05688 if (!res) { 05689 peer_unref(peer); 05690 break; 05691 } 05692 } 05693 peer_unref(peer); 05694 } 05695 if (!peer) { 05696 /* We checked our list and didn't find one. It's unlikely, but possible, 05697 that we're trying to authenticate *to* a realtime peer */ 05698 const char *peer_name = ast_strdupa(p->peer); 05699 ast_mutex_unlock(&iaxsl[callno]); 05700 if ((peer = realtime_peer(peer_name, NULL))) { 05701 ast_mutex_lock(&iaxsl[callno]); 05702 if (!(p = iaxs[callno])) { 05703 peer_unref(peer); 05704 return -1; 05705 } 05706 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05707 peer_unref(peer); 05708 } 05709 if (!peer) { 05710 ast_mutex_lock(&iaxsl[callno]); 05711 if (!(p = iaxs[callno])) 05712 return -1; 05713 } 05714 } 05715 } 05716 if (ies->encmethods) 05717 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05718 if (!res) 05719 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05720 return res; 05721 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5329 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, 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, send_command(), send_command_final(), user_unref(), and users.
Referenced by socket_process().
05330 { 05331 struct iax_ie_data ied; 05332 int res = -1, authreq_restrict = 0; 05333 char challenge[10]; 05334 struct chan_iax2_pvt *p = iaxs[call_num]; 05335 05336 memset(&ied, 0, sizeof(ied)); 05337 05338 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05339 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05340 struct iax2_user *user, tmp_user = { 05341 .name = p->username, 05342 }; 05343 05344 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05345 if (user) { 05346 if (user->curauthreq == user->maxauthreq) 05347 authreq_restrict = 1; 05348 else 05349 user->curauthreq++; 05350 user = user_unref(user); 05351 } 05352 } 05353 05354 /* If the AUTHREQ limit test failed, send back an error */ 05355 if (authreq_restrict) { 05356 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05357 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05358 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05359 return 0; 05360 } 05361 05362 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05363 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05364 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05365 ast_string_field_set(p, challenge, challenge); 05366 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05367 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05368 } 05369 if (p->encmethods) 05370 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05371 05372 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05373 05374 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05375 05376 if (p->encmethods) 05377 ast_set_flag(p, IAX_ENCRYPTED); 05378 05379 return res; 05380 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5382 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, ies, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05383 { 05384 char requeststr[256]; 05385 char md5secret[256] = ""; 05386 char secret[256] = ""; 05387 char rsasecret[256] = ""; 05388 int res = -1; 05389 int x; 05390 struct iax2_user *user, tmp_user = { 05391 .name = p->username, 05392 }; 05393 05394 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05395 if (user) { 05396 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05397 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05398 ast_clear_flag(p, IAX_MAXAUTHREQ); 05399 } 05400 ast_string_field_set(p, host, user->name); 05401 user = user_unref(user); 05402 } 05403 05404 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05405 return res; 05406 if (ies->password) 05407 ast_copy_string(secret, ies->password, sizeof(secret)); 05408 if (ies->md5_result) 05409 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05410 if (ies->rsa_result) 05411 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05412 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05413 struct ast_key *key; 05414 char *keyn; 05415 char tmpkey[256]; 05416 char *stringp=NULL; 05417 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05418 stringp=tmpkey; 05419 keyn = strsep(&stringp, ":"); 05420 while(keyn) { 05421 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05422 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05423 res = 0; 05424 break; 05425 } else if (!key) 05426 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05427 keyn = strsep(&stringp, ":"); 05428 } 05429 } else if (p->authmethods & IAX_AUTH_MD5) { 05430 struct MD5Context md5; 05431 unsigned char digest[16]; 05432 char *tmppw, *stringp; 05433 05434 tmppw = ast_strdupa(p->secret); 05435 stringp = tmppw; 05436 while((tmppw = strsep(&stringp, ";"))) { 05437 MD5Init(&md5); 05438 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05439 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05440 MD5Final(digest, &md5); 05441 /* If they support md5, authenticate with it. */ 05442 for (x=0;x<16;x++) 05443 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05444 if (!strcasecmp(requeststr, md5secret)) { 05445 res = 0; 05446 break; 05447 } 05448 } 05449 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05450 if (!strcmp(secret, p->secret)) 05451 res = 0; 05452 } 05453 return res; 05454 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3114 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03115 { 03116 #ifdef SCHED_MULTITHREADED 03117 if (schedule_action(__auto_congest, data)) 03118 #endif 03119 __auto_congest(data); 03120 return 0; 03121 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6408 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06409 { 06410 int callno = (int)(long)(data); 06411 ast_mutex_lock(&iaxsl[callno]); 06412 if (iaxs[callno]) { 06413 iaxs[callno]->autoid = -1; 06414 } 06415 ast_mutex_unlock(&iaxsl[callno]); 06416 #ifdef SCHED_MULTITHREADED 06417 if (schedule_action(__auto_hangup, data)) 06418 #endif 06419 __auto_hangup(data); 06420 return 0; 06421 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 9147 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
09148 { 09149 struct iax2_context *con; 09150 09151 if ((con = ast_calloc(1, sizeof(*con)))) 09152 ast_copy_string(con->context, context, sizeof(con->context)); 09153 09154 return con; 09155 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4101 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04102 { 04103 aes_encrypt_key128(digest, ecx); 04104 aes_decrypt_key128(digest, dcx); 04105 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 9293 of file chan_iax2.c.
References 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(), cid_name, cid_num, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, prefs, sched, secret, unlink_peer(), and ast_variable::value.
09294 { 09295 struct iax2_peer *peer = NULL; 09296 struct ast_ha *oldha = NULL; 09297 int maskfound=0; 09298 int found=0; 09299 int firstpass=1; 09300 struct iax2_peer tmp_peer = { 09301 .name = name, 09302 }; 09303 09304 if (!temponly) { 09305 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09306 if (peer && !ast_test_flag(peer, IAX_DELME)) 09307 firstpass = 0; 09308 } 09309 09310 if (peer) { 09311 found++; 09312 if (firstpass) { 09313 oldha = peer->ha; 09314 peer->ha = NULL; 09315 } 09316 unlink_peer(peer); 09317 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09318 peer->expire = -1; 09319 peer->pokeexpire = -1; 09320 peer->sockfd = defaultsockfd; 09321 if (ast_string_field_init(peer, 32)) 09322 peer = peer_unref(peer); 09323 } 09324 09325 if (peer) { 09326 if (firstpass) { 09327 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09328 peer->encmethods = iax2_encryption; 09329 peer->adsi = adsi; 09330 ast_string_field_set(peer,secret,""); 09331 if (!found) { 09332 ast_string_field_set(peer, name, name); 09333 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09334 peer->expiry = min_reg_expire; 09335 } 09336 peer->prefs = prefs; 09337 peer->capability = iax2_capability; 09338 peer->smoothing = 0; 09339 peer->pokefreqok = DEFAULT_FREQ_OK; 09340 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09341 ast_string_field_set(peer,context,""); 09342 ast_string_field_set(peer,peercontext,""); 09343 ast_clear_flag(peer, IAX_HASCALLERID); 09344 ast_string_field_set(peer, cid_name, ""); 09345 ast_string_field_set(peer, cid_num, ""); 09346 } 09347 09348 if (!v) { 09349 v = alt; 09350 alt = NULL; 09351 } 09352 while(v) { 09353 if (!strcasecmp(v->name, "secret")) { 09354 ast_string_field_set(peer, secret, v->value); 09355 } else if (!strcasecmp(v->name, "mailbox")) { 09356 ast_string_field_set(peer, mailbox, v->value); 09357 } else if (!strcasecmp(v->name, "mohinterpret")) { 09358 ast_string_field_set(peer, mohinterpret, v->value); 09359 } else if (!strcasecmp(v->name, "mohsuggest")) { 09360 ast_string_field_set(peer, mohsuggest, v->value); 09361 } else if (!strcasecmp(v->name, "dbsecret")) { 09362 ast_string_field_set(peer, dbsecret, v->value); 09363 } else if (!strcasecmp(v->name, "trunk")) { 09364 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09365 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09366 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09367 ast_clear_flag(peer, IAX_TRUNK); 09368 } 09369 } else if (!strcasecmp(v->name, "auth")) { 09370 peer->authmethods = get_auth_methods(v->value); 09371 } else if (!strcasecmp(v->name, "encryption")) { 09372 peer->encmethods = get_encrypt_methods(v->value); 09373 } else if (!strcasecmp(v->name, "notransfer")) { 09374 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09375 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09376 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09377 } else if (!strcasecmp(v->name, "transfer")) { 09378 if (!strcasecmp(v->value, "mediaonly")) { 09379 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09380 } else if (ast_true(v->value)) { 09381 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09382 } else 09383 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09384 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09385 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09386 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09387 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09388 } else if (!strcasecmp(v->name, "host")) { 09389 if (!strcasecmp(v->value, "dynamic")) { 09390 /* They'll register with us */ 09391 ast_set_flag(peer, IAX_DYNAMIC); 09392 if (!found) { 09393 /* Initialize stuff iff we're not found, otherwise 09394 we keep going with what we had */ 09395 memset(&peer->addr.sin_addr, 0, 4); 09396 if (peer->addr.sin_port) { 09397 /* If we've already got a port, make it the default rather than absolute */ 09398 peer->defaddr.sin_port = peer->addr.sin_port; 09399 peer->addr.sin_port = 0; 09400 } 09401 } 09402 } else { 09403 /* Non-dynamic. Make sure we become that way if we're not */ 09404 AST_SCHED_DEL(sched, peer->expire); 09405 ast_clear_flag(peer, IAX_DYNAMIC); 09406 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09407 return peer_unref(peer); 09408 if (!peer->addr.sin_port) 09409 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09410 } 09411 if (!maskfound) 09412 inet_aton("255.255.255.255", &peer->mask); 09413 } else if (!strcasecmp(v->name, "defaultip")) { 09414 if (ast_get_ip(&peer->defaddr, v->value)) 09415 return peer_unref(peer); 09416 } else if (!strcasecmp(v->name, "sourceaddress")) { 09417 peer_set_srcaddr(peer, v->value); 09418 } else if (!strcasecmp(v->name, "permit") || 09419 !strcasecmp(v->name, "deny")) { 09420 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09421 } else if (!strcasecmp(v->name, "mask")) { 09422 maskfound++; 09423 inet_aton(v->value, &peer->mask); 09424 } else if (!strcasecmp(v->name, "context")) { 09425 ast_string_field_set(peer, context, v->value); 09426 } else if (!strcasecmp(v->name, "regexten")) { 09427 ast_string_field_set(peer, regexten, v->value); 09428 } else if (!strcasecmp(v->name, "peercontext")) { 09429 ast_string_field_set(peer, peercontext, v->value); 09430 } else if (!strcasecmp(v->name, "port")) { 09431 if (ast_test_flag(peer, IAX_DYNAMIC)) 09432 peer->defaddr.sin_port = htons(atoi(v->value)); 09433 else 09434 peer->addr.sin_port = htons(atoi(v->value)); 09435 } else if (!strcasecmp(v->name, "username")) { 09436 ast_string_field_set(peer, username, v->value); 09437 } else if (!strcasecmp(v->name, "allow")) { 09438 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09439 } else if (!strcasecmp(v->name, "disallow")) { 09440 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09441 } else if (!strcasecmp(v->name, "callerid")) { 09442 if (!ast_strlen_zero(v->value)) { 09443 char name2[80]; 09444 char num2[80]; 09445 ast_callerid_split(v->value, name2, 80, num2, 80); 09446 ast_string_field_set(peer, cid_name, name2); 09447 ast_string_field_set(peer, cid_num, num2); 09448 ast_set_flag(peer, IAX_HASCALLERID); 09449 } else { 09450 ast_clear_flag(peer, IAX_HASCALLERID); 09451 ast_string_field_set(peer, cid_name, ""); 09452 ast_string_field_set(peer, cid_num, ""); 09453 } 09454 } else if (!strcasecmp(v->name, "fullname")) { 09455 if (!ast_strlen_zero(v->value)) { 09456 ast_string_field_set(peer, cid_name, v->value); 09457 ast_set_flag(peer, IAX_HASCALLERID); 09458 } else { 09459 ast_string_field_set(peer, cid_name, ""); 09460 if (ast_strlen_zero(peer->cid_num)) 09461 ast_clear_flag(peer, IAX_HASCALLERID); 09462 } 09463 } else if (!strcasecmp(v->name, "cid_number")) { 09464 if (!ast_strlen_zero(v->value)) { 09465 ast_string_field_set(peer, cid_num, v->value); 09466 ast_set_flag(peer, IAX_HASCALLERID); 09467 } else { 09468 ast_string_field_set(peer, cid_num, ""); 09469 if (ast_strlen_zero(peer->cid_name)) 09470 ast_clear_flag(peer, IAX_HASCALLERID); 09471 } 09472 } else if (!strcasecmp(v->name, "sendani")) { 09473 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09474 } else if (!strcasecmp(v->name, "inkeys")) { 09475 ast_string_field_set(peer, inkeys, v->value); 09476 } else if (!strcasecmp(v->name, "outkey")) { 09477 ast_string_field_set(peer, outkey, v->value); 09478 } else if (!strcasecmp(v->name, "qualify")) { 09479 if (!strcasecmp(v->value, "no")) { 09480 peer->maxms = 0; 09481 } else if (!strcasecmp(v->value, "yes")) { 09482 peer->maxms = DEFAULT_MAXMS; 09483 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09484 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); 09485 peer->maxms = 0; 09486 } 09487 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09488 peer->smoothing = ast_true(v->value); 09489 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09490 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09491 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); 09492 } 09493 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09494 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09495 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); 09496 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09497 } else if (!strcasecmp(v->name, "timezone")) { 09498 ast_string_field_set(peer, zonetag, v->value); 09499 } else if (!strcasecmp(v->name, "adsi")) { 09500 peer->adsi = ast_true(v->value); 09501 }/* else if (strcasecmp(v->name,"type")) */ 09502 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09503 v = v->next; 09504 if (!v) { 09505 v = alt; 09506 alt = NULL; 09507 } 09508 } 09509 if (!peer->authmethods) 09510 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09511 ast_clear_flag(peer, IAX_DELME); 09512 /* Make sure these are IPv4 addresses */ 09513 peer->addr.sin_family = AF_INET; 09514 } 09515 if (oldha) 09516 ast_free_ha(oldha); 09517 return peer; 09518 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 9534 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(), globalflags, 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_user::prefs, prefs, secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09535 { 09536 struct iax2_user *user = NULL; 09537 struct iax2_context *con, *conl = NULL; 09538 struct ast_ha *oldha = NULL; 09539 struct iax2_context *oldcon = NULL; 09540 int format; 09541 int firstpass=1; 09542 int oldcurauthreq = 0; 09543 char *varname = NULL, *varval = NULL; 09544 struct ast_variable *tmpvar = NULL; 09545 struct iax2_user tmp_user = { 09546 .name = name, 09547 }; 09548 09549 if (!temponly) { 09550 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09551 if (user && !ast_test_flag(user, IAX_DELME)) 09552 firstpass = 0; 09553 } 09554 09555 if (user) { 09556 if (firstpass) { 09557 oldcurauthreq = user->curauthreq; 09558 oldha = user->ha; 09559 oldcon = user->contexts; 09560 user->ha = NULL; 09561 user->contexts = NULL; 09562 } 09563 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09564 ao2_unlink(users, user); 09565 } else { 09566 user = ao2_alloc(sizeof(*user), user_destructor); 09567 } 09568 09569 if (user) { 09570 if (firstpass) { 09571 ast_string_field_free_memory(user); 09572 memset(user, 0, sizeof(struct iax2_user)); 09573 if (ast_string_field_init(user, 32)) { 09574 user = user_unref(user); 09575 goto cleanup; 09576 } 09577 user->maxauthreq = maxauthreq; 09578 user->curauthreq = oldcurauthreq; 09579 user->prefs = prefs; 09580 user->capability = iax2_capability; 09581 user->encmethods = iax2_encryption; 09582 user->adsi = adsi; 09583 ast_string_field_set(user, name, name); 09584 ast_string_field_set(user, language, language); 09585 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09586 ast_clear_flag(user, IAX_HASCALLERID); 09587 ast_string_field_set(user, cid_name, ""); 09588 ast_string_field_set(user, cid_num, ""); 09589 } 09590 if (!v) { 09591 v = alt; 09592 alt = NULL; 09593 } 09594 while(v) { 09595 if (!strcasecmp(v->name, "context")) { 09596 con = build_context(v->value); 09597 if (con) { 09598 if (conl) 09599 conl->next = con; 09600 else 09601 user->contexts = con; 09602 conl = con; 09603 } 09604 } else if (!strcasecmp(v->name, "permit") || 09605 !strcasecmp(v->name, "deny")) { 09606 user->ha = ast_append_ha(v->name, v->value, user->ha); 09607 } else if (!strcasecmp(v->name, "setvar")) { 09608 varname = ast_strdupa(v->value); 09609 if (varname && (varval = strchr(varname,'='))) { 09610 *varval = '\0'; 09611 varval++; 09612 if((tmpvar = ast_variable_new(varname, varval))) { 09613 tmpvar->next = user->vars; 09614 user->vars = tmpvar; 09615 } 09616 } 09617 } else if (!strcasecmp(v->name, "allow")) { 09618 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09619 } else if (!strcasecmp(v->name, "disallow")) { 09620 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09621 } else if (!strcasecmp(v->name, "trunk")) { 09622 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09623 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09624 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09625 ast_clear_flag(user, IAX_TRUNK); 09626 } 09627 } else if (!strcasecmp(v->name, "auth")) { 09628 user->authmethods = get_auth_methods(v->value); 09629 } else if (!strcasecmp(v->name, "encryption")) { 09630 user->encmethods = get_encrypt_methods(v->value); 09631 } else if (!strcasecmp(v->name, "notransfer")) { 09632 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09633 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09634 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09635 } else if (!strcasecmp(v->name, "transfer")) { 09636 if (!strcasecmp(v->value, "mediaonly")) { 09637 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09638 } else if (ast_true(v->value)) { 09639 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09640 } else 09641 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09642 } else if (!strcasecmp(v->name, "codecpriority")) { 09643 if(!strcasecmp(v->value, "caller")) 09644 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09645 else if(!strcasecmp(v->value, "disabled")) 09646 ast_set_flag(user, IAX_CODEC_NOPREFS); 09647 else if(!strcasecmp(v->value, "reqonly")) { 09648 ast_set_flag(user, IAX_CODEC_NOCAP); 09649 ast_set_flag(user, IAX_CODEC_NOPREFS); 09650 } 09651 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09652 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09653 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09654 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09655 } else if (!strcasecmp(v->name, "dbsecret")) { 09656 ast_string_field_set(user, dbsecret, v->value); 09657 } else if (!strcasecmp(v->name, "secret")) { 09658 if (!ast_strlen_zero(user->secret)) { 09659 char *old = ast_strdupa(user->secret); 09660 09661 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09662 } else 09663 ast_string_field_set(user, secret, v->value); 09664 } else if (!strcasecmp(v->name, "callerid")) { 09665 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09666 char name2[80]; 09667 char num2[80]; 09668 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09669 ast_string_field_set(user, cid_name, name2); 09670 ast_string_field_set(user, cid_num, num2); 09671 ast_set_flag(user, IAX_HASCALLERID); 09672 } else { 09673 ast_clear_flag(user, IAX_HASCALLERID); 09674 ast_string_field_set(user, cid_name, ""); 09675 ast_string_field_set(user, cid_num, ""); 09676 } 09677 } else if (!strcasecmp(v->name, "fullname")) { 09678 if (!ast_strlen_zero(v->value)) { 09679 ast_string_field_set(user, cid_name, v->value); 09680 ast_set_flag(user, IAX_HASCALLERID); 09681 } else { 09682 ast_string_field_set(user, cid_name, ""); 09683 if (ast_strlen_zero(user->cid_num)) 09684 ast_clear_flag(user, IAX_HASCALLERID); 09685 } 09686 } else if (!strcasecmp(v->name, "cid_number")) { 09687 if (!ast_strlen_zero(v->value)) { 09688 ast_string_field_set(user, cid_num, v->value); 09689 ast_set_flag(user, IAX_HASCALLERID); 09690 } else { 09691 ast_string_field_set(user, cid_num, ""); 09692 if (ast_strlen_zero(user->cid_name)) 09693 ast_clear_flag(user, IAX_HASCALLERID); 09694 } 09695 } else if (!strcasecmp(v->name, "accountcode")) { 09696 ast_string_field_set(user, accountcode, v->value); 09697 } else if (!strcasecmp(v->name, "mohinterpret")) { 09698 ast_string_field_set(user, mohinterpret, v->value); 09699 } else if (!strcasecmp(v->name, "mohsuggest")) { 09700 ast_string_field_set(user, mohsuggest, v->value); 09701 } else if (!strcasecmp(v->name, "language")) { 09702 ast_string_field_set(user, language, v->value); 09703 } else if (!strcasecmp(v->name, "amaflags")) { 09704 format = ast_cdr_amaflags2int(v->value); 09705 if (format < 0) { 09706 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09707 } else { 09708 user->amaflags = format; 09709 } 09710 } else if (!strcasecmp(v->name, "inkeys")) { 09711 ast_string_field_set(user, inkeys, v->value); 09712 } else if (!strcasecmp(v->name, "maxauthreq")) { 09713 user->maxauthreq = atoi(v->value); 09714 if (user->maxauthreq < 0) 09715 user->maxauthreq = 0; 09716 } else if (!strcasecmp(v->name, "adsi")) { 09717 user->adsi = ast_true(v->value); 09718 }/* else if (strcasecmp(v->name,"type")) */ 09719 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09720 v = v->next; 09721 if (!v) { 09722 v = alt; 09723 alt = NULL; 09724 } 09725 } 09726 if (!user->authmethods) { 09727 if (!ast_strlen_zero(user->secret)) { 09728 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09729 if (!ast_strlen_zero(user->inkeys)) 09730 user->authmethods |= IAX_AUTH_RSA; 09731 } else if (!ast_strlen_zero(user->inkeys)) { 09732 user->authmethods = IAX_AUTH_RSA; 09733 } else { 09734 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09735 } 09736 } 09737 ast_clear_flag(user, IAX_DELME); 09738 } 09739 cleanup: 09740 if (oldha) 09741 ast_free_ha(oldha); 09742 if (oldcon) 09743 free_context(oldcon); 09744 return user; 09745 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10250 of file chan_iax2.c.
References ARRAY_LEN, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
10251 { 10252 struct sockaddr_in sin; 10253 int x; 10254 int callno; 10255 struct iax_ie_data ied; 10256 struct create_addr_info cai; 10257 struct parsed_dial_string pds; 10258 char *tmpstr; 10259 10260 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10261 /* Look for an *exact match* call. Once a call is negotiated, it can only 10262 look up entries for a single context */ 10263 if (!ast_mutex_trylock(&iaxsl[x])) { 10264 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10265 return x; 10266 ast_mutex_unlock(&iaxsl[x]); 10267 } 10268 } 10269 10270 /* No match found, we need to create a new one */ 10271 10272 memset(&cai, 0, sizeof(cai)); 10273 memset(&ied, 0, sizeof(ied)); 10274 memset(&pds, 0, sizeof(pds)); 10275 10276 tmpstr = ast_strdupa(data); 10277 parse_dial_string(tmpstr, &pds); 10278 10279 if (ast_strlen_zero(pds.peer)) { 10280 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10281 return -1; 10282 } 10283 10284 /* Populate our address from the given */ 10285 if (create_addr(pds.peer, NULL, &sin, &cai)) 10286 return -1; 10287 10288 if (option_debug) 10289 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10290 pds.peer, pds.username, pds.password, pds.context); 10291 10292 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10293 if (callno < 1) { 10294 ast_log(LOG_WARNING, "Unable to create call\n"); 10295 return -1; 10296 } 10297 10298 ast_string_field_set(iaxs[callno], dproot, data); 10299 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10300 10301 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10302 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10303 /* the string format is slightly different from a standard dial string, 10304 because the context appears in the 'exten' position 10305 */ 10306 if (pds.exten) 10307 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10308 if (pds.username) 10309 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10310 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10311 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10312 /* Keep password handy */ 10313 if (pds.password) 10314 ast_string_field_set(iaxs[callno], secret, pds.password); 10315 if (pds.key) 10316 ast_string_field_set(iaxs[callno], outkey, pds.key); 10317 /* Start the call going */ 10318 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10319 10320 return callno; 10321 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3969 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03970 { 03971 /* Returns where in "receive time" we are. That is, how many ms 03972 since we received (or would have received) the frame with timestamp 0 */ 03973 int ms; 03974 #ifdef IAXTESTS 03975 int jit; 03976 #endif /* IAXTESTS */ 03977 /* Setup rxcore if necessary */ 03978 if (ast_tvzero(p->rxcore)) { 03979 p->rxcore = ast_tvnow(); 03980 if (option_debug && iaxdebug) 03981 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03982 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03983 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03984 #if 1 03985 if (option_debug && iaxdebug) 03986 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03987 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03988 #endif 03989 } 03990 03991 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03992 #ifdef IAXTESTS 03993 if (test_jit) { 03994 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03995 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03996 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03997 jit = -jit; 03998 ms += jit; 03999 } 04000 } 04001 if (test_late) { 04002 ms += test_late; 04003 test_late = 0; 04004 } 04005 #endif /* IAXTESTS */ 04006 return ms; 04007 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3840 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, and option_debug.
Referenced by iax2_send(), and socket_process().
03841 { 03842 int ms; 03843 int voice = 0; 03844 int genuine = 0; 03845 int adjust; 03846 struct timeval *delivery = NULL; 03847 03848 03849 /* What sort of frame do we have?: voice is self-explanatory 03850 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03851 non-genuine frames are CONTROL frames [ringing etc], DTMF 03852 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03853 the others need a timestamp slaved to the voice frames so that they go in sequence 03854 */ 03855 if (f) { 03856 if (f->frametype == AST_FRAME_VOICE) { 03857 voice = 1; 03858 delivery = &f->delivery; 03859 } else if (f->frametype == AST_FRAME_IAX) { 03860 genuine = 1; 03861 } else if (f->frametype == AST_FRAME_CNG) { 03862 p->notsilenttx = 0; 03863 } 03864 } 03865 if (ast_tvzero(p->offset)) { 03866 gettimeofday(&p->offset, NULL); 03867 /* Round to nearest 20ms for nice looking traces */ 03868 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03869 } 03870 /* If the timestamp is specified, just send it as is */ 03871 if (ts) 03872 return ts; 03873 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03874 if (delivery && !ast_tvzero(*delivery)) { 03875 ms = ast_tvdiff_ms(*delivery, p->offset); 03876 if (option_debug > 2 && iaxdebug) 03877 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03878 } else { 03879 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03880 if (ms < 0) 03881 ms = 0; 03882 if (voice) { 03883 /* On a voice frame, use predicted values if appropriate */ 03884 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03885 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03886 /* AN EXPLANATION: 03887 When we send voice, we usually send "calculated" timestamps worked out 03888 on the basis of the number of samples sent. When we send other frames, 03889 we usually send timestamps worked out from the real clock. 03890 The problem is that they can tend to drift out of step because the 03891 source channel's clock and our clock may not be exactly at the same rate. 03892 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03893 for this call. Moving it adjusts timestamps for non-voice frames. 03894 We make the adjustment in the style of a moving average. Each time we 03895 adjust p->offset by 10% of the difference between our clock-derived 03896 timestamp and the predicted timestamp. That's why you see "10000" 03897 below even though IAX2 timestamps are in milliseconds. 03898 The use of a moving average avoids offset moving too radically. 03899 Generally, "adjust" roams back and forth around 0, with offset hardly 03900 changing at all. But if a consistent different starts to develop it 03901 will be eliminated over the course of 10 frames (200-300msecs) 03902 */ 03903 adjust = (ms - p->nextpred); 03904 if (adjust < 0) 03905 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03906 else if (adjust > 0) 03907 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03908 03909 if (!p->nextpred) { 03910 p->nextpred = ms; /*f->samples / 8;*/ 03911 if (p->nextpred <= p->lastsent) 03912 p->nextpred = p->lastsent + 3; 03913 } 03914 ms = p->nextpred; 03915 } else { 03916 /* in this case, just use the actual 03917 * time, since we're either way off 03918 * (shouldn't happen), or we're ending a 03919 * silent period -- and seed the next 03920 * predicted time. Also, round ms to the 03921 * next multiple of frame size (so our 03922 * silent periods are multiples of 03923 * frame size too) */ 03924 03925 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03926 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03927 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03928 03929 if (f->samples >= 8) /* check to make sure we dont core dump */ 03930 { 03931 int diff = ms % (f->samples / 8); 03932 if (diff) 03933 ms += f->samples/8 - diff; 03934 } 03935 03936 p->nextpred = ms; 03937 p->notsilenttx = 1; 03938 } 03939 } else if ( f->frametype == AST_FRAME_VIDEO ) { 03940 /* 03941 * IAX2 draft 03 says that timestamps MUST be in order. 03942 * It does not say anything about several frames having the same timestamp 03943 * When transporting video, we can have a frame that spans multiple iax packets 03944 * (so called slices), so it would make sense to use the same timestamp for all of 03945 * them 03946 * We do want to make sure that frames don't go backwards though 03947 */ 03948 if ( (unsigned int)ms < p->lastsent ) 03949 ms = p->lastsent; 03950 } else { 03951 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03952 it's a genuine frame */ 03953 if (genuine) { 03954 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03955 if (ms <= p->lastsent) 03956 ms = p->lastsent + 3; 03957 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03958 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03959 ms = p->lastsent + 3; 03960 } 03961 } 03962 } 03963 p->lastsent = ms; 03964 if (voice) 03965 p->nextpred = p->nextpred + f->samples / 8; 03966 return ms; 03967 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3796 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().
03797 { 03798 unsigned long int mssincetx; /* unsigned to handle overflows */ 03799 long int ms, pred; 03800 03801 tpeer->trunkact = *tv; 03802 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03803 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03804 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03805 tpeer->txtrunktime = *tv; 03806 tpeer->lastsent = 999999; 03807 } 03808 /* Update last transmit time now */ 03809 tpeer->lasttxtime = *tv; 03810 03811 /* Calculate ms offset */ 03812 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03813 /* Predict from last value */ 03814 pred = tpeer->lastsent + sampms; 03815 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03816 ms = pred; 03817 03818 /* We never send the same timestamp twice, so fudge a little if we must */ 03819 if (ms == tpeer->lastsent) 03820 ms = tpeer->lastsent + 1; 03821 tpeer->lastsent = ms; 03822 return ms; 03823 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5080 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, 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, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, cid_name, cid_num, iax2_context::context, iax2_user::contexts, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, 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, ies, 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, realtime_user(), secret, user_unref(), users, ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
05081 { 05082 /* Start pessimistic */ 05083 int res = -1; 05084 int version = 2; 05085 struct iax2_user *user = NULL, *best = NULL; 05086 int bestscore = 0; 05087 int gotcapability = 0; 05088 struct ast_variable *v = NULL, *tmpvar = NULL; 05089 struct ao2_iterator i; 05090 05091 if (!iaxs[callno]) 05092 return res; 05093 if (ies->called_number) 05094 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05095 if (ies->calling_number) { 05096 ast_shrink_phone_number(ies->calling_number); 05097 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05098 } 05099 if (ies->calling_name) 05100 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05101 if (ies->calling_ani) 05102 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05103 if (ies->dnid) 05104 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05105 if (ies->rdnis) 05106 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05107 if (ies->called_context) 05108 ast_string_field_set(iaxs[callno], context, ies->called_context); 05109 if (ies->language) 05110 ast_string_field_set(iaxs[callno], language, ies->language); 05111 if (ies->username) 05112 ast_string_field_set(iaxs[callno], username, ies->username); 05113 if (ies->calling_ton > -1) 05114 iaxs[callno]->calling_ton = ies->calling_ton; 05115 if (ies->calling_tns > -1) 05116 iaxs[callno]->calling_tns = ies->calling_tns; 05117 if (ies->calling_pres > -1) 05118 iaxs[callno]->calling_pres = ies->calling_pres; 05119 if (ies->format) 05120 iaxs[callno]->peerformat = ies->format; 05121 if (ies->adsicpe) 05122 iaxs[callno]->peeradsicpe = ies->adsicpe; 05123 if (ies->capability) { 05124 gotcapability = 1; 05125 iaxs[callno]->peercapability = ies->capability; 05126 } 05127 if (ies->version) 05128 version = ies->version; 05129 05130 /* Use provided preferences until told otherwise for actual preferences */ 05131 if(ies->codec_prefs) { 05132 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05133 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05134 } 05135 05136 if (!gotcapability) 05137 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05138 if (version > IAX_PROTO_VERSION) { 05139 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05140 ast_inet_ntoa(sin->sin_addr), version); 05141 return res; 05142 } 05143 /* Search the userlist for a compatible entry, and fill in the rest */ 05144 i = ao2_iterator_init(users, 0); 05145 while ((user = ao2_iterator_next(&i))) { 05146 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05147 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05148 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05149 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05150 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05151 if (!ast_strlen_zero(iaxs[callno]->username)) { 05152 /* Exact match, stop right now. */ 05153 if (best) 05154 user_unref(best); 05155 best = user; 05156 break; 05157 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05158 /* No required authentication */ 05159 if (user->ha) { 05160 /* There was host authentication and we passed, bonus! */ 05161 if (bestscore < 4) { 05162 bestscore = 4; 05163 if (best) 05164 user_unref(best); 05165 best = user; 05166 continue; 05167 } 05168 } else { 05169 /* No host access, but no secret, either, not bad */ 05170 if (bestscore < 3) { 05171 bestscore = 3; 05172 if (best) 05173 user_unref(best); 05174 best = user; 05175 continue; 05176 } 05177 } 05178 } else { 05179 if (user->ha) { 05180 /* Authentication, but host access too, eh, it's something.. */ 05181 if (bestscore < 2) { 05182 bestscore = 2; 05183 if (best) 05184 user_unref(best); 05185 best = user; 05186 continue; 05187 } 05188 } else { 05189 /* Authentication and no host access... This is our baseline */ 05190 if (bestscore < 1) { 05191 bestscore = 1; 05192 if (best) 05193 user_unref(best); 05194 best = user; 05195 continue; 05196 } 05197 } 05198 } 05199 } 05200 user_unref(user); 05201 } 05202 user = best; 05203 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05204 user = realtime_user(iaxs[callno]->username, sin); 05205 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05206 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05207 user = user_unref(user); 05208 } 05209 } 05210 if (user) { 05211 /* We found our match (use the first) */ 05212 /* copy vars */ 05213 for (v = user->vars ; v ; v = v->next) { 05214 if((tmpvar = ast_variable_new(v->name, v->value))) { 05215 tmpvar->next = iaxs[callno]->vars; 05216 iaxs[callno]->vars = tmpvar; 05217 } 05218 } 05219 /* If a max AUTHREQ restriction is in place, activate it */ 05220 if (user->maxauthreq > 0) 05221 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05222 iaxs[callno]->prefs = user->prefs; 05223 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05224 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05225 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05226 iaxs[callno]->encmethods = user->encmethods; 05227 /* Store the requested username if not specified */ 05228 if (ast_strlen_zero(iaxs[callno]->username)) 05229 ast_string_field_set(iaxs[callno], username, user->name); 05230 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05231 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05232 iaxs[callno]->capability = user->capability; 05233 /* And use the default context */ 05234 if (ast_strlen_zero(iaxs[callno]->context)) { 05235 if (user->contexts) 05236 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05237 else 05238 ast_string_field_set(iaxs[callno], context, context); 05239 } 05240 /* And any input keys */ 05241 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05242 /* And the permitted authentication methods */ 05243 iaxs[callno]->authmethods = user->authmethods; 05244 iaxs[callno]->adsi = user->adsi; 05245 /* If they have callerid, override the given caller id. Always store the ANI */ 05246 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05247 if (ast_test_flag(user, IAX_HASCALLERID)) { 05248 iaxs[callno]->calling_tns = 0; 05249 iaxs[callno]->calling_ton = 0; 05250 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05251 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05252 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05253 } 05254 if (ast_strlen_zero(iaxs[callno]->ani)) 05255 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05256 } else { 05257 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05258 } 05259 if (!ast_strlen_zero(user->accountcode)) 05260 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05261 if (!ast_strlen_zero(user->mohinterpret)) 05262 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05263 if (!ast_strlen_zero(user->mohsuggest)) 05264 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05265 if (user->amaflags) 05266 iaxs[callno]->amaflags = user->amaflags; 05267 if (!ast_strlen_zero(user->language)) 05268 ast_string_field_set(iaxs[callno], language, user->language); 05269 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05270 /* Keep this check last */ 05271 if (!ast_strlen_zero(user->dbsecret)) { 05272 char *family, *key=NULL; 05273 char buf[80]; 05274 family = ast_strdupa(user->dbsecret); 05275 key = strchr(family, '/'); 05276 if (key) { 05277 *key = '\0'; 05278 key++; 05279 } 05280 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05281 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05282 else 05283 ast_string_field_set(iaxs[callno], secret, buf); 05284 } else 05285 ast_string_field_set(iaxs[callno], secret, user->secret); 05286 res = 0; 05287 user = user_unref(user); 05288 } 05289 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05290 return res; 05291 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6766 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06767 { 06768 unsigned int ourver; 06769 char rsi[80]; 06770 snprintf(rsi, sizeof(rsi), "si-%s", si); 06771 if (iax_provision_version(&ourver, rsi, 1)) 06772 return 0; 06773 if (option_debug) 06774 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06775 if (ourver != ver) 06776 iax2_provision(sin, sockfd, NULL, rsi, 1); 06777 return 0; 06778 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9173 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09174 { 09175 int sd; 09176 int res; 09177 09178 sd = socket(AF_INET, SOCK_DGRAM, 0); 09179 if (sd < 0) { 09180 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09181 return -1; 09182 } 09183 09184 res = bind(sd, sa, salen); 09185 if (res < 0) { 09186 if (option_debug) 09187 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09188 close(sd); 09189 return 1; 09190 } 09191 09192 close(sd); 09193 return 0; 09194 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5770 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
05771 { 05772 char exten[256] = ""; 05773 int status = CACHE_FLAG_UNKNOWN; 05774 int expiry = iaxdefaultdpcache; 05775 int x; 05776 int matchmore = 0; 05777 struct iax2_dpcache *dp, *prev; 05778 05779 if (ies->called_number) 05780 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05781 05782 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05783 status = CACHE_FLAG_EXISTS; 05784 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05785 status = CACHE_FLAG_CANEXIST; 05786 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05787 status = CACHE_FLAG_NONEXISTENT; 05788 05789 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05790 /* Don't really do anything with this */ 05791 } 05792 if (ies->refresh) 05793 expiry = ies->refresh; 05794 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05795 matchmore = CACHE_FLAG_MATCHMORE; 05796 ast_mutex_lock(&dpcache_lock); 05797 prev = NULL; 05798 dp = pvt->dpentries; 05799 while(dp) { 05800 if (!strcmp(dp->exten, exten)) { 05801 /* Let them go */ 05802 if (prev) 05803 prev->peer = dp->peer; 05804 else 05805 pvt->dpentries = dp->peer; 05806 dp->peer = NULL; 05807 dp->callno = 0; 05808 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05809 if (dp->flags & CACHE_FLAG_PENDING) { 05810 dp->flags &= ~CACHE_FLAG_PENDING; 05811 dp->flags |= status; 05812 dp->flags |= matchmore; 05813 } 05814 /* Wake up waiters */ 05815 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05816 if (dp->waiters[x] > -1) 05817 write(dp->waiters[x], "asdf", 4); 05818 } 05819 prev = dp; 05820 dp = dp->peer; 05821 } 05822 ast_mutex_unlock(&dpcache_lock); 05823 return 0; 05824 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2389 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02390 { 02391 int which = 0; 02392 struct iax2_peer *peer; 02393 char *res = NULL; 02394 int wordlen = strlen(word); 02395 struct ao2_iterator i; 02396 02397 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02398 if (pos != 3) 02399 return NULL; 02400 02401 i = ao2_iterator_init(peers, 0); 02402 while ((peer = ao2_iterator_next(&i))) { 02403 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02404 res = ast_strdup(peer->name); 02405 peer_unref(peer); 02406 break; 02407 } 02408 peer_unref(peer); 02409 } 02410 02411 return res; 02412 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5826 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, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), 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().
05827 { 05828 int peercallno = 0; 05829 struct chan_iax2_pvt *pvt = iaxs[callno]; 05830 struct iax_frame *cur; 05831 jb_frame frame; 05832 05833 if (ies->callno) 05834 peercallno = ies->callno; 05835 05836 if (peercallno < 1) { 05837 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05838 return -1; 05839 } 05840 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05841 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05842 /* Reset sequence numbers */ 05843 pvt->oseqno = 0; 05844 pvt->rseqno = 0; 05845 pvt->iseqno = 0; 05846 pvt->aseqno = 0; 05847 05848 if (pvt->peercallno) { 05849 remove_by_peercallno(pvt); 05850 } 05851 pvt->peercallno = peercallno; 05852 store_by_peercallno(pvt); 05853 05854 pvt->transferring = TRANSFER_NONE; 05855 pvt->svoiceformat = -1; 05856 pvt->voiceformat = 0; 05857 pvt->svideoformat = -1; 05858 pvt->videoformat = 0; 05859 pvt->transfercallno = -1; 05860 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05861 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05862 /* reset jitterbuffer */ 05863 while(jb_getall(pvt->jb,&frame) == JB_OK) 05864 iax2_frame_free(frame.data); 05865 jb_reset(pvt->jb); 05866 pvt->lag = 0; 05867 pvt->last = 0; 05868 pvt->lastsent = 0; 05869 pvt->nextpred = 0; 05870 pvt->pingtime = DEFAULT_RETRY_TIME; 05871 AST_LIST_LOCK(&iaxq.queue); 05872 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05873 /* We must cancel any packets that would have been transmitted 05874 because now we're talking to someone new. It's okay, they 05875 were transmitted to someone that didn't care anyway. */ 05876 if (callno == cur->callno) 05877 cur->retries = -1; 05878 } 05879 AST_LIST_UNLOCK(&iaxq.queue); 05880 return 0; 05881 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1061 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01062 { 01063 int x; 01064 int power=-1; 01065 /* If it's 128 or smaller, just return it */ 01066 if (subclass < IAX_FLAG_SC_LOG) 01067 return subclass; 01068 /* Otherwise find its power */ 01069 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01070 if (subclass & (1 << x)) { 01071 if (power > -1) { 01072 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01073 return 0; 01074 } else 01075 power = x; 01076 } 01077 } 01078 return power | IAX_FLAG_SC_LOG; 01079 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6780 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().
06781 { 06782 jb_info stats; 06783 jb_getinfo(pvt->jb, &stats); 06784 06785 memset(iep, 0, sizeof(*iep)); 06786 06787 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06788 if(stats.frames_in == 0) stats.frames_in = 1; 06789 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06790 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06791 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06792 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06793 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06794 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3006 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), 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, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, 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.
03007 { 03008 struct ast_hostent ahp; 03009 struct hostent *hp; 03010 struct iax2_peer *peer; 03011 int res = -1; 03012 struct ast_codec_pref ourprefs; 03013 03014 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03015 cai->sockfd = defaultsockfd; 03016 cai->maxtime = 0; 03017 sin->sin_family = AF_INET; 03018 03019 if (!(peer = find_peer(peername, 1))) { 03020 cai->found = 0; 03021 03022 hp = ast_gethostbyname(peername, &ahp); 03023 if (hp) { 03024 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03025 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03026 /* use global iax prefs for unknown peer/user */ 03027 /* But move the calling channel's native codec to the top of the preference list */ 03028 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03029 if (c) 03030 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03031 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03032 return 0; 03033 } else { 03034 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03035 return -1; 03036 } 03037 } 03038 03039 cai->found = 1; 03040 03041 /* if the peer has no address (current or default), return failure */ 03042 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03043 goto return_unref; 03044 03045 /* if the peer is being monitored and is currently unreachable, return failure */ 03046 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03047 goto return_unref; 03048 03049 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03050 cai->maxtime = peer->maxms; 03051 cai->capability = peer->capability; 03052 cai->encmethods = peer->encmethods; 03053 cai->sockfd = peer->sockfd; 03054 cai->adsi = peer->adsi; 03055 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03056 /* Move the calling channel's native codec to the top of the preference list */ 03057 if (c) { 03058 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03059 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03060 } 03061 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03062 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03063 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03064 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03065 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03066 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03067 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03068 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03069 if (ast_strlen_zero(peer->dbsecret)) { 03070 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03071 } else { 03072 char *family; 03073 char *key = NULL; 03074 03075 family = ast_strdupa(peer->dbsecret); 03076 key = strchr(family, '/'); 03077 if (key) 03078 *key++ = '\0'; 03079 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03080 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03081 goto return_unref; 03082 } 03083 } 03084 03085 if (peer->addr.sin_addr.s_addr) { 03086 sin->sin_addr = peer->addr.sin_addr; 03087 sin->sin_port = peer->addr.sin_port; 03088 } else { 03089 sin->sin_addr = peer->defaddr.sin_addr; 03090 sin->sin_port = peer->defaddr.sin_port; 03091 } 03092 03093 res = 0; 03094 03095 return_unref: 03096 peer_unref(peer); 03097 03098 return res; 03099 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4155 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, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
04156 { 04157 int padding; 04158 unsigned char *workspace; 04159 04160 workspace = alloca(*datalen); 04161 memset(f, 0, sizeof(*f)); 04162 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04163 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04164 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04165 return -1; 04166 /* Decrypt */ 04167 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04168 04169 padding = 16 + (workspace[15] & 0xf); 04170 if (option_debug && iaxdebug) 04171 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04172 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04173 return -1; 04174 04175 *datalen -= padding; 04176 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04177 f->frametype = fh->type; 04178 if (f->frametype == AST_FRAME_VIDEO) { 04179 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04180 } else { 04181 f->subclass = uncompress_subclass(fh->csub); 04182 } 04183 } else { 04184 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04185 if (option_debug && iaxdebug) 04186 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04187 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04188 return -1; 04189 /* Decrypt */ 04190 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04191 padding = 16 + (workspace[15] & 0x0f); 04192 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04193 return -1; 04194 *datalen -= padding; 04195 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04196 } 04197 return 0; 04198 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4241 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
04242 { 04243 int res=-1; 04244 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04245 /* Search for possible keys, given secrets */ 04246 struct MD5Context md5; 04247 unsigned char digest[16]; 04248 char *tmppw, *stringp; 04249 04250 tmppw = ast_strdupa(iaxs[callno]->secret); 04251 stringp = tmppw; 04252 while ((tmppw = strsep(&stringp, ";"))) { 04253 MD5Init(&md5); 04254 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04255 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04256 MD5Final(digest, &md5); 04257 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04258 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04259 if (!res) { 04260 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04261 break; 04262 } 04263 } 04264 } else 04265 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04266 return res; 04267 }
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 6842 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().
06843 { 06844 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06845 struct ast_iax2_full_hdr *fh, *cur_fh; 06846 06847 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06848 return; 06849 06850 pkt_buf->len = from_here->buf_len; 06851 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06852 06853 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06854 ast_mutex_lock(&to_here->lock); 06855 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06856 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06857 if (fh->oseqno < cur_fh->oseqno) { 06858 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06859 break; 06860 } 06861 } 06862 AST_LIST_TRAVERSE_SAFE_END 06863 06864 if (!cur_pkt_buf) 06865 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06866 06867 ast_mutex_unlock(&to_here->lock); 06868 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9765 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, sched, user_delme_cb(), and users.
09766 { 09767 struct iax2_registry *reg; 09768 09769 ao2_callback(users, 0, user_delme_cb, NULL); 09770 09771 AST_LIST_LOCK(®istrations); 09772 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09773 ast_sched_del(sched, reg->expire); 09774 if (reg->callno) { 09775 ast_mutex_lock(&iaxsl[reg->callno]); 09776 if (iaxs[reg->callno]) { 09777 iaxs[reg->callno]->reg = NULL; 09778 iax2_destroy(reg->callno); 09779 } 09780 ast_mutex_unlock(&iaxsl[reg->callno]); 09781 } 09782 if (reg->dnsmgr) 09783 ast_dnsmgr_release(reg->dnsmgr); 09784 free(reg); 09785 } 09786 AST_LIST_UNLOCK(®istrations); 09787 09788 ao2_callback(peers, 0, peer_delme_cb, NULL); 09789 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1740 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01741 { 01742 /* Close firmware */ 01743 if (cur->fwh) { 01744 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01745 } 01746 close(cur->fd); 01747 free(cur); 01748 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6614 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06615 { 06616 unsigned short dpstatus = 0; 06617 struct iax_ie_data ied1; 06618 int mm; 06619 06620 memset(&ied1, 0, sizeof(ied1)); 06621 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06622 /* Must be started */ 06623 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06624 dpstatus = IAX_DPSTATUS_EXISTS; 06625 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06626 dpstatus = IAX_DPSTATUS_CANEXIST; 06627 } else { 06628 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06629 } 06630 if (ast_ignore_pattern(context, callednum)) 06631 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06632 if (mm) 06633 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06634 if (!skiplock) 06635 ast_mutex_lock(&iaxsl[callno]); 06636 if (iaxs[callno]) { 06637 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06638 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06639 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06640 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06641 } 06642 if (!skiplock) 06643 ast_mutex_unlock(&iaxsl[callno]); 06644 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6646 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().
06647 { 06648 /* Look up for dpreq */ 06649 struct dpreq_data *dpr = data; 06650 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06651 if (dpr->callerid) 06652 free(dpr->callerid); 06653 free(dpr); 06654 return NULL; 06655 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4200 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
04201 { 04202 int padding; 04203 unsigned char *workspace; 04204 workspace = alloca(*datalen + 32); 04205 if (!workspace) 04206 return -1; 04207 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04208 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04209 if (option_debug && iaxdebug) 04210 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04211 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04212 padding = 16 + (padding & 0xf); 04213 memcpy(workspace, poo, padding); 04214 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04215 workspace[15] &= 0xf0; 04216 workspace[15] |= (padding & 0xf); 04217 if (option_debug && iaxdebug) 04218 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]); 04219 *datalen += padding; 04220 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04221 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04222 memcpy(poo, workspace + *datalen - 32, 32); 04223 } else { 04224 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04225 if (option_debug && iaxdebug) 04226 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04227 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04228 padding = 16 + (padding & 0xf); 04229 memcpy(workspace, poo, padding); 04230 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04231 workspace[15] &= 0xf0; 04232 workspace[15] |= (padding & 0x0f); 04233 *datalen += padding; 04234 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04235 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04236 memcpy(poo, workspace + *datalen - 32, 32); 04237 } 04238 return 0; 04239 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6063 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
06064 { 06065 #ifdef SCHED_MULTITHREADED 06066 if (schedule_action(__expire_registry, data)) 06067 #endif 06068 __expire_registry(data); 06069 return 0; 06070 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 10323 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, 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().
10324 { 10325 struct iax2_dpcache *dp, *prev = NULL, *next; 10326 struct timeval tv; 10327 int x; 10328 int com[2]; 10329 int timeout; 10330 int old=0; 10331 int outfd; 10332 int abort; 10333 int callno; 10334 struct ast_channel *c; 10335 struct ast_frame *f; 10336 gettimeofday(&tv, NULL); 10337 dp = dpcache; 10338 while(dp) { 10339 next = dp->next; 10340 /* Expire old caches */ 10341 if (ast_tvcmp(tv, dp->expiry) > 0) { 10342 /* It's expired, let it disappear */ 10343 if (prev) 10344 prev->next = dp->next; 10345 else 10346 dpcache = dp->next; 10347 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10348 /* Free memory and go again */ 10349 free(dp); 10350 } else { 10351 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); 10352 } 10353 dp = next; 10354 continue; 10355 } 10356 /* We found an entry that matches us! */ 10357 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10358 break; 10359 prev = dp; 10360 dp = next; 10361 } 10362 if (!dp) { 10363 /* No matching entry. Create a new one. */ 10364 /* First, can we make a callno? */ 10365 callno = cache_get_callno_locked(data); 10366 if (callno < 0) { 10367 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10368 return NULL; 10369 } 10370 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10371 ast_mutex_unlock(&iaxsl[callno]); 10372 return NULL; 10373 } 10374 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10375 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10376 gettimeofday(&dp->expiry, NULL); 10377 dp->orig = dp->expiry; 10378 /* Expires in 30 mins by default */ 10379 dp->expiry.tv_sec += iaxdefaultdpcache; 10380 dp->next = dpcache; 10381 dp->flags = CACHE_FLAG_PENDING; 10382 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10383 dp->waiters[x] = -1; 10384 dpcache = dp; 10385 dp->peer = iaxs[callno]->dpentries; 10386 iaxs[callno]->dpentries = dp; 10387 /* Send the request if we're already up */ 10388 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10389 iax2_dprequest(dp, callno); 10390 ast_mutex_unlock(&iaxsl[callno]); 10391 } 10392 /* By here we must have a dp */ 10393 if (dp->flags & CACHE_FLAG_PENDING) { 10394 /* Okay, here it starts to get nasty. We need a pipe now to wait 10395 for a reply to come back so long as it's pending */ 10396 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10397 /* Find an empty slot */ 10398 if (dp->waiters[x] < 0) 10399 break; 10400 } 10401 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10402 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10403 return NULL; 10404 } 10405 if (pipe(com)) { 10406 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10407 return NULL; 10408 } 10409 dp->waiters[x] = com[1]; 10410 /* Okay, now we wait */ 10411 timeout = iaxdefaulttimeout * 1000; 10412 /* Temporarily unlock */ 10413 ast_mutex_unlock(&dpcache_lock); 10414 /* Defer any dtmf */ 10415 if (chan) 10416 old = ast_channel_defer_dtmf(chan); 10417 abort = 0; 10418 while(timeout) { 10419 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10420 if (outfd > -1) { 10421 break; 10422 } 10423 if (c) { 10424 f = ast_read(c); 10425 if (f) 10426 ast_frfree(f); 10427 else { 10428 /* Got hung up on, abort! */ 10429 break; 10430 abort = 1; 10431 } 10432 } 10433 } 10434 if (!timeout) { 10435 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10436 } 10437 ast_mutex_lock(&dpcache_lock); 10438 dp->waiters[x] = -1; 10439 close(com[1]); 10440 close(com[0]); 10441 if (abort) { 10442 /* Don't interpret anything, just abort. Not sure what th epoint 10443 of undeferring dtmf on a hung up channel is but hey whatever */ 10444 if (!old && chan) 10445 ast_channel_undefer_dtmf(chan); 10446 return NULL; 10447 } 10448 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10449 /* Now to do non-independent analysis the results of our wait */ 10450 if (dp->flags & CACHE_FLAG_PENDING) { 10451 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10452 pending. Don't let it take as long to timeout. */ 10453 dp->flags &= ~CACHE_FLAG_PENDING; 10454 dp->flags |= CACHE_FLAG_TIMEOUT; 10455 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10456 systems without leaving it unavailable once the server comes back online */ 10457 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10458 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10459 if (dp->waiters[x] > -1) 10460 write(dp->waiters[x], "asdf", 4); 10461 } 10462 } 10463 /* Our caller will obtain the rest */ 10464 if (!old && chan) 10465 ast_channel_undefer_dtmf(chan); 10466 } 10467 return dp; 10468 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1640 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01640 { 01641 01642 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01643 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1645 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01645 { 01646 01647 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01648 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 906 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, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00907 { 00908 pthread_attr_t attr; 00909 struct iax2_thread *thread = NULL; 00910 00911 /* Pop the head of the list off */ 00912 AST_LIST_LOCK(&idle_list); 00913 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00914 AST_LIST_UNLOCK(&idle_list); 00915 00916 /* If no idle thread is available from the regular list, try dynamic */ 00917 if (thread == NULL) { 00918 AST_LIST_LOCK(&dynamic_list); 00919 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00920 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00921 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00922 /* We need to MAKE a thread! */ 00923 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00924 thread->threadnum = iaxdynamicthreadcount; 00925 thread->type = IAX_TYPE_DYNAMIC; 00926 ast_mutex_init(&thread->lock); 00927 ast_cond_init(&thread->cond, NULL); 00928 pthread_attr_init(&attr); 00929 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00930 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00931 free(thread); 00932 thread = NULL; 00933 } else { 00934 /* All went well and the thread is up, so increment our count */ 00935 iaxdynamicthreadcount++; 00936 00937 /* Wait for the thread to be ready before returning it to the caller */ 00938 while (!thread->ready_for_signal) 00939 usleep(1); 00940 } 00941 } 00942 } 00943 AST_LIST_UNLOCK(&dynamic_list); 00944 } 00945 00946 /* this thread is not processing a full frame (since it is idle), 00947 so ensure that the field for the full frame call number is empty */ 00948 if (thread) 00949 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00950 00951 return thread; 00952 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1139 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01140 { 01141 struct iax2_peer *peer = NULL; 01142 struct iax2_peer tmp_peer = { 01143 .name = name, 01144 }; 01145 01146 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01147 01148 /* Now go for realtime if applicable */ 01149 if(!peer && realtime) 01150 peer = realtime_peer(name, NULL); 01151 01152 return peer; 01153 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 4009 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
04010 { 04011 struct iax2_trunk_peer *tpeer; 04012 04013 /* Finds and locks trunk peer */ 04014 ast_mutex_lock(&tpeerlock); 04015 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04016 /* We don't lock here because tpeer->addr *never* changes */ 04017 if (!inaddrcmp(&tpeer->addr, sin)) { 04018 ast_mutex_lock(&tpeer->lock); 04019 break; 04020 } 04021 } 04022 if (!tpeer) { 04023 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04024 ast_mutex_init(&tpeer->lock); 04025 tpeer->lastsent = 9999; 04026 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04027 tpeer->trunkact = ast_tvnow(); 04028 ast_mutex_lock(&tpeer->lock); 04029 tpeer->next = tpeers; 04030 tpeer->sockfd = fd; 04031 tpeers = tpeer; 04032 #ifdef SO_NO_CHECK 04033 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04034 #endif 04035 if (option_debug) 04036 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04037 } 04038 } 04039 ast_mutex_unlock(&tpeerlock); 04040 return tpeer; 04041 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3825 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03826 { 03827 long ms; /* NOT unsigned */ 03828 if (ast_tvzero(iaxs[callno]->rxcore)) { 03829 /* Initialize rxcore time if appropriate */ 03830 gettimeofday(&iaxs[callno]->rxcore, NULL); 03831 /* Round to nearest 20ms so traces look pretty */ 03832 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03833 } 03834 /* Calculate difference between trunk and channel */ 03835 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03836 /* Return as the sum of trunk time and the difference between trunk and real time */ 03837 return ms + ts; 03838 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8932 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08933 { 08934 struct iax2_context *conl; 08935 while(con) { 08936 conl = con; 08937 con = con->next; 08938 free(conl); 08939 } 08940 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10592 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::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.
10593 { 10594 struct iax2_peer *peer; 10595 char *peername, *colname; 10596 10597 peername = ast_strdupa(data); 10598 10599 /* if our channel, return the IP address of the endpoint of current channel */ 10600 if (!strcmp(peername,"CURRENTCHANNEL")) { 10601 unsigned short callno; 10602 if (chan->tech != &iax2_tech) 10603 return -1; 10604 callno = PTR_TO_CALLNO(chan->tech_pvt); 10605 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10606 return 0; 10607 } 10608 10609 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10610 *colname++ = '\0'; 10611 else if ((colname = strchr(peername, '|'))) 10612 *colname++ = '\0'; 10613 else 10614 colname = "ip"; 10615 10616 if (!(peer = find_peer(peername, 1))) 10617 return -1; 10618 10619 if (!strcasecmp(colname, "ip")) { 10620 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10621 } else if (!strcasecmp(colname, "status")) { 10622 peer_status(peer, buf, len); 10623 } else if (!strcasecmp(colname, "mailbox")) { 10624 ast_copy_string(buf, peer->mailbox, len); 10625 } else if (!strcasecmp(colname, "context")) { 10626 ast_copy_string(buf, peer->context, len); 10627 } else if (!strcasecmp(colname, "expire")) { 10628 snprintf(buf, len, "%d", peer->expire); 10629 } else if (!strcasecmp(colname, "dynamic")) { 10630 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10631 } else if (!strcasecmp(colname, "callerid_name")) { 10632 ast_copy_string(buf, peer->cid_name, len); 10633 } else if (!strcasecmp(colname, "callerid_num")) { 10634 ast_copy_string(buf, peer->cid_num, len); 10635 } else if (!strcasecmp(colname, "codecs")) { 10636 ast_getformatname_multiple(buf, len -1, peer->capability); 10637 } else if (!strncasecmp(colname, "codec[", 6)) { 10638 char *codecnum, *ptr; 10639 int index = 0, codec = 0; 10640 10641 codecnum = strchr(colname, '['); 10642 *codecnum = '\0'; 10643 codecnum++; 10644 if ((ptr = strchr(codecnum, ']'))) { 10645 *ptr = '\0'; 10646 } 10647 index = atoi(codecnum); 10648 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10649 ast_copy_string(buf, ast_getformatname(codec), len); 10650 } 10651 } 10652 10653 peer_unref(peer); 10654 10655 return 0; 10656 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9157 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09158 { 09159 int methods = 0; 09160 if (strstr(value, "rsa")) 09161 methods |= IAX_AUTH_RSA; 09162 if (strstr(value, "md5")) 09163 methods |= IAX_AUTH_MD5; 09164 if (strstr(value, "plaintext")) 09165 methods |= IAX_AUTH_PLAINTEXT; 09166 return methods; 09167 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1021 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01022 { 01023 int e; 01024 if (!strcasecmp(s, "aes128")) 01025 e = IAX_ENCRYPT_AES128; 01026 else if (ast_true(s)) 01027 e = IAX_ENCRYPT_AES128; 01028 else 01029 e = 0; 01030 return e; 01031 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2620 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02621 { 02622 #ifdef SCHED_MULTITHREADED 02623 if (schedule_action(__get_from_jb, data)) 02624 #endif 02625 __get_from_jb(data); 02626 return 0; 02627 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6812 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), socket_process(), and thread.
06813 { 06814 struct iax2_pkt_buf *pkt_buf; 06815 06816 ast_mutex_lock(&thread->lock); 06817 06818 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06819 ast_mutex_unlock(&thread->lock); 06820 06821 thread->buf = pkt_buf->buf; 06822 thread->buf_len = pkt_buf->len; 06823 thread->buf_size = pkt_buf->len + 1; 06824 06825 socket_process(thread); 06826 06827 thread->buf = NULL; 06828 ast_free(pkt_buf); 06829 06830 ast_mutex_lock(&thread->lock); 06831 } 06832 06833 ast_mutex_unlock(&thread->lock); 06834 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2028 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().
02029 { 02030 /* XXX Ideally we should figure out why an error occured and then abort those 02031 rather than continuing to try. Unfortunately, the published interface does 02032 not seem to work XXX */ 02033 #if 0 02034 struct sockaddr_in *sin; 02035 int res; 02036 struct msghdr m; 02037 struct sock_extended_err e; 02038 m.msg_name = NULL; 02039 m.msg_namelen = 0; 02040 m.msg_iov = NULL; 02041 m.msg_control = &e; 02042 m.msg_controllen = sizeof(e); 02043 m.msg_flags = 0; 02044 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02045 if (res < 0) 02046 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02047 else { 02048 if (m.msg_controllen) { 02049 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02050 if (sin) 02051 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02052 else 02053 ast_log(LOG_WARNING, "No address detected??\n"); 02054 } else { 02055 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02056 } 02057 } 02058 #endif 02059 return 0; 02060 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5884 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05885 { 05886 struct iax2_registry *reg; 05887 /* Start pessimistic */ 05888 char peer[256] = ""; 05889 char msgstatus[60]; 05890 int refresh = 60; 05891 char ourip[256] = "<Unspecified>"; 05892 struct sockaddr_in oldus; 05893 struct sockaddr_in us; 05894 int oldmsgs; 05895 05896 memset(&us, 0, sizeof(us)); 05897 if (ies->apparent_addr) 05898 bcopy(ies->apparent_addr, &us, sizeof(us)); 05899 if (ies->username) 05900 ast_copy_string(peer, ies->username, sizeof(peer)); 05901 if (ies->refresh) 05902 refresh = ies->refresh; 05903 if (ies->calling_number) { 05904 /* We don't do anything with it really, but maybe we should */ 05905 } 05906 reg = iaxs[callno]->reg; 05907 if (!reg) { 05908 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05909 return -1; 05910 } 05911 memcpy(&oldus, ®->us, sizeof(oldus)); 05912 oldmsgs = reg->messages; 05913 if (inaddrcmp(®->addr, sin)) { 05914 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05915 return -1; 05916 } 05917 memcpy(®->us, &us, sizeof(reg->us)); 05918 if (ies->msgcount >= 0) 05919 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05920 /* always refresh the registration at the interval requested by the server 05921 we are registering to 05922 */ 05923 reg->refresh = refresh; 05924 AST_SCHED_DEL(sched, reg->expire); 05925 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05926 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05927 if (option_verbose > 2) { 05928 if (reg->messages > 255) 05929 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05930 else if (reg->messages > 1) 05931 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05932 else if (reg->messages > 0) 05933 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05934 else 05935 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05936 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05937 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05938 } 05939 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05940 } 05941 reg->regstate = REG_STATE_REGISTERED; 05942 return 0; 05943 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3625 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03626 { 03627 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03628 if (option_debug) 03629 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03630 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03631 }
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 3475 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, tv, unlock_both(), and VERBOSE_PREFIX_3.
03476 { 03477 struct ast_channel *cs[3]; 03478 struct ast_channel *who, *other; 03479 int to = -1; 03480 int res = -1; 03481 int transferstarted=0; 03482 struct ast_frame *f; 03483 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03484 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03485 struct timeval waittimer = {0, 0}, tv; 03486 03487 lock_both(callno0, callno1); 03488 if (!iaxs[callno0] || !iaxs[callno1]) { 03489 unlock_both(callno0, callno1); 03490 return AST_BRIDGE_FAILED; 03491 } 03492 /* Put them in native bridge mode */ 03493 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03494 iaxs[callno0]->bridgecallno = callno1; 03495 iaxs[callno1]->bridgecallno = callno0; 03496 } 03497 unlock_both(callno0, callno1); 03498 03499 /* If not, try to bridge until we can execute a transfer, if we can */ 03500 cs[0] = c0; 03501 cs[1] = c1; 03502 for (/* ever */;;) { 03503 /* Check in case we got masqueraded into */ 03504 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03505 if (option_verbose > 2) 03506 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03507 /* Remove from native mode */ 03508 if (c0->tech == &iax2_tech) { 03509 ast_mutex_lock(&iaxsl[callno0]); 03510 iaxs[callno0]->bridgecallno = 0; 03511 ast_mutex_unlock(&iaxsl[callno0]); 03512 } 03513 if (c1->tech == &iax2_tech) { 03514 ast_mutex_lock(&iaxsl[callno1]); 03515 iaxs[callno1]->bridgecallno = 0; 03516 ast_mutex_unlock(&iaxsl[callno1]); 03517 } 03518 return AST_BRIDGE_FAILED_NOWARN; 03519 } 03520 if (c0->nativeformats != c1->nativeformats) { 03521 if (option_verbose > 2) { 03522 char buf0[255]; 03523 char buf1[255]; 03524 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03525 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03526 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03527 } 03528 /* Remove from native mode */ 03529 lock_both(callno0, callno1); 03530 if (iaxs[callno0]) 03531 iaxs[callno0]->bridgecallno = 0; 03532 if (iaxs[callno1]) 03533 iaxs[callno1]->bridgecallno = 0; 03534 unlock_both(callno0, callno1); 03535 return AST_BRIDGE_FAILED_NOWARN; 03536 } 03537 /* check if transfered and if we really want native bridging */ 03538 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03539 /* Try the transfer */ 03540 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03541 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03542 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03543 transferstarted = 1; 03544 } 03545 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03546 /* Call has been transferred. We're no longer involved */ 03547 gettimeofday(&tv, NULL); 03548 if (ast_tvzero(waittimer)) { 03549 waittimer = tv; 03550 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03551 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03552 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03553 *fo = NULL; 03554 *rc = c0; 03555 res = AST_BRIDGE_COMPLETE; 03556 break; 03557 } 03558 } 03559 to = 1000; 03560 who = ast_waitfor_n(cs, 2, &to); 03561 if (timeoutms > -1) { 03562 timeoutms -= (1000 - to); 03563 if (timeoutms < 0) 03564 timeoutms = 0; 03565 } 03566 if (!who) { 03567 if (!timeoutms) { 03568 res = AST_BRIDGE_RETRY; 03569 break; 03570 } 03571 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03572 res = AST_BRIDGE_FAILED; 03573 break; 03574 } 03575 continue; 03576 } 03577 f = ast_read(who); 03578 if (!f) { 03579 *fo = NULL; 03580 *rc = who; 03581 res = AST_BRIDGE_COMPLETE; 03582 break; 03583 } 03584 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03585 *fo = f; 03586 *rc = who; 03587 res = AST_BRIDGE_COMPLETE; 03588 break; 03589 } 03590 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03591 if ((f->frametype == AST_FRAME_VOICE) || 03592 (f->frametype == AST_FRAME_TEXT) || 03593 (f->frametype == AST_FRAME_VIDEO) || 03594 (f->frametype == AST_FRAME_IMAGE) || 03595 (f->frametype == AST_FRAME_DTMF)) { 03596 /* monitored dtmf take out of the bridge. 03597 * check if we monitor the specific source. 03598 */ 03599 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03600 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03601 *rc = who; 03602 *fo = f; 03603 res = AST_BRIDGE_COMPLETE; 03604 /* Remove from native mode */ 03605 break; 03606 } 03607 /* everything else goes to the other side */ 03608 ast_write(other, f); 03609 } 03610 ast_frfree(f); 03611 /* Swap who gets priority */ 03612 cs[2] = cs[0]; 03613 cs[0] = cs[1]; 03614 cs[1] = cs[2]; 03615 } 03616 lock_both(callno0, callno1); 03617 if(iaxs[callno0]) 03618 iaxs[callno0]->bridgecallno = 0; 03619 if(iaxs[callno1]) 03620 iaxs[callno1]->bridgecallno = 0; 03621 unlock_both(callno0, callno1); 03622 return res; 03623 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3220 of file chan_iax2.c.
References ast_channel::_state, 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(), 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, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, 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, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, and ast_channel::tech_pvt.
03221 { 03222 struct sockaddr_in sin; 03223 char *l=NULL, *n=NULL, *tmpstr; 03224 struct iax_ie_data ied; 03225 char *defaultrdest = "s"; 03226 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03227 struct parsed_dial_string pds; 03228 struct create_addr_info cai; 03229 03230 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03231 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03232 return -1; 03233 } 03234 03235 memset(&cai, 0, sizeof(cai)); 03236 cai.encmethods = iax2_encryption; 03237 03238 memset(&pds, 0, sizeof(pds)); 03239 tmpstr = ast_strdupa(dest); 03240 parse_dial_string(tmpstr, &pds); 03241 03242 if (ast_strlen_zero(pds.peer)) { 03243 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03244 return -1; 03245 } 03246 03247 if (!pds.exten) { 03248 pds.exten = defaultrdest; 03249 } 03250 03251 if (create_addr(pds.peer, c, &sin, &cai)) { 03252 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03253 return -1; 03254 } 03255 03256 if (!pds.username && !ast_strlen_zero(cai.username)) 03257 pds.username = cai.username; 03258 if (!pds.password && !ast_strlen_zero(cai.secret)) 03259 pds.password = cai.secret; 03260 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03261 pds.key = cai.outkey; 03262 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03263 pds.context = cai.peercontext; 03264 03265 /* Keep track of the context for outgoing calls too */ 03266 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03267 03268 if (pds.port) 03269 sin.sin_port = htons(atoi(pds.port)); 03270 03271 l = c->cid.cid_num; 03272 n = c->cid.cid_name; 03273 03274 /* Now build request */ 03275 memset(&ied, 0, sizeof(ied)); 03276 03277 /* On new call, first IE MUST be IAX version of caller */ 03278 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03279 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03280 if (pds.options && strchr(pds.options, 'a')) { 03281 /* Request auto answer */ 03282 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03283 } 03284 03285 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03286 03287 if (l) { 03288 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03289 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03290 } else { 03291 if (n) 03292 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03293 else 03294 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03295 } 03296 03297 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03298 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03299 03300 if (n) 03301 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03302 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03303 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03304 03305 if (!ast_strlen_zero(c->language)) 03306 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03307 if (!ast_strlen_zero(c->cid.cid_dnid)) 03308 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03309 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03310 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03311 03312 if (pds.context) 03313 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03314 03315 if (pds.username) 03316 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03317 03318 if (cai.encmethods) 03319 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03320 03321 ast_mutex_lock(&iaxsl[callno]); 03322 03323 if (!ast_strlen_zero(c->context)) 03324 ast_string_field_set(iaxs[callno], context, c->context); 03325 03326 if (pds.username) 03327 ast_string_field_set(iaxs[callno], username, pds.username); 03328 03329 iaxs[callno]->encmethods = cai.encmethods; 03330 03331 iaxs[callno]->adsi = cai.adsi; 03332 03333 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03334 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03335 03336 if (pds.key) 03337 ast_string_field_set(iaxs[callno], outkey, pds.key); 03338 if (pds.password) 03339 ast_string_field_set(iaxs[callno], secret, pds.password); 03340 03341 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03342 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03343 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03344 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03345 03346 if (iaxs[callno]->maxtime) { 03347 /* Initialize pingtime and auto-congest time */ 03348 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03349 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03350 } else if (autokill) { 03351 iaxs[callno]->pingtime = autokill / 2; 03352 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03353 } 03354 03355 /* send the command using the appropriate socket for this peer */ 03356 iaxs[callno]->sockfd = cai.sockfd; 03357 03358 /* Transmit the string in a "NEW" request */ 03359 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03360 03361 ast_mutex_unlock(&iaxsl[callno]); 03362 ast_setstate(c, AST_STATE_RINGING); 03363 03364 return 0; 03365 }
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 10494 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.
10495 { 10496 int res = 0; 10497 struct iax2_dpcache *dp; 10498 #if 0 10499 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10500 #endif 10501 if ((priority != 1) && (priority != 2)) 10502 return 0; 10503 ast_mutex_lock(&dpcache_lock); 10504 dp = find_cache(chan, data, context, exten, priority); 10505 if (dp) { 10506 if (dp->flags & CACHE_FLAG_CANEXIST) 10507 res= 1; 10508 } 10509 ast_mutex_unlock(&dpcache_lock); 10510 if (!dp) { 10511 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10512 } 10513 return res; 10514 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3123 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03124 { 03125 time_t t; 03126 struct tm tm; 03127 unsigned int tmp; 03128 time(&t); 03129 if (!ast_strlen_zero(tz)) 03130 ast_localtime(&t, &tm, tz); 03131 else 03132 ast_localtime(&t, &tm, NULL); 03133 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03134 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03135 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03136 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03137 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03138 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03139 return tmp; 03140 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1279 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), and update_max_trunk().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01280 { 01281 struct chan_iax2_pvt *pvt; 01282 struct ast_channel *owner; 01283 01284 retry: 01285 pvt = iaxs[callno]; 01286 gettimeofday(&lastused[callno], NULL); 01287 01288 owner = pvt ? pvt->owner : NULL; 01289 01290 if (owner) { 01291 if (ast_mutex_trylock(&owner->lock)) { 01292 if (option_debug > 2) 01293 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01294 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01295 goto retry; 01296 } 01297 } 01298 if (!owner) { 01299 iaxs[callno] = NULL; 01300 } 01301 01302 if (pvt) { 01303 if (!owner) { 01304 pvt->owner = NULL; 01305 } else { 01306 /* If there's an owner, prod it to give up */ 01307 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01308 * because we already hold the owner channel lock. */ 01309 ast_queue_hangup(owner); 01310 } 01311 01312 if (pvt->peercallno) { 01313 remove_by_peercallno(pvt); 01314 } 01315 01316 if (!owner) { 01317 ao2_ref(pvt, -1); 01318 pvt = NULL; 01319 } 01320 } 01321 01322 if (owner) { 01323 ast_mutex_unlock(&owner->lock); 01324 } 01325 01326 if (callno & 0x4000) { 01327 update_max_trunk(); 01328 } 01329 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1209 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, sched, user_unref(), and users.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01210 { 01211 /* Decrement AUTHREQ count if needed */ 01212 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01213 struct iax2_user *user; 01214 struct iax2_user tmp_user = { 01215 .name = pvt->username, 01216 }; 01217 01218 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01219 if (user) { 01220 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01221 user = user_unref(user); 01222 } 01223 01224 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01225 } 01226 01227 /* No more pings or lagrq's */ 01228 AST_SCHED_DEL(sched, pvt->pingid); 01229 AST_SCHED_DEL(sched, pvt->lagid); 01230 AST_SCHED_DEL(sched, pvt->autoid); 01231 AST_SCHED_DEL(sched, pvt->authid); 01232 AST_SCHED_DEL(sched, pvt->initid); 01233 AST_SCHED_DEL(sched, pvt->jbid); 01234 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10681 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_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().
10682 { 10683 struct parsed_dial_string pds; 10684 char *tmp = ast_strdupa(data); 10685 struct iax2_peer *p; 10686 int res = AST_DEVICE_INVALID; 10687 10688 memset(&pds, 0, sizeof(pds)); 10689 parse_dial_string(tmp, &pds); 10690 10691 if (ast_strlen_zero(pds.peer)) { 10692 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10693 return res; 10694 } 10695 10696 if (option_debug > 2) 10697 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10698 10699 /* SLD: FIXME: second call to find_peer during registration */ 10700 if (!(p = find_peer(pds.peer, 1))) 10701 return res; 10702 10703 res = AST_DEVICE_UNAVAILABLE; 10704 if (option_debug > 2) 10705 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10706 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10707 10708 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10709 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10710 /* Peer is registered, or have default IP address 10711 and a valid registration */ 10712 if (p->historicms == 0 || p->historicms <= p->maxms) 10713 /* let the core figure out whether it is in use or not */ 10714 res = AST_DEVICE_UNKNOWN; 10715 } 10716 10717 peer_unref(p); 10718 10719 return res; 10720 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2739 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02740 { 02741 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02742 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2744 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02745 { 02746 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02747 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4931 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04932 { 04933 if (argc < 2 || argc > 3) 04934 return RESULT_SHOWUSAGE; 04935 iaxdebug = 1; 04936 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04937 return RESULT_SUCCESS; 04938 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4949 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04950 { 04951 if (argc < 3 || argc > 4) 04952 return RESULT_SHOWUSAGE; 04953 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04954 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04955 return RESULT_SUCCESS; 04956 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8651 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, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), 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_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08652 { 08653 struct iax_ie_data ied; 08654 if (option_debug && iaxdebug) 08655 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08656 08657 if (reg->dnsmgr && 08658 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08659 /* Maybe the IP has changed, force DNS refresh */ 08660 ast_dnsmgr_refresh(reg->dnsmgr); 08661 } 08662 08663 /* 08664 * if IP has Changed, free allocated call to create a new one with new IP 08665 * call has the pointer to IP and must be updated to the new one 08666 */ 08667 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08668 ast_mutex_lock(&iaxsl[reg->callno]); 08669 iax2_destroy(reg->callno); 08670 ast_mutex_unlock(&iaxsl[reg->callno]); 08671 reg->callno = 0; 08672 } 08673 if (!reg->addr.sin_addr.s_addr) { 08674 if (option_debug && iaxdebug) 08675 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08676 /* Setup the next registration attempt */ 08677 AST_SCHED_DEL(sched, reg->expire); 08678 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08679 return -1; 08680 } 08681 08682 if (!reg->callno) { 08683 if (option_debug) 08684 ast_log(LOG_DEBUG, "Allocate call number\n"); 08685 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08686 if (reg->callno < 1) { 08687 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08688 return -1; 08689 } else if (option_debug) 08690 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08691 iaxs[reg->callno]->reg = reg; 08692 ast_mutex_unlock(&iaxsl[reg->callno]); 08693 } 08694 /* Schedule the next registration attempt */ 08695 AST_SCHED_DEL(sched, reg->expire); 08696 /* Setup the next registration a little early */ 08697 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08698 /* Send the request */ 08699 memset(&ied, 0, sizeof(ied)); 08700 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08701 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08702 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08703 reg->regstate = REG_STATE_REGSENT; 08704 return 0; 08705 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5732 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05733 { 05734 #ifdef SCHED_MULTITHREADED 05735 if (schedule_action(__iax2_do_register_s, data)) 05736 #endif 05737 __iax2_do_register_s(data); 05738 return 0; 05739 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4940 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04941 { 04942 if (argc < 3 || argc > 4) 04943 return RESULT_SHOWUSAGE; 04944 iaxtrunkdebug = 1; 04945 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04946 return RESULT_SUCCESS; 04947 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6423 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
06424 { 06425 struct iax_ie_data ied; 06426 /* Auto-hangup with 30 seconds of inactivity */ 06427 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06428 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06429 memset(&ied, 0, sizeof(ied)); 06430 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06431 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06432 dp->flags |= CACHE_FLAG_TRANSMITTED; 06433 }
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 10540 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.
10541 { 10542 char odata[256]; 10543 char req[256]; 10544 char *ncontext; 10545 struct iax2_dpcache *dp; 10546 struct ast_app *dial; 10547 #if 0 10548 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); 10549 #endif 10550 if (priority == 2) { 10551 /* Indicate status, can be overridden in dialplan */ 10552 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10553 if (dialstatus) { 10554 dial = pbx_findapp(dialstatus); 10555 if (dial) 10556 pbx_exec(chan, dial, ""); 10557 } 10558 return -1; 10559 } else if (priority != 1) 10560 return -1; 10561 ast_mutex_lock(&dpcache_lock); 10562 dp = find_cache(chan, data, context, exten, priority); 10563 if (dp) { 10564 if (dp->flags & CACHE_FLAG_EXISTS) { 10565 ast_copy_string(odata, data, sizeof(odata)); 10566 ncontext = strchr(odata, '/'); 10567 if (ncontext) { 10568 *ncontext = '\0'; 10569 ncontext++; 10570 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10571 } else { 10572 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10573 } 10574 if (option_verbose > 2) 10575 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10576 } else { 10577 ast_mutex_unlock(&dpcache_lock); 10578 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10579 return -1; 10580 } 10581 } 10582 ast_mutex_unlock(&dpcache_lock); 10583 dial = pbx_findapp("Dial"); 10584 if (dial) { 10585 return pbx_exec(chan, dial, req); 10586 } else { 10587 ast_log(LOG_WARNING, "No dial application registered\n"); 10588 } 10589 return -1; 10590 }
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 10471 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.
10472 { 10473 struct iax2_dpcache *dp; 10474 int res = 0; 10475 #if 0 10476 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10477 #endif 10478 if ((priority != 1) && (priority != 2)) 10479 return 0; 10480 ast_mutex_lock(&dpcache_lock); 10481 dp = find_cache(chan, data, context, exten, priority); 10482 if (dp) { 10483 if (dp->flags & CACHE_FLAG_EXISTS) 10484 res= 1; 10485 } 10486 ast_mutex_unlock(&dpcache_lock); 10487 if (!dp) { 10488 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10489 } 10490 return res; 10491 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2766 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02767 { 02768 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02769 ast_mutex_lock(&iaxsl[callno]); 02770 if (iaxs[callno]) 02771 iaxs[callno]->owner = newchan; 02772 else 02773 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02774 ast_mutex_unlock(&iaxsl[callno]); 02775 return 0; 02776 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1273 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), and schedule_delivery().
01274 { 01275 AST_SCHED_DEL(sched, fr->retrans); 01276 iax_frame_free(fr); 01277 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1179 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().
01180 { 01181 struct iax2_peer *peer = NULL; 01182 int res = 0; 01183 struct ao2_iterator i; 01184 01185 i = ao2_iterator_init(peers, 0); 01186 while ((peer = ao2_iterator_next(&i))) { 01187 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01188 (peer->addr.sin_port == sin.sin_port)) { 01189 ast_copy_string(host, peer->name, len); 01190 peer_unref(peer); 01191 res = 1; 01192 break; 01193 } 01194 peer_unref(peer); 01195 } 01196 01197 if (!peer) { 01198 peer = realtime_peer(NULL, &sin); 01199 if (peer) { 01200 ast_copy_string(host, peer->name, len); 01201 peer_unref(peer); 01202 res = 1; 01203 } 01204 } 01205 01206 return res; 01207 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3700 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().
03701 { 03702 struct iax2_peer *peer; 03703 int res = 0; 03704 struct ao2_iterator i; 03705 03706 i = ao2_iterator_init(peers, 0); 03707 while ((peer = ao2_iterator_next(&i))) { 03708 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03709 (peer->addr.sin_port == sin.sin_port)) { 03710 res = ast_test_flag(peer, IAX_TRUNK); 03711 peer_unref(peer); 03712 break; 03713 } 03714 peer_unref(peer); 03715 } 03716 03717 return res; 03718 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3367 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, option_debug, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03368 { 03369 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03370 int alreadygone; 03371 struct iax_ie_data ied; 03372 memset(&ied, 0, sizeof(ied)); 03373 ast_mutex_lock(&iaxsl[callno]); 03374 if (callno && iaxs[callno]) { 03375 if (option_debug) 03376 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03377 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03378 /* Send the hangup unless we have had a transmission error or are already gone */ 03379 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03380 if (!iaxs[callno]->error && !alreadygone) { 03381 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03382 if (!iaxs[callno]) { 03383 ast_mutex_unlock(&iaxsl[callno]); 03384 return 0; 03385 } 03386 } 03387 /* Explicitly predestroy it */ 03388 iax2_predestroy(callno); 03389 /* If we were already gone to begin with, destroy us now */ 03390 if (alreadygone && iaxs[callno]) { 03391 if (option_debug) 03392 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03393 iax2_destroy(callno); 03394 } 03395 } 03396 ast_mutex_unlock(&iaxsl[callno]); 03397 if (option_verbose > 2) 03398 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03399 return 0; 03400 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3633 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(), DEADLOCK_AVOIDANCE, iaxs, iaxsl, option_debug, chan_iax2_pvt::peercallno, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03634 { 03635 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03636 struct chan_iax2_pvt *pvt; 03637 int res = 0; 03638 03639 if (option_debug && iaxdebug) 03640 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03641 03642 ast_mutex_lock(&iaxsl[callno]); 03643 pvt = iaxs[callno]; 03644 03645 if (!pvt->peercallno) { 03646 /* We don't know the remote side's call number, yet. :( */ 03647 int count = 10; 03648 while (count-- && pvt && !pvt->peercallno) { 03649 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03650 pvt = iaxs[callno]; 03651 } 03652 if (!pvt->peercallno) { 03653 res = -1; 03654 goto done; 03655 } 03656 } 03657 03658 switch (condition) { 03659 case AST_CONTROL_HOLD: 03660 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03661 ast_moh_start(c, data, pvt->mohinterpret); 03662 goto done; 03663 } 03664 break; 03665 case AST_CONTROL_UNHOLD: 03666 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03667 ast_moh_stop(c); 03668 goto done; 03669 } 03670 } 03671 03672 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03673 03674 done: 03675 ast_mutex_unlock(&iaxsl[callno]); 03676 03677 return res; 03678 }
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 10517 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.
10518 { 10519 int res = 0; 10520 struct iax2_dpcache *dp; 10521 #if 0 10522 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10523 #endif 10524 if ((priority != 1) && (priority != 2)) 10525 return 0; 10526 ast_mutex_lock(&dpcache_lock); 10527 dp = find_cache(chan, data, context, exten, priority); 10528 if (dp) { 10529 if (dp->flags & CACHE_FLAG_MATCHMORE) 10530 res= 1; 10531 } 10532 ast_mutex_unlock(&dpcache_lock); 10533 if (!dp) { 10534 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10535 } 10536 return res; 10537 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4958 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04959 { 04960 if (argc < 3 || argc > 4) 04961 return RESULT_SHOWUSAGE; 04962 iaxdebug = 0; 04963 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04964 return RESULT_SUCCESS; 04965 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4976 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04977 { 04978 if (argc < 4 || argc > 5) 04979 return RESULT_SHOWUSAGE; 04980 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04981 jb_debug_output("\n"); 04982 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04983 return RESULT_SUCCESS; 04984 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4967 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04968 { 04969 if (argc < 4 || argc > 5) 04970 return RESULT_SHOWUSAGE; 04971 iaxtrunkdebug = 0; 04972 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04973 return RESULT_SUCCESS; 04974 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8849 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08850 { 08851 struct iax2_peer *peer = (struct iax2_peer *)data; 08852 peer->pokeexpire = -1; 08853 #ifdef SCHED_MULTITHREADED 08854 if (schedule_action(__iax2_poke_noanswer, data)) 08855 #endif 08856 __iax2_poke_noanswer(data); 08857 peer_unref(peer); 08858 return 0; 08859 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8870 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, sched, 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().
08871 { 08872 int callno; 08873 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08874 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08875 immediately after clearing things out */ 08876 peer->lastms = 0; 08877 peer->historicms = 0; 08878 peer->pokeexpire = -1; 08879 peer->callno = 0; 08880 return 0; 08881 } 08882 08883 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 08884 if ((callno = peer->callno) > 0) { 08885 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08886 ast_mutex_lock(&iaxsl[callno]); 08887 iax2_destroy(callno); 08888 ast_mutex_unlock(&iaxsl[callno]); 08889 } 08890 if (heldcall) 08891 ast_mutex_unlock(&iaxsl[heldcall]); 08892 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08893 if (heldcall) 08894 ast_mutex_lock(&iaxsl[heldcall]); 08895 if (peer->callno < 1) { 08896 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08897 return -1; 08898 } 08899 08900 /* Speed up retransmission times for this qualify call */ 08901 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08902 iaxs[peer->callno]->peerpoke = peer; 08903 08904 /* Remove any pending pokeexpire task */ 08905 if (peer->pokeexpire > -1) { 08906 if (!ast_sched_del(sched, peer->pokeexpire)) { 08907 peer->pokeexpire = -1; 08908 peer_unref(peer); 08909 } 08910 } 08911 08912 /* Queue up a new task to handle no reply */ 08913 /* If the host is already unreachable then use the unreachable interval instead */ 08914 if (peer->lastms < 0) { 08915 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08916 } else 08917 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08918 08919 if (peer->pokeexpire == -1) 08920 peer_unref(peer); 08921 08922 /* And send the poke */ 08923 ast_mutex_lock(&iaxsl[callno]); 08924 if (iaxs[callno]) { 08925 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08926 } 08927 ast_mutex_unlock(&iaxsl[callno]); 08928 08929 return 0; 08930 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8861 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08862 { 08863 struct iax2_peer *peer = obj; 08864 08865 iax2_poke_peer(peer, 0); 08866 08867 return 0; 08868 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6463 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06464 { 06465 struct iax2_peer *peer = (struct iax2_peer *)data; 06466 peer->pokeexpire = -1; 06467 #ifdef SCHED_MULTITHREADED 06468 if (schedule_action(__iax2_poke_peer_s, data)) 06469 #endif 06470 __iax2_poke_peer_s(data); 06471 return 0; 06472 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2112 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().
02113 { 02114 struct ast_channel *c; 02115 struct chan_iax2_pvt *pvt = iaxs[callno]; 02116 02117 if (!pvt) 02118 return -1; 02119 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02120 iax2_destroy_helper(pvt); 02121 ast_set_flag(pvt, IAX_ALREADYGONE); 02122 } 02123 c = pvt->owner; 02124 if (c) { 02125 c->tech_pvt = NULL; 02126 iax2_queue_hangup(callno); 02127 pvt->owner = NULL; 02128 ast_module_unref(ast_module_info->self); 02129 } 02130 return 0; 02131 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8526 of file chan_iax2.c.
References ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08527 { 08528 struct iax2_thread *thread = data; 08529 struct timeval tv; 08530 struct timespec ts; 08531 int put_into_idle = 0; 08532 08533 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08534 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08535 for(;;) { 08536 /* Wait for something to signal us to be awake */ 08537 ast_mutex_lock(&thread->lock); 08538 08539 /* Flag that we're ready to accept signals */ 08540 thread->ready_for_signal = 1; 08541 08542 /* Put into idle list if applicable */ 08543 if (put_into_idle) 08544 insert_idle_thread(thread); 08545 08546 if (thread->type == IAX_TYPE_DYNAMIC) { 08547 struct iax2_thread *t = NULL; 08548 /* Wait to be signalled or time out */ 08549 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08550 ts.tv_sec = tv.tv_sec; 08551 ts.tv_nsec = tv.tv_usec * 1000; 08552 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08553 /* This thread was never put back into the available dynamic 08554 * thread list, so just go away. */ 08555 if (!put_into_idle) { 08556 ast_mutex_unlock(&thread->lock); 08557 break; 08558 } 08559 AST_LIST_LOCK(&dynamic_list); 08560 /* Account for the case where this thread is acquired *right* after a timeout */ 08561 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08562 iaxdynamicthreadcount--; 08563 AST_LIST_UNLOCK(&dynamic_list); 08564 if (t) { 08565 /* This dynamic thread timed out waiting for a task and was 08566 * not acquired immediately after the timeout, 08567 * so it's time to go away. */ 08568 ast_mutex_unlock(&thread->lock); 08569 break; 08570 } 08571 /* Someone grabbed our thread *right* after we timed out. 08572 * Wait for them to set us up with something to do and signal 08573 * us to continue. */ 08574 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08575 ts.tv_sec = tv.tv_sec; 08576 ts.tv_nsec = tv.tv_usec * 1000; 08577 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08578 { 08579 ast_mutex_unlock(&thread->lock); 08580 break; 08581 } 08582 } 08583 } else { 08584 ast_cond_wait(&thread->cond, &thread->lock); 08585 } 08586 08587 /* Go back into our respective list */ 08588 put_into_idle = 1; 08589 08590 ast_mutex_unlock(&thread->lock); 08591 08592 if (thread->iostate == IAX_IOSTATE_IDLE) 08593 continue; 08594 08595 /* Add ourselves to the active list now */ 08596 AST_LIST_LOCK(&active_list); 08597 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08598 AST_LIST_UNLOCK(&active_list); 08599 08600 /* See what we need to do */ 08601 switch(thread->iostate) { 08602 case IAX_IOSTATE_READY: 08603 thread->actions++; 08604 thread->iostate = IAX_IOSTATE_PROCESSING; 08605 socket_process(thread); 08606 handle_deferred_full_frames(thread); 08607 break; 08608 case IAX_IOSTATE_SCHEDREADY: 08609 thread->actions++; 08610 thread->iostate = IAX_IOSTATE_PROCESSING; 08611 #ifdef SCHED_MULTITHREADED 08612 thread->schedfunc(thread->scheddata); 08613 #endif 08614 break; 08615 } 08616 time(&thread->checktime); 08617 thread->iostate = IAX_IOSTATE_IDLE; 08618 #ifdef DEBUG_SCHED_MULTITHREAD 08619 thread->curfunc[0]='\0'; 08620 #endif 08621 08622 /* Now... remove ourselves from the active list, and return to the idle list */ 08623 AST_LIST_LOCK(&active_list); 08624 AST_LIST_REMOVE(&active_list, thread, list); 08625 AST_LIST_UNLOCK(&active_list); 08626 08627 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08628 handle_deferred_full_frames(thread); 08629 } 08630 08631 /*!\note For some reason, idle threads are exiting without being removed 08632 * from an idle list, which is causing memory corruption. Forcibly remove 08633 * it from the list, if it's there. 08634 */ 08635 AST_LIST_LOCK(&idle_list); 08636 AST_LIST_REMOVE(&idle_list, thread, list); 08637 AST_LIST_UNLOCK(&idle_list); 08638 08639 AST_LIST_LOCK(&dynamic_list); 08640 AST_LIST_REMOVE(&dynamic_list, thread, list); 08641 AST_LIST_UNLOCK(&dynamic_list); 08642 08643 /* I am exiting here on my own volition, I need to clean up my own data structures 08644 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08645 */ 08646 pthread_cleanup_pop(1); 08647 08648 return NULL; 08649 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8517 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08518 { 08519 struct iax2_thread *thread = data; 08520 ast_mutex_destroy(&thread->lock); 08521 ast_cond_destroy(&thread->cond); 08522 free(thread); 08523 ast_atomic_dec_and_test(&iaxactivethreadcount); 08524 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8804 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08805 { 08806 int force = 0; 08807 int res; 08808 if (argc < 4) 08809 return RESULT_SHOWUSAGE; 08810 if ((argc > 4)) { 08811 if (!strcasecmp(argv[4], "forced")) 08812 force = 1; 08813 else 08814 return RESULT_SHOWUSAGE; 08815 } 08816 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08817 if (res < 0) 08818 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08819 else if (res < 1) 08820 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08821 else 08822 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08823 return RESULT_SUCCESS; 08824 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8707 of file chan_iax2.c.
References iax_prov_complete_template().
08708 { 08709 if (pos != 3) 08710 return NULL; 08711 return iax_prov_complete_template(line, word, pos, state); 08712 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8714 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08715 { 08716 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08717 is found for template */ 08718 struct iax_ie_data provdata; 08719 struct iax_ie_data ied; 08720 unsigned int sig; 08721 struct sockaddr_in sin; 08722 int callno; 08723 struct create_addr_info cai; 08724 08725 memset(&cai, 0, sizeof(cai)); 08726 08727 if (option_debug) 08728 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08729 08730 if (iax_provision_build(&provdata, &sig, template, force)) { 08731 if (option_debug) 08732 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08733 return 0; 08734 } 08735 08736 if (end) { 08737 memcpy(&sin, end, sizeof(sin)); 08738 cai.sockfd = sockfd; 08739 } else if (create_addr(dest, NULL, &sin, &cai)) 08740 return -1; 08741 08742 /* Build the rest of the message */ 08743 memset(&ied, 0, sizeof(ied)); 08744 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08745 08746 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08747 if (!callno) 08748 return -1; 08749 08750 if (iaxs[callno]) { 08751 /* Schedule autodestruct in case they don't ever give us anything back */ 08752 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08753 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08754 ast_set_flag(iaxs[callno], IAX_PROVISION); 08755 /* Got a call number now, so go ahead and send the provisioning information */ 08756 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08757 } 08758 ast_mutex_unlock(&iaxsl[callno]); 08759 08760 return 1; 08761 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2236 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.
02237 { 02238 struct iax2_peer *peer; 02239 02240 if (argc != 4) 02241 return RESULT_SHOWUSAGE; 02242 if (!strcmp(argv[3],"all")) { 02243 reload_config(); 02244 ast_cli(fd, "OK cache is flushed.\n"); 02245 } else if ((peer = find_peer(argv[3], 0))) { 02246 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02247 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02248 expire_registry(peer_ref(peer)); 02249 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02250 } else { 02251 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02252 } 02253 peer_unref(peer); 02254 } else { 02255 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02256 } 02257 02258 return RESULT_SUCCESS; 02259 }
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 1722 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01724 { 01725 for (;;) { 01726 if (iaxs[callno] && iaxs[callno]->owner) { 01727 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01728 /* Avoid deadlock by pausing and trying again */ 01729 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01730 } else { 01731 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01732 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01733 break; 01734 } 01735 } else 01736 break; 01737 } 01738 return 0; 01739 }
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 1660 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01661 { 01662 for (;;) { 01663 if (iaxs[callno] && iaxs[callno]->owner) { 01664 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01665 /* Avoid deadlock by pausing and trying again */ 01666 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01667 } else { 01668 ast_queue_frame(iaxs[callno]->owner, f); 01669 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01670 break; 01671 } 01672 } else 01673 break; 01674 } 01675 return 0; 01676 }
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 1691 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxsl, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01692 { 01693 for (;;) { 01694 if (iaxs[callno] && iaxs[callno]->owner) { 01695 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01696 /* Avoid deadlock by pausing and trying again */ 01697 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01698 } else { 01699 ast_queue_hangup(iaxs[callno]->owner); 01700 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01701 break; 01702 } 01703 } else 01704 break; 01705 } 01706 return 0; 01707 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3428 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
03429 { 03430 ast_log(LOG_NOTICE, "I should never be called!\n"); 03431 return &ast_null_frame; 03432 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5945 of file chan_iax2.c.
References ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, secret, and strsep().
Referenced by set_config().
05946 { 05947 struct iax2_registry *reg; 05948 char copy[256]; 05949 char *username, *hostname, *secret; 05950 char *porta; 05951 char *stringp=NULL; 05952 05953 if (!value) 05954 return -1; 05955 ast_copy_string(copy, value, sizeof(copy)); 05956 stringp=copy; 05957 username = strsep(&stringp, "@"); 05958 hostname = strsep(&stringp, "@"); 05959 if (!hostname) { 05960 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05961 return -1; 05962 } 05963 stringp=username; 05964 username = strsep(&stringp, ":"); 05965 secret = strsep(&stringp, ":"); 05966 stringp=hostname; 05967 hostname = strsep(&stringp, ":"); 05968 porta = strsep(&stringp, ":"); 05969 05970 if (porta && !atoi(porta)) { 05971 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05972 return -1; 05973 } 05974 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05975 return -1; 05976 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05977 free(reg); 05978 return -1; 05979 } 05980 ast_copy_string(reg->username, username, sizeof(reg->username)); 05981 if (secret) 05982 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05983 reg->expire = -1; 05984 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05985 reg->addr.sin_family = AF_INET; 05986 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05987 AST_LIST_LOCK(®istrations); 05988 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05989 AST_LIST_UNLOCK(®istrations); 05990 05991 return 0; 05992 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10240 of file chan_iax2.c.
References reload_config().
10241 { 10242 return reload_config(); 10243 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8942 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_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), fmt, globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.
08943 { 08944 int callno; 08945 int res; 08946 int fmt, native; 08947 struct sockaddr_in sin; 08948 struct ast_channel *c; 08949 struct parsed_dial_string pds; 08950 struct create_addr_info cai; 08951 char *tmpstr; 08952 08953 memset(&pds, 0, sizeof(pds)); 08954 tmpstr = ast_strdupa(data); 08955 parse_dial_string(tmpstr, &pds); 08956 08957 if (ast_strlen_zero(pds.peer)) { 08958 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 08959 return NULL; 08960 } 08961 08962 memset(&cai, 0, sizeof(cai)); 08963 cai.capability = iax2_capability; 08964 08965 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08966 08967 /* Populate our address from the given */ 08968 if (create_addr(pds.peer, NULL, &sin, &cai)) { 08969 *cause = AST_CAUSE_UNREGISTERED; 08970 return NULL; 08971 } 08972 08973 if (pds.port) 08974 sin.sin_port = htons(atoi(pds.port)); 08975 08976 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08977 if (callno < 1) { 08978 ast_log(LOG_WARNING, "Unable to create call\n"); 08979 *cause = AST_CAUSE_CONGESTION; 08980 return NULL; 08981 } 08982 08983 /* If this is a trunk, update it now */ 08984 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08985 if (ast_test_flag(&cai, IAX_TRUNK)) { 08986 int new_callno; 08987 if ((new_callno = make_trunk(callno, 1)) != -1) 08988 callno = new_callno; 08989 } 08990 iaxs[callno]->maxtime = cai.maxtime; 08991 if (cai.found) 08992 ast_string_field_set(iaxs[callno], host, pds.peer); 08993 08994 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08995 08996 ast_mutex_unlock(&iaxsl[callno]); 08997 08998 if (c) { 08999 /* Choose a format we can live with */ 09000 if (c->nativeformats & format) 09001 c->nativeformats &= format; 09002 else { 09003 native = c->nativeformats; 09004 fmt = format; 09005 res = ast_translator_best_choice(&fmt, &native); 09006 if (res < 0) { 09007 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09008 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09009 ast_hangup(c); 09010 return NULL; 09011 } 09012 c->nativeformats = native; 09013 } 09014 c->readformat = ast_best_codec(c->nativeformats); 09015 c->writeformat = c->readformat; 09016 } 09017 09018 return c; 09019 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 983 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00984 { 00985 int res; 00986 00987 res = ast_sched_add(con, when, callback, data); 00988 signal_condition(&sched_lock, &sched_cond); 00989 00990 return res; 00991 }
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 4269 of file chan_iax2.c.
References 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, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), f, 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, chan_iax2_pvt::lastvsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, 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().
04270 { 04271 /* Queue a packet for delivery on a given private structure. Use "ts" for 04272 timestamp, or calculate if ts is 0. Send immediately without retransmission 04273 or delayed, with retransmission */ 04274 struct ast_iax2_full_hdr *fh; 04275 struct ast_iax2_mini_hdr *mh; 04276 struct ast_iax2_video_hdr *vh; 04277 struct { 04278 struct iax_frame fr2; 04279 unsigned char buffer[4096]; 04280 } frb; 04281 struct iax_frame *fr; 04282 int res; 04283 int sendmini=0; 04284 unsigned int lastsent; 04285 unsigned int fts; 04286 04287 frb.fr2.afdatalen = sizeof(frb.buffer); 04288 04289 if (!pvt) { 04290 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04291 return -1; 04292 } 04293 04294 lastsent = pvt->lastsent; 04295 04296 /* Calculate actual timestamp */ 04297 fts = calc_timestamp(pvt, ts, f); 04298 04299 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04300 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04301 * increment the "predicted timestamps" for voice, if we're predecting */ 04302 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04303 return 0; 04304 04305 04306 if ((ast_test_flag(pvt, IAX_TRUNK) || 04307 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04308 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04309 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04310 (f->frametype == AST_FRAME_VOICE) 04311 /* is a voice frame */ && 04312 (f->subclass == pvt->svoiceformat) 04313 /* is the same type */ ) { 04314 /* Force immediate rather than delayed transmission */ 04315 now = 1; 04316 /* Mark that mini-style frame is appropriate */ 04317 sendmini = 1; 04318 } 04319 if ( f->frametype == AST_FRAME_VIDEO ) { 04320 /* 04321 * If the lower 15 bits of the timestamp roll over, or if 04322 * the video format changed then send a full frame. 04323 * Otherwise send a mini video frame 04324 */ 04325 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04326 ((f->subclass & ~0x1) == pvt->svideoformat) 04327 ) { 04328 now = 1; 04329 sendmini = 1; 04330 } else { 04331 now = 0; 04332 sendmini = 0; 04333 } 04334 pvt->lastvsent = fts; 04335 } 04336 /* Allocate an iax_frame */ 04337 if (now) { 04338 fr = &frb.fr2; 04339 } else 04340 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)); 04341 if (!fr) { 04342 ast_log(LOG_WARNING, "Out of memory\n"); 04343 return -1; 04344 } 04345 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04346 iax_frame_wrap(fr, f); 04347 04348 fr->ts = fts; 04349 fr->callno = pvt->callno; 04350 fr->transfer = transfer; 04351 fr->final = final; 04352 if (!sendmini) { 04353 /* We need a full frame */ 04354 if (seqno > -1) 04355 fr->oseqno = seqno; 04356 else 04357 fr->oseqno = pvt->oseqno++; 04358 fr->iseqno = pvt->iseqno; 04359 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04360 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04361 fh->ts = htonl(fr->ts); 04362 fh->oseqno = fr->oseqno; 04363 if (transfer) { 04364 fh->iseqno = 0; 04365 } else 04366 fh->iseqno = fr->iseqno; 04367 /* Keep track of the last thing we've acknowledged */ 04368 if (!transfer) 04369 pvt->aseqno = fr->iseqno; 04370 fh->type = fr->af.frametype & 0xFF; 04371 if (fr->af.frametype == AST_FRAME_VIDEO) 04372 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04373 else 04374 fh->csub = compress_subclass(fr->af.subclass); 04375 if (transfer) { 04376 fr->dcallno = pvt->transfercallno; 04377 } else 04378 fr->dcallno = pvt->peercallno; 04379 fh->dcallno = htons(fr->dcallno); 04380 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04381 fr->data = fh; 04382 fr->retries = 0; 04383 /* Retry after 2x the ping time has passed */ 04384 fr->retrytime = pvt->pingtime * 2; 04385 if (fr->retrytime < MIN_RETRY_TIME) 04386 fr->retrytime = MIN_RETRY_TIME; 04387 if (fr->retrytime > MAX_RETRY_TIME) 04388 fr->retrytime = MAX_RETRY_TIME; 04389 /* Acks' don't get retried */ 04390 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04391 fr->retries = -1; 04392 else if (f->frametype == AST_FRAME_VOICE) 04393 pvt->svoiceformat = f->subclass; 04394 else if (f->frametype == AST_FRAME_VIDEO) 04395 pvt->svideoformat = f->subclass & ~0x1; 04396 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04397 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04398 if (iaxdebug) { 04399 if (fr->transfer) 04400 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04401 else 04402 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04403 } 04404 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04405 } else 04406 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04407 } 04408 04409 if (now) { 04410 res = send_packet(fr); 04411 } else 04412 res = iax2_transmit(fr); 04413 } else { 04414 if (ast_test_flag(pvt, IAX_TRUNK)) { 04415 iax2_trunk_queue(pvt, fr); 04416 res = 0; 04417 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04418 /* Video frame have no sequence number */ 04419 fr->oseqno = -1; 04420 fr->iseqno = -1; 04421 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04422 vh->zeros = 0; 04423 vh->callno = htons(0x8000 | fr->callno); 04424 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04425 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04426 fr->data = vh; 04427 fr->retries = -1; 04428 res = send_packet(fr); 04429 } else { 04430 /* Mini-frames have no sequence number */ 04431 fr->oseqno = -1; 04432 fr->iseqno = -1; 04433 /* Mini frame will do */ 04434 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04435 mh->callno = htons(fr->callno); 04436 mh->ts = htons(fr->ts & 0xFFFF); 04437 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04438 fr->data = mh; 04439 fr->retries = -1; 04440 if (pvt->transferring == TRANSFER_MEDIAPASS) 04441 fr->transfer = 1; 04442 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04443 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04444 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04445 } else 04446 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04447 } 04448 res = send_packet(fr); 04449 } 04450 } 04451 return res; 04452 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2761 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02762 { 02763 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02764 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2756 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.
02757 { 02758 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02759 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2749 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02750 { 02751 02752 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02753 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02754 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3402 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03403 { 03404 struct ast_option_header *h; 03405 int res; 03406 03407 switch (option) { 03408 case AST_OPTION_TXGAIN: 03409 case AST_OPTION_RXGAIN: 03410 /* these two cannot be sent, because they require a result */ 03411 errno = ENOSYS; 03412 return -1; 03413 default: 03414 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03415 return -1; 03416 03417 h->flag = AST_OPTION_FLAG_REQUEST; 03418 h->option = htons(option); 03419 memcpy(h->data, data, datalen); 03420 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03421 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03422 datalen + sizeof(*h), -1); 03423 free(h); 03424 return res; 03425 } 03426 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2440 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.
02441 { 02442 struct iax2_dpcache *dp; 02443 char tmp[1024], *pc; 02444 int s; 02445 int x,y; 02446 struct timeval tv; 02447 gettimeofday(&tv, NULL); 02448 ast_mutex_lock(&dpcache_lock); 02449 dp = dpcache; 02450 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02451 while(dp) { 02452 s = dp->expiry.tv_sec - tv.tv_sec; 02453 tmp[0] = '\0'; 02454 if (dp->flags & CACHE_FLAG_EXISTS) 02455 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02456 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02457 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02458 if (dp->flags & CACHE_FLAG_CANEXIST) 02459 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02460 if (dp->flags & CACHE_FLAG_PENDING) 02461 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02462 if (dp->flags & CACHE_FLAG_TIMEOUT) 02463 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02464 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02465 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02466 if (dp->flags & CACHE_FLAG_MATCHMORE) 02467 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02468 if (dp->flags & CACHE_FLAG_UNKNOWN) 02469 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02470 /* Trim trailing pipe */ 02471 if (!ast_strlen_zero(tmp)) 02472 tmp[strlen(tmp) - 1] = '\0'; 02473 else 02474 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02475 y=0; 02476 pc = strchr(dp->peercontext, '@'); 02477 if (!pc) 02478 pc = dp->peercontext; 02479 else 02480 pc++; 02481 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02482 if (dp->waiters[x] > -1) 02483 y++; 02484 if (s > 0) 02485 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02486 else 02487 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02488 dp = dp->next; 02489 } 02490 ast_mutex_unlock(&dpcache_lock); 02491 return RESULT_SUCCESS; 02492 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4796 of file chan_iax2.c.
References ARRAY_LEN, 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_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04797 { 04798 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04799 #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" 04800 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04801 int x; 04802 int numchans = 0; 04803 04804 if (argc != 3) 04805 return RESULT_SHOWUSAGE; 04806 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04807 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04808 ast_mutex_lock(&iaxsl[x]); 04809 if (iaxs[x]) { 04810 int lag, jitter, localdelay; 04811 jb_info jbinfo; 04812 04813 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04814 jb_getinfo(iaxs[x]->jb, &jbinfo); 04815 jitter = jbinfo.jitter; 04816 localdelay = jbinfo.current - jbinfo.min; 04817 } else { 04818 jitter = -1; 04819 localdelay = 0; 04820 } 04821 lag = iaxs[x]->remote_rr.delay; 04822 ast_cli(fd, FORMAT, 04823 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04824 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04825 S_OR(iaxs[x]->username, "(None)"), 04826 iaxs[x]->callno, iaxs[x]->peercallno, 04827 iaxs[x]->oseqno, iaxs[x]->iseqno, 04828 lag, 04829 jitter, 04830 localdelay, 04831 ast_getformatname(iaxs[x]->voiceformat) ); 04832 numchans++; 04833 } 04834 ast_mutex_unlock(&iaxsl[x]); 04835 } 04836 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04837 return RESULT_SUCCESS; 04838 #undef FORMAT 04839 #undef FORMAT2 04840 #undef FORMATB 04841 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4707 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.
04708 { 04709 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04710 #if !defined(__FreeBSD__) 04711 #define FORMAT "%-15.15s %-15d %-15d\n" 04712 #else /* __FreeBSD__ */ 04713 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04714 #endif /* __FreeBSD__ */ 04715 struct iax_firmware *cur; 04716 if ((argc != 3) && (argc != 4)) 04717 return RESULT_SHOWUSAGE; 04718 ast_mutex_lock(&waresl.lock); 04719 04720 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04721 for (cur = waresl.wares;cur;cur = cur->next) { 04722 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04723 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04724 (int)ntohl(cur->fwh->datalen)); 04725 } 04726 ast_mutex_unlock(&waresl.lock); 04727 return RESULT_SUCCESS; 04728 #undef FORMAT 04729 #undef FORMAT2 04730 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4919 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04920 { 04921 int numchans = 0; 04922 if (argc != 3) 04923 return RESULT_SHOWUSAGE; 04924 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04925 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04926 numchans = ast_cli_netstats(NULL, fd, 1); 04927 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04928 return RESULT_SUCCESS; 04929 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2330 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.
02331 { 02332 char status[30]; 02333 char cbuf[256]; 02334 struct iax2_peer *peer; 02335 char codec_buf[512]; 02336 int x = 0, codec = 0, load_realtime = 0; 02337 02338 if (argc < 4) 02339 return RESULT_SHOWUSAGE; 02340 02341 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02342 02343 peer = find_peer(argv[3], load_realtime); 02344 if (peer) { 02345 ast_cli(fd,"\n\n"); 02346 ast_cli(fd, " * Name : %s\n", peer->name); 02347 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02348 ast_cli(fd, " Context : %s\n", peer->context); 02349 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02350 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02351 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02352 ast_cli(fd, " Expire : %d\n", peer->expire); 02353 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02354 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)); 02355 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02356 ast_cli(fd, " Username : %s\n", peer->username); 02357 ast_cli(fd, " Codecs : "); 02358 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02359 ast_cli(fd, "%s\n", codec_buf); 02360 02361 ast_cli(fd, " Codec Order : ("); 02362 for(x = 0; x < 32 ; x++) { 02363 codec = ast_codec_pref_index(&peer->prefs,x); 02364 if(!codec) 02365 break; 02366 ast_cli(fd, "%s", ast_getformatname(codec)); 02367 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02368 ast_cli(fd, "|"); 02369 } 02370 02371 if (!x) 02372 ast_cli(fd, "none"); 02373 ast_cli(fd, ")\n"); 02374 02375 ast_cli(fd, " Status : "); 02376 peer_status(peer, status, sizeof(status)); 02377 ast_cli(fd, "%s\n",status); 02378 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02379 ast_cli(fd,"\n"); 02380 peer_unref(peer); 02381 } else { 02382 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02383 ast_cli(fd,"\n"); 02384 } 02385 02386 return RESULT_SUCCESS; 02387 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4696 of file chan_iax2.c.
References __iax2_show_peers().
04697 { 04698 return __iax2_show_peers(0, fd, NULL, argc, argv); 04699 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4768 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.
04769 { 04770 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04771 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04772 struct iax2_registry *reg = NULL; 04773 04774 char host[80]; 04775 char perceived[80]; 04776 if (argc != 3) 04777 return RESULT_SHOWUSAGE; 04778 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04779 AST_LIST_LOCK(®istrations); 04780 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04781 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04782 if (reg->us.sin_addr.s_addr) 04783 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04784 else 04785 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04786 ast_cli(fd, FORMAT, host, 04787 (reg->dnsmgr) ? "Y" : "N", 04788 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04789 } 04790 AST_LIST_UNLOCK(®istrations); 04791 return RESULT_SUCCESS; 04792 #undef FORMAT 04793 #undef FORMAT2 04794 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2414 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.
02415 { 02416 struct iax_frame *cur; 02417 int cnt = 0, dead=0, final=0; 02418 02419 if (argc != 3) 02420 return RESULT_SHOWUSAGE; 02421 02422 AST_LIST_LOCK(&iaxq.queue); 02423 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02424 if (cur->retries < 0) 02425 dead++; 02426 if (cur->final) 02427 final++; 02428 cnt++; 02429 } 02430 AST_LIST_UNLOCK(&iaxq.queue); 02431 02432 ast_cli(fd, " IAX Statistics\n"); 02433 ast_cli(fd, "---------------------\n"); 02434 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02435 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02436 02437 return RESULT_SUCCESS; 02438 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4637 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, thread, and type.
04638 { 04639 struct iax2_thread *thread = NULL; 04640 time_t t; 04641 int threadcount = 0, dynamiccount = 0; 04642 char type; 04643 04644 if (argc != 3) 04645 return RESULT_SHOWUSAGE; 04646 04647 ast_cli(fd, "IAX2 Thread Information\n"); 04648 time(&t); 04649 ast_cli(fd, "Idle Threads:\n"); 04650 AST_LIST_LOCK(&idle_list); 04651 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04652 #ifdef DEBUG_SCHED_MULTITHREAD 04653 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04654 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04655 #else 04656 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04657 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04658 #endif 04659 threadcount++; 04660 } 04661 AST_LIST_UNLOCK(&idle_list); 04662 ast_cli(fd, "Active Threads:\n"); 04663 AST_LIST_LOCK(&active_list); 04664 AST_LIST_TRAVERSE(&active_list, thread, list) { 04665 if (thread->type == IAX_TYPE_DYNAMIC) 04666 type = 'D'; 04667 else 04668 type = 'P'; 04669 #ifdef DEBUG_SCHED_MULTITHREAD 04670 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04671 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04672 #else 04673 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04674 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04675 #endif 04676 threadcount++; 04677 } 04678 AST_LIST_UNLOCK(&active_list); 04679 ast_cli(fd, "Dynamic Threads:\n"); 04680 AST_LIST_LOCK(&dynamic_list); 04681 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04682 #ifdef DEBUG_SCHED_MULTITHREAD 04683 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04684 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04685 #else 04686 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04687 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04688 #endif 04689 dynamiccount++; 04690 } 04691 AST_LIST_UNLOCK(&dynamic_list); 04692 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04693 return RESULT_SUCCESS; 04694 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4454 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.
04455 { 04456 regex_t regexbuf; 04457 int havepattern = 0; 04458 04459 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04460 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04461 04462 struct iax2_user *user = NULL; 04463 char auth[90]; 04464 char *pstr = ""; 04465 struct ao2_iterator i; 04466 04467 switch (argc) { 04468 case 5: 04469 if (!strcasecmp(argv[3], "like")) { 04470 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04471 return RESULT_SHOWUSAGE; 04472 havepattern = 1; 04473 } else 04474 return RESULT_SHOWUSAGE; 04475 case 3: 04476 break; 04477 default: 04478 return RESULT_SHOWUSAGE; 04479 } 04480 04481 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04482 i = ao2_iterator_init(users, 0); 04483 for (user = ao2_iterator_next(&i); user; 04484 user_unref(user), user = ao2_iterator_next(&i)) { 04485 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04486 continue; 04487 04488 if (!ast_strlen_zero(user->secret)) { 04489 ast_copy_string(auth,user->secret,sizeof(auth)); 04490 } else if (!ast_strlen_zero(user->inkeys)) { 04491 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04492 } else 04493 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04494 04495 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04496 pstr = "REQ Only"; 04497 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04498 pstr = "Disabled"; 04499 else 04500 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04501 04502 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04503 user->contexts ? user->contexts->context : context, 04504 user->ha ? "Yes" : "No", pstr); 04505 } 04506 04507 if (havepattern) 04508 regfree(®exbuf); 04509 04510 return RESULT_SUCCESS; 04511 #undef FORMAT 04512 #undef FORMAT2 04513 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3434 of file chan_iax2.c.
References AST_FRAME_IAX, ast_random(), 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, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
03435 { 03436 int res; 03437 struct iax_ie_data ied0; 03438 struct iax_ie_data ied1; 03439 unsigned int transferid = (unsigned int)ast_random(); 03440 memset(&ied0, 0, sizeof(ied0)); 03441 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03442 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03443 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03444 03445 memset(&ied1, 0, sizeof(ied1)); 03446 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03447 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03448 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03449 03450 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03451 if (res) 03452 return -1; 03453 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03454 if (res) 03455 return -1; 03456 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03457 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03458 return 0; 03459 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2261 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02262 { 02263 if (argc != 4) 02264 return RESULT_SHOWUSAGE; 02265 02266 test_losspct = atoi(argv[3]); 02267 02268 return RESULT_SUCCESS; 02269 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3680 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03681 { 03682 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03683 struct iax_ie_data ied; 03684 char tmp[256], *context; 03685 ast_copy_string(tmp, dest, sizeof(tmp)); 03686 context = strchr(tmp, '@'); 03687 if (context) { 03688 *context = '\0'; 03689 context++; 03690 } 03691 memset(&ied, 0, sizeof(ied)); 03692 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03693 if (context) 03694 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03695 if (option_debug) 03696 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03697 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03698 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2720 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().
02721 { 02722 /* Lock the queue and place this packet at the end */ 02723 /* By setting this to 0, the network thread will send it for us, and 02724 queue retransmission if necessary */ 02725 fr->sentyet = 0; 02726 AST_LIST_LOCK(&iaxq.queue); 02727 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02728 iaxq.count++; 02729 AST_LIST_UNLOCK(&iaxq.queue); 02730 /* Wake up the network and scheduler thread */ 02731 if (netthreadid != AST_PTHREADT_NULL) 02732 pthread_kill(netthreadid, SIGURG); 02733 signal_condition(&sched_lock, &sched_cond); 02734 return 0; 02735 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6518 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06519 { 06520 /* Drop when trunk is about 5 seconds idle */ 06521 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06522 return 1; 06523 return 0; 06524 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4043 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, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, 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().
04044 { 04045 struct ast_frame *f; 04046 struct iax2_trunk_peer *tpeer; 04047 void *tmp, *ptr; 04048 struct ast_iax2_meta_trunk_entry *met; 04049 struct ast_iax2_meta_trunk_mini *mtm; 04050 04051 f = &fr->af; 04052 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04053 if (tpeer) { 04054 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04055 /* Need to reallocate space */ 04056 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04057 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04058 ast_mutex_unlock(&tpeer->lock); 04059 return -1; 04060 } 04061 04062 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04063 tpeer->trunkdata = tmp; 04064 if (option_debug) 04065 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); 04066 } else { 04067 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)); 04068 ast_mutex_unlock(&tpeer->lock); 04069 return -1; 04070 } 04071 } 04072 04073 /* Append to meta frame */ 04074 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04075 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04076 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04077 mtm->len = htons(f->datalen); 04078 mtm->mini.callno = htons(pvt->callno); 04079 mtm->mini.ts = htons(0xffff & fr->ts); 04080 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04081 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04082 } else { 04083 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04084 /* Store call number and length in meta header */ 04085 met->callno = htons(pvt->callno); 04086 met->len = htons(f->datalen); 04087 /* Advance pointers/decrease length past trunk entry header */ 04088 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04089 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04090 } 04091 /* Copy actual trunk data */ 04092 memcpy(ptr, f->data, f->datalen); 04093 tpeer->trunkdatalen += f->datalen; 04094 04095 tpeer->calls++; 04096 ast_mutex_unlock(&tpeer->lock); 04097 } 04098 return 0; 04099 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6435 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06436 { 06437 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06438 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4986 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(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04987 { 04988 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04989 int res = -1; 04990 ast_mutex_lock(&iaxsl[callno]); 04991 if (iaxs[callno]) { 04992 /* If there's an outstanding error, return failure now */ 04993 if (!iaxs[callno]->error) { 04994 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04995 res = 0; 04996 /* Don't waste bandwidth sending null frames */ 04997 else if (f->frametype == AST_FRAME_NULL) 04998 res = 0; 04999 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05000 res = 0; 05001 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05002 res = 0; 05003 else 05004 /* Simple, just queue for transmission */ 05005 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05006 } else { 05007 if (option_debug) 05008 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05009 } 05010 } 05011 /* If it's already gone, just return */ 05012 ast_mutex_unlock(&iaxsl[callno]); 05013 return res; 05014 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1895 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().
01896 { 01897 int res = 0; 01898 struct iax_firmware *cur; 01899 if (!ast_strlen_zero(dev)) { 01900 ast_mutex_lock(&waresl.lock); 01901 cur = waresl.wares; 01902 while(cur) { 01903 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01904 res = ntohs(cur->fwh->version); 01905 break; 01906 } 01907 cur = cur->next; 01908 } 01909 ast_mutex_unlock(&waresl.lock); 01910 } 01911 return res; 01912 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 761 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00762 { 00763 if (iaxdebug) 00764 ast_verbose("%s", data); 00765 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 767 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00768 { 00769 ast_log(LOG_WARNING, "%s", data); 00770 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1914 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().
01915 { 01916 int res = -1; 01917 unsigned int bs = desc & 0xff; 01918 unsigned int start = (desc >> 8) & 0xffffff; 01919 unsigned int bytes; 01920 struct iax_firmware *cur; 01921 if (!ast_strlen_zero((char *)dev) && bs) { 01922 start *= bs; 01923 ast_mutex_lock(&waresl.lock); 01924 cur = waresl.wares; 01925 while(cur) { 01926 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01927 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01928 if (start < ntohl(cur->fwh->datalen)) { 01929 bytes = ntohl(cur->fwh->datalen) - start; 01930 if (bytes > bs) 01931 bytes = bs; 01932 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01933 } else { 01934 bytes = 0; 01935 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01936 } 01937 if (bytes == bs) 01938 res = 0; 01939 else 01940 res = 1; 01941 break; 01942 } 01943 cur = cur->next; 01944 } 01945 ast_mutex_unlock(&waresl.lock); 01946 } 01947 return res; 01948 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6706 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, 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().
06707 { 06708 struct iax_dual *d; 06709 struct ast_channel *chan1m, *chan2m; 06710 pthread_t th; 06711 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06712 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06713 if (chan2m && chan1m) { 06714 /* Make formats okay */ 06715 chan1m->readformat = chan1->readformat; 06716 chan1m->writeformat = chan1->writeformat; 06717 ast_channel_masquerade(chan1m, chan1); 06718 /* Setup the extensions and such */ 06719 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06720 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06721 chan1m->priority = chan1->priority; 06722 06723 /* We make a clone of the peer channel too, so we can play 06724 back the announcement */ 06725 /* Make formats okay */ 06726 chan2m->readformat = chan2->readformat; 06727 chan2m->writeformat = chan2->writeformat; 06728 ast_channel_masquerade(chan2m, chan2); 06729 /* Setup the extensions and such */ 06730 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06731 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06732 chan2m->priority = chan2->priority; 06733 if (ast_do_masquerade(chan2m)) { 06734 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06735 ast_hangup(chan2m); 06736 return -1; 06737 } 06738 } else { 06739 if (chan1m) 06740 ast_hangup(chan1m); 06741 if (chan2m) 06742 ast_hangup(chan2m); 06743 return -1; 06744 } 06745 if ((d = ast_calloc(1, sizeof(*d)))) { 06746 pthread_attr_t attr; 06747 06748 pthread_attr_init(&attr); 06749 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06750 06751 d->chan1 = chan1m; 06752 d->chan2 = chan2m; 06753 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06754 pthread_attr_destroy(&attr); 06755 return 0; 06756 } 06757 pthread_attr_destroy(&attr); 06758 free(d); 06759 } 06760 return -1; 06761 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6686 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().
06687 { 06688 struct ast_channel *chan1, *chan2; 06689 struct iax_dual *d; 06690 struct ast_frame *f; 06691 int ext; 06692 int res; 06693 d = stuff; 06694 chan1 = d->chan1; 06695 chan2 = d->chan2; 06696 free(d); 06697 f = ast_read(chan1); 06698 if (f) 06699 ast_frfree(f); 06700 res = ast_park_call(chan1, chan2, 0, &ext); 06701 ast_hangup(chan2); 06702 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06703 return NULL; 06704 }
Definition at line 1409 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().
01410 { 01411 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01412 if (new) { 01413 size_t afdatalen = new->afdatalen; 01414 memcpy(new, fr, sizeof(*new)); 01415 iax_frame_wrap(new, &fr->af); 01416 new->afdatalen = afdatalen; 01417 new->data = NULL; 01418 new->datalen = 0; 01419 new->direction = DIRECTION_INGRESS; 01420 new->retrans = -1; 01421 } 01422 return new; 01423 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 891 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.
Referenced by iax2_process_thread().
00892 { 00893 if (thread->type == IAX_TYPE_DYNAMIC) { 00894 AST_LIST_LOCK(&dynamic_list); 00895 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00896 AST_LIST_UNLOCK(&dynamic_list); 00897 } else { 00898 AST_LIST_LOCK(&idle_list); 00899 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00900 AST_LIST_UNLOCK(&idle_list); 00901 } 00902 00903 return; 00904 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 796 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00797 { 00798 va_list args; 00799 char buf[1024]; 00800 00801 va_start(args, fmt); 00802 vsnprintf(buf, 1024, fmt, args); 00803 va_end(args); 00804 00805 ast_verbose(buf); 00806 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 772 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00773 { 00774 va_list args; 00775 char buf[1024]; 00776 00777 va_start(args, fmt); 00778 vsnprintf(buf, 1024, fmt, args); 00779 va_end(args); 00780 00781 ast_log(LOG_ERROR, buf); 00782 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 784 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00785 { 00786 va_list args; 00787 char buf[1024]; 00788 00789 va_start(args, fmt); 00790 vsnprintf(buf, 1024, fmt, args); 00791 va_end(args); 00792 00793 ast_log(LOG_WARNING, buf); 00794 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11076 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ARRAY_LEN, 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_peercallno_pvts, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, netsock, option_verbose, outsock, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, pvt_cmp_cb(), pvt_hash_cb(), reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
11077 { 11078 char *config = "iax.conf"; 11079 int res = 0; 11080 int x; 11081 struct iax2_registry *reg = NULL; 11082 11083 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11084 if (!peers) 11085 return AST_MODULE_LOAD_FAILURE; 11086 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11087 if (!users) { 11088 ao2_ref(peers, -1); 11089 return AST_MODULE_LOAD_FAILURE; 11090 } 11091 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11092 if (!iax_peercallno_pvts) { 11093 ao2_ref(peers, -1); 11094 ao2_ref(users, -1); 11095 return AST_MODULE_LOAD_FAILURE; 11096 } 11097 11098 ast_custom_function_register(&iaxpeer_function); 11099 11100 iax_set_output(iax_debug_output); 11101 iax_set_error(iax_error_output); 11102 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11103 11104 #ifdef HAVE_ZAPTEL 11105 #ifdef ZT_TIMERACK 11106 timingfd = open("/dev/zap/timer", O_RDWR); 11107 if (timingfd < 0) 11108 #endif 11109 timingfd = open("/dev/zap/pseudo", O_RDWR); 11110 if (timingfd < 0) 11111 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11112 #endif 11113 11114 memset(iaxs, 0, sizeof(iaxs)); 11115 11116 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11117 ast_mutex_init(&iaxsl[x]); 11118 } 11119 11120 ast_cond_init(&sched_cond, NULL); 11121 11122 io = io_context_create(); 11123 sched = sched_context_create(); 11124 11125 if (!io || !sched) { 11126 ast_log(LOG_ERROR, "Out of memory\n"); 11127 return -1; 11128 } 11129 11130 netsock = ast_netsock_list_alloc(); 11131 if (!netsock) { 11132 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11133 return -1; 11134 } 11135 ast_netsock_init(netsock); 11136 11137 outsock = ast_netsock_list_alloc(); 11138 if (!outsock) { 11139 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11140 return -1; 11141 } 11142 ast_netsock_init(outsock); 11143 11144 ast_mutex_init(&waresl.lock); 11145 11146 AST_LIST_HEAD_INIT(&iaxq.queue); 11147 11148 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11149 11150 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11151 11152 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11153 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11154 11155 if(set_config(config, 0) == -1) 11156 return AST_MODULE_LOAD_DECLINE; 11157 11158 if (ast_channel_register(&iax2_tech)) { 11159 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11160 __unload_module(); 11161 return -1; 11162 } 11163 11164 if (ast_register_switch(&iax2_switch)) 11165 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11166 11167 res = start_network_thread(); 11168 if (!res) { 11169 if (option_verbose > 1) 11170 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11171 } else { 11172 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11173 ast_netsock_release(netsock); 11174 ast_netsock_release(outsock); 11175 } 11176 11177 AST_LIST_LOCK(®istrations); 11178 AST_LIST_TRAVERSE(®istrations, reg, entry) 11179 iax2_do_register(reg); 11180 AST_LIST_UNLOCK(®istrations); 11181 11182 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11183 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11184 11185 reload_firmware(0); 11186 iax_provision_reload(); 11187 return res; 11188 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3461 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03462 { 03463 ast_mutex_lock(&iaxsl[callno0]); 03464 while (ast_mutex_trylock(&iaxsl[callno1])) { 03465 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03466 } 03467 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1463 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_sched_add(), iaxsl, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01464 { 01465 int x; 01466 int res= 0; 01467 struct timeval now; 01468 if (iaxs[callno]->oseqno) { 01469 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01470 return -1; 01471 } 01472 if (callno & TRUNK_CALL_START) { 01473 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01474 return -1; 01475 } 01476 gettimeofday(&now, NULL); 01477 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01478 ast_mutex_lock(&iaxsl[x]); 01479 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01480 iaxs[x] = iaxs[callno]; 01481 iaxs[x]->callno = x; 01482 iaxs[callno] = NULL; 01483 /* Update the two timers that should have been started */ 01484 AST_SCHED_DEL(sched, iaxs[x]->pingid); 01485 AST_SCHED_DEL(sched, iaxs[x]->lagid); 01486 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01487 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01488 if (locked) 01489 ast_mutex_unlock(&iaxsl[callno]); 01490 res = x; 01491 if (!locked) 01492 ast_mutex_unlock(&iaxsl[x]); 01493 break; 01494 } 01495 ast_mutex_unlock(&iaxsl[x]); 01496 } 01497 if (x >= ARRAY_LEN(iaxs) - 1) { 01498 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01499 return -1; 01500 } 01501 if (option_debug) 01502 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01503 /* We move this call from a non-trunked to a trunked call */ 01504 update_max_trunk(); 01505 update_max_nontrunk(); 01506 return res; 01507 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4700 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04701 { 04702 ast_cli_netstats(s, -1, 0); 04703 astman_append(s, "\r\n"); 04704 return RESULT_SUCCESS; 04705 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4733 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04734 { 04735 char *a[] = { "iax2", "show", "users" }; 04736 int ret; 04737 const char *id = astman_get_header(m,"ActionID"); 04738 04739 if (!ast_strlen_zero(id)) 04740 astman_append(s, "ActionID: %s\r\n",id); 04741 ret = __iax2_show_peers(1, -1, s, 3, a ); 04742 astman_append(s, "\r\n\r\n" ); 04743 return ret; 04744 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1429 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and softhangup_exec().
01430 { 01431 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01432 (cur->addr.sin_port == sin->sin_port)) { 01433 /* This is the main host */ 01434 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01435 (check_dcallno ? dcallno == cur->callno : 1) ) { 01436 /* That's us. Be sure we keep track of the peer call number */ 01437 return 1; 01438 } 01439 } 01440 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01441 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01442 /* We're transferring */ 01443 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01444 return 1; 01445 } 01446 return 0; 01447 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4107 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04108 { 04109 #if 0 04110 /* Debug with "fake encryption" */ 04111 int x; 04112 if (len % 16) 04113 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04114 for (x=0;x<len;x++) 04115 dst[x] = src[x] ^ 0xff; 04116 #else 04117 unsigned char lastblock[16] = { 0 }; 04118 int x; 04119 while(len > 0) { 04120 aes_decrypt(src, dst, dcx); 04121 for (x=0;x<16;x++) 04122 dst[x] ^= lastblock[x]; 04123 memcpy(lastblock, src, sizeof(lastblock)); 04124 dst += 16; 04125 src += 16; 04126 len -= 16; 04127 } 04128 #endif 04129 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4131 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04132 { 04133 #if 0 04134 /* Debug with "fake encryption" */ 04135 int x; 04136 if (len % 16) 04137 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04138 for (x=0;x<len;x++) 04139 dst[x] = src[x] ^ 0xff; 04140 #else 04141 unsigned char curblock[16] = { 0 }; 04142 int x; 04143 while(len > 0) { 04144 for (x=0;x<16;x++) 04145 curblock[x] ^= src[x]; 04146 aes_encrypt(curblock, dst, ecx); 04147 memcpy(curblock, dst, sizeof(curblock)); 04148 dst += 16; 04149 src += 16; 04150 len -= 16; 04151 } 04152 #endif 04153 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5311 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05312 { 05313 /* Select exactly one common encryption if there are any */ 05314 p->encmethods &= enc; 05315 if (p->encmethods) { 05316 if (p->encmethods & IAX_ENCRYPT_AES128) 05317 p->encmethods = IAX_ENCRYPT_AES128; 05318 else 05319 p->encmethods = 0; 05320 } 05321 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9049 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(), f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, option_debug, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
09050 { 09051 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09052 from the network, and queue them for delivery to the channels */ 09053 int res, count, wakeup; 09054 struct iax_frame *f; 09055 09056 if (timingfd > -1) 09057 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09058 09059 for(;;) { 09060 pthread_testcancel(); 09061 09062 /* Go through the queue, sending messages which have not yet been 09063 sent, and scheduling retransmissions if appropriate */ 09064 AST_LIST_LOCK(&iaxq.queue); 09065 count = 0; 09066 wakeup = -1; 09067 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09068 if (f->sentyet) 09069 continue; 09070 09071 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09072 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09073 wakeup = 1; 09074 continue; 09075 } 09076 09077 f->sentyet++; 09078 09079 if (iaxs[f->callno]) { 09080 send_packet(f); 09081 count++; 09082 } 09083 09084 ast_mutex_unlock(&iaxsl[f->callno]); 09085 09086 if (f->retries < 0) { 09087 /* This is not supposed to be retransmitted */ 09088 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09089 iaxq.count--; 09090 /* Free the iax frame */ 09091 iax_frame_free(f); 09092 } else { 09093 /* We need reliable delivery. Schedule a retransmission */ 09094 f->retries++; 09095 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09096 } 09097 } 09098 AST_LIST_TRAVERSE_SAFE_END 09099 AST_LIST_UNLOCK(&iaxq.queue); 09100 09101 pthread_testcancel(); 09102 09103 if (option_debug && count >= 20) 09104 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09105 09106 /* Now do the IO, and run scheduled tasks */ 09107 res = ast_io_wait(io, wakeup); 09108 if (res >= 0) { 09109 if (option_debug && res >= 20) 09110 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09111 } 09112 } 09113 return NULL; 09114 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1370 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), and jb_conf::resync_threshold.
Referenced by __find_callno().
01371 { 01372 struct chan_iax2_pvt *tmp; 01373 jb_conf jbconf; 01374 01375 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01376 return NULL; 01377 } 01378 01379 if (ast_string_field_init(tmp, 32)) { 01380 ao2_ref(tmp, -1); 01381 tmp = NULL; 01382 return NULL; 01383 } 01384 01385 tmp->prefs = prefs; 01386 tmp->callno = 0; 01387 tmp->peercallno = 0; 01388 tmp->transfercallno = 0; 01389 tmp->bridgecallno = 0; 01390 tmp->pingid = -1; 01391 tmp->lagid = -1; 01392 tmp->autoid = -1; 01393 tmp->authid = -1; 01394 tmp->initid = -1; 01395 01396 ast_string_field_set(tmp,exten, "s"); 01397 ast_string_field_set(tmp,host, host); 01398 01399 tmp->jb = jb_new(); 01400 tmp->jbid = -1; 01401 jbconf.max_jitterbuf = maxjitterbuffer; 01402 jbconf.resync_threshold = resyncthreshold; 01403 jbconf.max_contig_interp = maxjitterinterps; 01404 jb_setconf(tmp->jb,&jbconf); 01405 01406 return tmp; 01407 }
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 3180 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().
03181 { 03182 if (ast_strlen_zero(data)) 03183 return; 03184 03185 pds->peer = strsep(&data, "/"); 03186 pds->exten = strsep(&data, "/"); 03187 pds->options = data; 03188 03189 if (pds->exten) { 03190 data = pds->exten; 03191 pds->exten = strsep(&data, "@"); 03192 pds->context = data; 03193 } 03194 03195 if (strchr(pds->peer, '@')) { 03196 data = pds->peer; 03197 pds->username = strsep(&data, "@"); 03198 pds->peer = data; 03199 } 03200 03201 if (pds->username) { 03202 data = pds->username; 03203 pds->username = strsep(&data, ":"); 03204 pds->password = data; 03205 } 03206 03207 data = pds->peer; 03208 pds->peer = strsep(&data, ":"); 03209 pds->port = data; 03210 03211 /* check for a key name wrapped in [] in the secret position, if found, 03212 move it to the key field instead 03213 */ 03214 if (pds->password && (pds->password[0] == '[')) { 03215 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03216 pds->password = NULL; 03217 } 03218 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1108 of file chan_iax2.c.
Referenced by load_module().
01109 { 01110 struct iax2_peer *peer = obj, *peer2 = arg; 01111 01112 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01113 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9747 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09748 { 09749 struct iax2_peer *peer = obj; 09750 09751 ast_set_flag(peer, IAX_DELME); 09752 09753 return 0; 09754 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9272 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().
09273 { 09274 struct iax2_peer *peer = obj; 09275 09276 ast_free_ha(peer->ha); 09277 09278 if (peer->callno > 0) { 09279 ast_mutex_lock(&iaxsl[peer->callno]); 09280 iax2_destroy(peer->callno); 09281 ast_mutex_unlock(&iaxsl[peer->callno]); 09282 } 09283 09284 register_peer_exten(peer, 0); 09285 09286 if (peer->dnsmgr) 09287 ast_dnsmgr_release(peer->dnsmgr); 09288 09289 ast_string_field_free_memory(peer); 09290 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1098 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01099 { 01100 const struct iax2_peer *peer = obj; 01101 01102 return ast_str_hash(peer->name); 01103 }
Definition at line 1155 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), reg_source_db(), socket_process(), and update_registry().
01156 { 01157 ao2_ref(peer, +1); 01158 return peer; 01159 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11047 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11048 { 11049 struct iax2_peer *peer = obj; 11050 11051 if (peer->sockfd < 0) 11052 peer->sockfd = defaultsockfd; 11053 11054 return 0; 11055 }
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 9199 of file chan_iax2.c.
References ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, netsock, option_debug, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
09200 { 09201 struct sockaddr_in sin; 09202 int nonlocal = 1; 09203 int port = IAX_DEFAULT_PORTNO; 09204 int sockfd = defaultsockfd; 09205 char *tmp; 09206 char *addr; 09207 char *portstr; 09208 09209 if (!(tmp = ast_strdupa(srcaddr))) 09210 return -1; 09211 09212 addr = strsep(&tmp, ":"); 09213 portstr = tmp; 09214 09215 if (portstr) { 09216 port = atoi(portstr); 09217 if (port < 1) 09218 port = IAX_DEFAULT_PORTNO; 09219 } 09220 09221 if (!ast_get_ip(&sin, addr)) { 09222 struct ast_netsock *sock; 09223 int res; 09224 09225 sin.sin_port = 0; 09226 sin.sin_family = AF_INET; 09227 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09228 if (res == 0) { 09229 /* ip address valid. */ 09230 sin.sin_port = htons(port); 09231 if (!(sock = ast_netsock_find(netsock, &sin))) 09232 sock = ast_netsock_find(outsock, &sin); 09233 if (sock) { 09234 sockfd = ast_netsock_sockfd(sock); 09235 nonlocal = 0; 09236 } else { 09237 unsigned int orig_saddr = sin.sin_addr.s_addr; 09238 /* INADDR_ANY matches anyway! */ 09239 sin.sin_addr.s_addr = INADDR_ANY; 09240 if (ast_netsock_find(netsock, &sin)) { 09241 sin.sin_addr.s_addr = orig_saddr; 09242 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09243 if (sock) { 09244 sockfd = ast_netsock_sockfd(sock); 09245 ast_netsock_unref(sock); 09246 nonlocal = 0; 09247 } else { 09248 nonlocal = 2; 09249 } 09250 } 09251 } 09252 } 09253 } 09254 09255 peer->sockfd = sockfd; 09256 09257 if (nonlocal == 1) { 09258 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09259 srcaddr, peer->name); 09260 return -1; 09261 } else if (nonlocal == 2) { 09262 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09263 srcaddr, peer->name); 09264 return -1; 09265 } else { 09266 if (option_debug) 09267 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09268 return 0; 09269 } 09270 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2307 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().
02308 { 02309 int res = 0; 02310 if (peer->maxms) { 02311 if (peer->lastms < 0) { 02312 ast_copy_string(status, "UNREACHABLE", statuslen); 02313 } else if (peer->lastms > peer->maxms) { 02314 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02315 res = 1; 02316 } else if (peer->lastms) { 02317 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02318 res = 1; 02319 } else { 02320 ast_copy_string(status, "UNKNOWN", statuslen); 02321 } 02322 } else { 02323 ast_copy_string(status, "Unmonitored", statuslen); 02324 res = -1; 02325 } 02326 return res; 02327 }
Definition at line 1161 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(), reg_source_db(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01162 { 01163 ao2_ref(peer, -1); 01164 return NULL; 01165 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10208 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10209 { 10210 struct ao2_iterator i; 10211 struct iax2_peer *peer; 10212 10213 i = ao2_iterator_init(peers, 0); 10214 while ((peer = ao2_iterator_next(&i))) { 10215 iax2_poke_peer(peer, 0); 10216 peer_unref(peer); 10217 } 10218 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9805 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09806 { 09807 struct iax2_peer *peer; 09808 struct ao2_iterator i; 09809 09810 i = ao2_iterator_init(peers, 0); 09811 while ((peer = ao2_iterator_next(&i))) { 09812 if (ast_test_flag(peer, IAX_DELME)) 09813 unlink_peer(peer); 09814 peer_unref(peer); 09815 } 09816 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9791 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().
09792 { 09793 struct iax2_user *user; 09794 struct ao2_iterator i; 09795 09796 i = ao2_iterator_init(users, 0); 09797 while ((user = ao2_iterator_next(&i))) { 09798 if (ast_test_flag(user, IAX_DELME)) 09799 ao2_unlink(users, user); 09800 user_unref(user); 09801 } 09802 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11064 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11065 { 11066 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11067 11068 /* The frames_received field is used to hold whether we're matching 11069 * against a full frame or not ... */ 11070 11071 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11072 pvt2->frames_received) ? CMP_MATCH : 0; 11073 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1331 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and chan_iax2_pvt::vars.
Referenced by new_iax().
01332 { 01333 struct chan_iax2_pvt *pvt = obj; 01334 struct iax_frame *cur = NULL; 01335 01336 iax2_destroy_helper(pvt); 01337 01338 /* Already gone */ 01339 ast_set_flag(pvt, IAX_ALREADYGONE); 01340 01341 AST_LIST_LOCK(&iaxq.queue); 01342 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01343 /* Cancel any pending transmissions */ 01344 if (cur->callno == pvt->callno) { 01345 cur->retries = -1; 01346 } 01347 } 01348 AST_LIST_UNLOCK(&iaxq.queue); 01349 01350 if (pvt->reg) { 01351 pvt->reg->callno = 0; 01352 } 01353 01354 if (!pvt->owner) { 01355 jb_frame frame; 01356 if (pvt->vars) { 01357 ast_variables_destroy(pvt->vars); 01358 pvt->vars = NULL; 01359 } 01360 01361 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01362 iax2_frame_free(frame.data); 01363 } 01364 01365 jb_destroy(pvt->jb); 01366 ast_string_field_free_memory(pvt); 01367 } 01368 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11057 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11058 { 11059 const struct chan_iax2_pvt *pvt = obj; 11060 11061 return pvt->peercallno; 11062 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5293 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
05294 { 05295 struct ast_iax2_full_hdr fh; 05296 fh.scallno = htons(src | IAX_FLAG_FULL); 05297 fh.dcallno = htons(dst); 05298 fh.ts = 0; 05299 fh.oseqno = 0; 05300 fh.iseqno = 0; 05301 fh.type = AST_FRAME_IAX; 05302 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05303 if (iaxdebug) 05304 iax_showframe(NULL, &fh, 0, sin, 0); 05305 if (option_debug) 05306 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05307 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05308 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05309 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2782 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02783 { 02784 struct ast_variable *var = NULL; 02785 struct ast_variable *tmp; 02786 struct iax2_peer *peer=NULL; 02787 time_t regseconds = 0, nowtime; 02788 int dynamic=0; 02789 02790 if (peername) { 02791 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02792 if (!var && sin) 02793 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02794 } else if (sin) { 02795 char porta[25]; 02796 sprintf(porta, "%d", ntohs(sin->sin_port)); 02797 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02798 if (var) { 02799 /* We'll need the peer name in order to build the structure! */ 02800 for (tmp = var; tmp; tmp = tmp->next) { 02801 if (!strcasecmp(tmp->name, "name")) 02802 peername = tmp->value; 02803 } 02804 } 02805 } 02806 if (!var && peername) { /* Last ditch effort */ 02807 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02808 /*!\note 02809 * If this one loaded something, then we need to ensure that the host 02810 * field matched. The only reason why we can't have this as a criteria 02811 * is because we only have the IP address and the host field might be 02812 * set as a name (and the reverse PTR might not match). 02813 */ 02814 if (var && sin) { 02815 for (tmp = var; tmp; tmp = tmp->next) { 02816 if (!strcasecmp(tmp->name, "host")) { 02817 struct ast_hostent ahp; 02818 struct hostent *hp; 02819 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02820 /* No match */ 02821 ast_variables_destroy(var); 02822 var = NULL; 02823 } 02824 break; 02825 } 02826 } 02827 } 02828 } 02829 if (!var) 02830 return NULL; 02831 02832 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02833 02834 if (!peer) { 02835 ast_variables_destroy(var); 02836 return NULL; 02837 } 02838 02839 for (tmp = var; tmp; tmp = tmp->next) { 02840 /* Make sure it's not a user only... */ 02841 if (!strcasecmp(tmp->name, "type")) { 02842 if (strcasecmp(tmp->value, "friend") && 02843 strcasecmp(tmp->value, "peer")) { 02844 /* Whoops, we weren't supposed to exist! */ 02845 peer = peer_unref(peer); 02846 break; 02847 } 02848 } else if (!strcasecmp(tmp->name, "regseconds")) { 02849 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02850 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02851 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02852 } else if (!strcasecmp(tmp->name, "port")) { 02853 peer->addr.sin_port = htons(atoi(tmp->value)); 02854 } else if (!strcasecmp(tmp->name, "host")) { 02855 if (!strcasecmp(tmp->value, "dynamic")) 02856 dynamic = 1; 02857 } 02858 } 02859 02860 ast_variables_destroy(var); 02861 02862 if (!peer) 02863 return NULL; 02864 02865 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02866 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02867 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02868 if (peer->expire > -1) { 02869 if (!ast_sched_del(sched, peer->expire)) { 02870 peer->expire = -1; 02871 peer_unref(peer); 02872 } 02873 } 02874 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02875 if (peer->expire == -1) 02876 peer_unref(peer); 02877 } 02878 ao2_link(peers, peer); 02879 if (ast_test_flag(peer, IAX_DYNAMIC)) 02880 reg_source_db(peer); 02881 } else { 02882 ast_set_flag(peer, IAX_TEMPONLY); 02883 } 02884 02885 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02886 time(&nowtime); 02887 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02888 memset(&peer->addr, 0, sizeof(peer->addr)); 02889 realtime_update_peer(peer->name, &peer->addr, 0); 02890 if (option_debug) 02891 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02892 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02893 } 02894 else { 02895 if (option_debug) 02896 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02897 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02898 } 02899 } 02900 02901 return peer; 02902 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2975 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02976 { 02977 char port[10]; 02978 char regseconds[20]; 02979 02980 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02981 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02982 ast_update_realtime("iaxpeers", "name", peername, 02983 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02984 "regseconds", regseconds, NULL); 02985 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2904 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02905 { 02906 struct ast_variable *var; 02907 struct ast_variable *tmp; 02908 struct iax2_user *user=NULL; 02909 02910 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02911 if (!var) 02912 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02913 if (!var && sin) { 02914 char porta[6]; 02915 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02916 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02917 if (!var) 02918 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02919 } 02920 if (!var) { /* Last ditch effort */ 02921 var = ast_load_realtime("iaxusers", "name", username, NULL); 02922 /*!\note 02923 * If this one loaded something, then we need to ensure that the host 02924 * field matched. The only reason why we can't have this as a criteria 02925 * is because we only have the IP address and the host field might be 02926 * set as a name (and the reverse PTR might not match). 02927 */ 02928 if (var) { 02929 for (tmp = var; tmp; tmp = tmp->next) { 02930 if (!strcasecmp(tmp->name, "host")) { 02931 struct ast_hostent ahp; 02932 struct hostent *hp; 02933 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02934 /* No match */ 02935 ast_variables_destroy(var); 02936 var = NULL; 02937 } 02938 break; 02939 } 02940 } 02941 } 02942 } 02943 if (!var) 02944 return NULL; 02945 02946 tmp = var; 02947 while(tmp) { 02948 /* Make sure it's not a peer only... */ 02949 if (!strcasecmp(tmp->name, "type")) { 02950 if (strcasecmp(tmp->value, "friend") && 02951 strcasecmp(tmp->value, "user")) { 02952 return NULL; 02953 } 02954 } 02955 tmp = tmp->next; 02956 } 02957 02958 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02959 02960 ast_variables_destroy(var); 02961 02962 if (!user) 02963 return NULL; 02964 02965 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02966 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02967 ao2_link(users, user); 02968 } else { 02969 ast_set_flag(user, IAX_TEMPONLY); 02970 } 02971 02972 return user; 02973 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6074 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(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
06075 { 06076 char data[80]; 06077 struct in_addr in; 06078 char *c, *d; 06079 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06080 c = strchr(data, ':'); 06081 if (c) { 06082 *c = '\0'; 06083 c++; 06084 if (inet_aton(data, &in)) { 06085 d = strchr(c, ':'); 06086 if (d) { 06087 *d = '\0'; 06088 d++; 06089 if (option_verbose > 2) 06090 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06091 ast_inet_ntoa(in), atoi(c), atoi(d)); 06092 iax2_poke_peer(p, 0); 06093 p->expiry = atoi(d); 06094 memset(&p->addr, 0, sizeof(p->addr)); 06095 p->addr.sin_family = AF_INET; 06096 p->addr.sin_addr = in; 06097 p->addr.sin_port = htons(atoi(c)); 06098 if (p->expire > -1) { 06099 if (!ast_sched_del(sched, p->expire)) { 06100 p->expire = -1; 06101 peer_unref(p); 06102 } 06103 } 06104 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06105 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06106 if (p->expire == -1) 06107 peer_unref(p); 06108 if (iax2_regfunk) 06109 iax2_regfunk(p->name, 1); 06110 register_peer_exten(p, 1); 06111 } 06112 06113 } 06114 } 06115 } 06116 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5994 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().
05995 { 05996 char multi[256]; 05997 char *stringp, *ext; 05998 if (!ast_strlen_zero(regcontext)) { 05999 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06000 stringp = multi; 06001 while((ext = strsep(&stringp, "&"))) { 06002 if (onoff) { 06003 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06004 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06005 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06006 } else 06007 ast_context_remove_extension(regcontext, ext, 1, NULL); 06008 } 06009 } 06010 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5457 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, iaxs, iaxsl, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by handle_request_register(), and socket_process().
05458 { 05459 char requeststr[256] = ""; 05460 char peer[256] = ""; 05461 char md5secret[256] = ""; 05462 char rsasecret[256] = ""; 05463 char secret[256] = ""; 05464 struct iax2_peer *p = NULL; 05465 struct ast_key *key; 05466 char *keyn; 05467 int x; 05468 int expire = 0; 05469 int res = -1; 05470 05471 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05472 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05473 if (ies->username) 05474 ast_copy_string(peer, ies->username, sizeof(peer)); 05475 if (ies->password) 05476 ast_copy_string(secret, ies->password, sizeof(secret)); 05477 if (ies->md5_result) 05478 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05479 if (ies->rsa_result) 05480 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05481 if (ies->refresh) 05482 expire = ies->refresh; 05483 05484 if (ast_strlen_zero(peer)) { 05485 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05486 return -1; 05487 } 05488 05489 /* SLD: first call to lookup peer during registration */ 05490 ast_mutex_unlock(&iaxsl[callno]); 05491 p = find_peer(peer, 1); 05492 ast_mutex_lock(&iaxsl[callno]); 05493 if (!p || !iaxs[callno]) { 05494 if (authdebug && !p) 05495 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05496 goto return_unref; 05497 } 05498 05499 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05500 if (authdebug) 05501 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05502 goto return_unref; 05503 } 05504 05505 if (!ast_apply_ha(p->ha, sin)) { 05506 if (authdebug) 05507 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05508 goto return_unref; 05509 } 05510 if (!inaddrcmp(&p->addr, sin)) 05511 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05512 ast_string_field_set(iaxs[callno], secret, p->secret); 05513 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05514 /* Check secret against what we have on file */ 05515 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05516 if (!ast_strlen_zero(p->inkeys)) { 05517 char tmpkeys[256]; 05518 char *stringp=NULL; 05519 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05520 stringp=tmpkeys; 05521 keyn = strsep(&stringp, ":"); 05522 while(keyn) { 05523 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05524 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05525 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05526 break; 05527 } else if (!key) 05528 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05529 keyn = strsep(&stringp, ":"); 05530 } 05531 if (!keyn) { 05532 if (authdebug) 05533 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05534 goto return_unref; 05535 } 05536 } else { 05537 if (authdebug) 05538 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05539 goto return_unref; 05540 } 05541 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05542 struct MD5Context md5; 05543 unsigned char digest[16]; 05544 char *tmppw, *stringp; 05545 05546 tmppw = ast_strdupa(p->secret); 05547 stringp = tmppw; 05548 while((tmppw = strsep(&stringp, ";"))) { 05549 MD5Init(&md5); 05550 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05551 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05552 MD5Final(digest, &md5); 05553 for (x=0;x<16;x++) 05554 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05555 if (!strcasecmp(requeststr, md5secret)) 05556 break; 05557 } 05558 if (tmppw) { 05559 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05560 } else { 05561 if (authdebug) 05562 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05563 goto return_unref; 05564 } 05565 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05566 /* They've provided a plain text password and we support that */ 05567 if (strcmp(secret, p->secret)) { 05568 if (authdebug) 05569 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05570 goto return_unref; 05571 } else 05572 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05573 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05574 if (authdebug) 05575 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05576 goto return_unref; 05577 } 05578 ast_string_field_set(iaxs[callno], peer, peer); 05579 /* Choose lowest expiry number */ 05580 if (expire && (expire < iaxs[callno]->expiry)) 05581 iaxs[callno]->expiry = expire; 05582 05583 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05584 05585 res = 0; 05586 05587 return_unref: 05588 if (p) 05589 peer_unref(p); 05590 05591 return res; 05592 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6253 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, 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(), and send_command().
Referenced by socket_process().
06254 { 06255 struct iax_ie_data ied; 06256 struct iax2_peer *p; 06257 char challenge[10]; 06258 const char *peer_name; 06259 int res = -1; 06260 06261 peer_name = ast_strdupa(iaxs[callno]->peer); 06262 06263 /* SLD: third call to find_peer in registration */ 06264 ast_mutex_unlock(&iaxsl[callno]); 06265 p = find_peer(peer_name, 1); 06266 ast_mutex_lock(&iaxsl[callno]); 06267 if (!iaxs[callno]) 06268 goto return_unref; 06269 if (!p) { 06270 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06271 goto return_unref; 06272 } 06273 06274 memset(&ied, 0, sizeof(ied)); 06275 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06276 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06277 /* Build the challenge */ 06278 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06279 ast_string_field_set(iaxs[callno], challenge, challenge); 06280 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06281 } 06282 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06283 06284 res = 0; 06285 06286 return_unref: 06287 peer_unref(p); 06288 06289 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 06290 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6292 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_process().
06293 { 06294 struct iax2_registry *reg; 06295 /* Start pessimistic */ 06296 struct iax_ie_data ied; 06297 char peer[256] = ""; 06298 char challenge[256] = ""; 06299 int res; 06300 int authmethods = 0; 06301 if (ies->authmethods) 06302 authmethods = ies->authmethods; 06303 if (ies->username) 06304 ast_copy_string(peer, ies->username, sizeof(peer)); 06305 if (ies->challenge) 06306 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06307 memset(&ied, 0, sizeof(ied)); 06308 reg = iaxs[callno]->reg; 06309 if (reg) { 06310 if (inaddrcmp(®->addr, sin)) { 06311 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06312 return -1; 06313 } 06314 if (ast_strlen_zero(reg->secret)) { 06315 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06316 reg->regstate = REG_STATE_NOAUTH; 06317 return -1; 06318 } 06319 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06320 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06321 if (reg->secret[0] == '[') { 06322 char tmpkey[256]; 06323 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06324 tmpkey[strlen(tmpkey) - 1] = '\0'; 06325 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06326 } else 06327 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06328 if (!res) { 06329 reg->regstate = REG_STATE_AUTHSENT; 06330 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06331 } else 06332 return -1; 06333 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06334 } else 06335 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06336 return -1; 06337 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4746 of file chan_iax2.c.
References REG_STATE_AUTHSENT, 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().
04747 { 04748 switch(regstate) { 04749 case REG_STATE_UNREGISTERED: 04750 return "Unregistered"; 04751 case REG_STATE_REGSENT: 04752 return "Request Sent"; 04753 case REG_STATE_AUTHSENT: 04754 return "Auth. Sent"; 04755 case REG_STATE_REGISTERED: 04756 return "Registered"; 04757 case REG_STATE_REJECTED: 04758 return "Rejected"; 04759 case REG_STATE_TIMEOUT: 04760 return "Timeout"; 04761 case REG_STATE_NOAUTH: 04762 return "No Authentication"; 04763 default: 04764 return "Unknown"; 04765 } 04766 }
static int reload | ( | void | ) | [static] |
Definition at line 10245 of file chan_iax2.c.
References reload_config().
10246 { 10247 return reload_config(); 10248 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10219 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().
10220 { 10221 char *config = "iax.conf"; 10222 struct iax2_registry *reg; 10223 10224 if (set_config(config, 1) > 0) { 10225 prune_peers(); 10226 prune_users(); 10227 AST_LIST_LOCK(®istrations); 10228 AST_LIST_TRAVERSE(®istrations, reg, entry) 10229 iax2_do_register(reg); 10230 AST_LIST_UNLOCK(®istrations); 10231 /* Qualify hosts, too */ 10232 poke_all_peers(); 10233 } 10234 reload_firmware(0); 10235 iax_provision_reload(); 10236 10237 return 0; 10238 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1951 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().
01952 { 01953 struct iax_firmware *cur, *curl, *curp; 01954 DIR *fwd; 01955 struct dirent *de; 01956 char dir[256]; 01957 char fn[256]; 01958 /* Mark all as dead */ 01959 ast_mutex_lock(&waresl.lock); 01960 cur = waresl.wares; 01961 while(cur) { 01962 cur->dead = 1; 01963 cur = cur->next; 01964 } 01965 01966 /* Now that we've freed them, load the new ones */ 01967 if (!unload) { 01968 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01969 fwd = opendir(dir); 01970 if (fwd) { 01971 while((de = readdir(fwd))) { 01972 if (de->d_name[0] != '.') { 01973 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01974 if (!try_firmware(fn)) { 01975 if (option_verbose > 1) 01976 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01977 } 01978 } 01979 } 01980 closedir(fwd); 01981 } else 01982 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01983 } 01984 01985 /* Clean up leftovers */ 01986 cur = waresl.wares; 01987 curp = NULL; 01988 while(cur) { 01989 curl = cur; 01990 cur = cur->next; 01991 if (curl->dead) { 01992 if (curp) { 01993 curp->next = cur; 01994 } else { 01995 waresl.wares = cur; 01996 } 01997 destroy_firmware(curl); 01998 } else { 01999 curp = cur; 02000 } 02001 } 02002 ast_mutex_unlock(&waresl.lock); 02003 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1246 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), and socket_process().
01247 { 01248 if (!pvt->peercallno) { 01249 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01250 return; 01251 } 01252 01253 ao2_unlink(iax_peercallno_pvts, pvt); 01254 }
Definition at line 6796 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
06797 { 06798 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06799 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06800 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06801 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06802 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06803 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06804 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06805 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9021 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(), option_debug, and sched.
Referenced by start_network_thread().
09022 { 09023 int count; 09024 int res; 09025 struct timeval tv; 09026 struct timespec ts; 09027 09028 for (;;) { 09029 res = ast_sched_wait(sched); 09030 if ((res > 1000) || (res < 0)) 09031 res = 1000; 09032 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09033 ts.tv_sec = tv.tv_sec; 09034 ts.tv_nsec = tv.tv_usec * 1000; 09035 09036 pthread_testcancel(); 09037 ast_mutex_lock(&sched_lock); 09038 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09039 ast_mutex_unlock(&sched_lock); 09040 pthread_testcancel(); 09041 09042 count = ast_sched_runq(sched); 09043 if (option_debug && count >= 20) 09044 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09045 } 09046 return NULL; 09047 }
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 2635 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, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, len, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_channel::tech, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02636 { 02637 int type, len; 02638 int ret; 02639 int needfree = 0; 02640 struct ast_channel *owner = NULL; 02641 struct ast_channel *bridge = NULL; 02642 02643 /* Attempt to recover wrapped timestamps */ 02644 unwrap_timestamp(fr); 02645 02646 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02647 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02648 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02649 else { 02650 #if 0 02651 if (option_debug) 02652 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02653 #endif 02654 fr->af.delivery = ast_tv(0,0); 02655 } 02656 02657 type = JB_TYPE_CONTROL; 02658 len = 0; 02659 02660 if(fr->af.frametype == AST_FRAME_VOICE) { 02661 type = JB_TYPE_VOICE; 02662 len = ast_codec_get_samples(&fr->af) / 8; 02663 } else if(fr->af.frametype == AST_FRAME_CNG) { 02664 type = JB_TYPE_SILENCE; 02665 } 02666 02667 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02668 if (tsout) 02669 *tsout = fr->ts; 02670 __do_deliver(fr); 02671 return -1; 02672 } 02673 02674 if ((owner = iaxs[fr->callno]->owner)) 02675 bridge = ast_bridged_channel(owner); 02676 02677 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02678 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02679 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02680 jb_frame frame; 02681 02682 /* deliver any frames in the jb */ 02683 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02684 __do_deliver(frame.data); 02685 /* __do_deliver() can make the call disappear */ 02686 if (!iaxs[fr->callno]) 02687 return -1; 02688 } 02689 02690 jb_reset(iaxs[fr->callno]->jb); 02691 02692 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02693 02694 /* deliver this frame now */ 02695 if (tsout) 02696 *tsout = fr->ts; 02697 __do_deliver(fr); 02698 return -1; 02699 } 02700 02701 /* insert into jitterbuffer */ 02702 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02703 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02704 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02705 if (ret == JB_DROP) { 02706 needfree++; 02707 } else if (ret == JB_SCHED) { 02708 update_jbsched(iaxs[fr->callno]); 02709 } 02710 if (tsout) 02711 *tsout = fr->ts; 02712 if (needfree) { 02713 /* Free our iax frame */ 02714 iax2_frame_free(fr); 02715 return -1; 02716 } 02717 return 0; 02718 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno | |||
) | [static] |
Definition at line 3153 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and f.
Referenced by socket_process().
03154 { 03155 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03156 .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX, 03157 .csub = compress_subclass(command) }; 03158 03159 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03160 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5030 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().
05031 { 05032 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05033 }
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 5049 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().
05050 { 05051 int call_num = i->callno; 05052 /* It is assumed that the callno has already been locked */ 05053 iax2_predestroy(i->callno); 05054 if (!iaxs[call_num]) 05055 return -1; 05056 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05057 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5059 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05060 { 05061 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05062 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5035 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().
05036 { 05037 int res; 05038 ast_mutex_lock(&iaxsl[callno]); 05039 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05040 ast_mutex_unlock(&iaxsl[callno]); 05041 return res; 05042 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 5064 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05065 { 05066 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05067 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1052 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01053 { 01054 #ifdef SCHED_MULTITHREADED 01055 if (schedule_action(__send_lagrq, data)) 01056 #endif 01057 __send_lagrq(data); 01058 return 0; 01059 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2076 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), errno, error(), f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02077 { 02078 int res; 02079 int callno = f->callno; 02080 02081 /* Don't send if there was an error, but return error instead */ 02082 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02083 return -1; 02084 02085 /* Called with iaxsl held */ 02086 if (option_debug > 2 && iaxdebug) 02087 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)); 02088 if (f->transfer) { 02089 if (iaxdebug) 02090 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02091 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02092 sizeof(iaxs[callno]->transfer)); 02093 } else { 02094 if (iaxdebug) 02095 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02096 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02097 sizeof(iaxs[callno]->addr)); 02098 } 02099 if (res < 0) { 02100 if (option_debug && iaxdebug) 02101 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02102 handle_error(); 02103 } else 02104 res = 0; 02105 return res; 02106 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1012 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01013 { 01014 #ifdef SCHED_MULTITHREADED 01015 if (schedule_action(__send_ping, data)) 01016 #endif 01017 __send_ping(data); 01018 return 0; 01019 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6474 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, 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().
06475 { 06476 int res = 0; 06477 struct iax_frame *fr; 06478 struct ast_iax2_meta_hdr *meta; 06479 struct ast_iax2_meta_trunk_hdr *mth; 06480 int calls = 0; 06481 06482 /* Point to frame */ 06483 fr = (struct iax_frame *)tpeer->trunkdata; 06484 /* Point to meta data */ 06485 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06486 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06487 if (tpeer->trunkdatalen) { 06488 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06489 meta->zeros = 0; 06490 meta->metacmd = IAX_META_TRUNK; 06491 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06492 meta->cmddata = IAX_META_TRUNK_MINI; 06493 else 06494 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06495 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06496 /* And the rest of the ast_iax2 header */ 06497 fr->direction = DIRECTION_OUTGRESS; 06498 fr->retrans = -1; 06499 fr->transfer = 0; 06500 /* Any appropriate call will do */ 06501 fr->data = fr->afdata; 06502 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06503 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06504 calls = tpeer->calls; 06505 #if 0 06506 if (option_debug) 06507 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)); 06508 #endif 06509 /* Reset transmit trunk side data */ 06510 tpeer->trunkdatalen = 0; 06511 tpeer->calls = 0; 06512 } 06513 if (res < 0) 06514 return res; 06515 return calls; 06516 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9849 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(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, 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, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), peers, portno, prefs, reg_source_db(), 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().
09850 { 09851 struct ast_config *cfg, *ucfg; 09852 int capability=iax2_capability; 09853 struct ast_variable *v; 09854 char *cat; 09855 const char *utype; 09856 const char *tosval; 09857 int format; 09858 int portno = IAX_DEFAULT_PORTNO; 09859 int x; 09860 struct iax2_user *user; 09861 struct iax2_peer *peer; 09862 struct ast_netsock *ns; 09863 #if 0 09864 static unsigned short int last_port=0; 09865 #endif 09866 09867 cfg = ast_config_load(config_file); 09868 09869 if (!cfg) { 09870 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09871 return -1; 09872 } 09873 09874 if (reload) { 09875 set_config_destroy(); 09876 } 09877 09878 /* Reset global codec prefs */ 09879 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09880 09881 /* Reset Global Flags */ 09882 memset(&globalflags, 0, sizeof(globalflags)); 09883 ast_set_flag(&globalflags, IAX_RTUPDATE); 09884 09885 #ifdef SO_NO_CHECK 09886 nochecksums = 0; 09887 #endif 09888 09889 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09890 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09891 09892 maxauthreq = 3; 09893 09894 v = ast_variable_browse(cfg, "general"); 09895 09896 /* Seed initial tos value */ 09897 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09898 if (tosval) { 09899 if (ast_str2tos(tosval, &tos)) 09900 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09901 } 09902 while(v) { 09903 if (!strcasecmp(v->name, "bindport")){ 09904 if (reload) 09905 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09906 else 09907 portno = atoi(v->value); 09908 } else if (!strcasecmp(v->name, "pingtime")) 09909 ping_time = atoi(v->value); 09910 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09911 if (reload) { 09912 if (atoi(v->value) != iaxthreadcount) 09913 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09914 } else { 09915 iaxthreadcount = atoi(v->value); 09916 if (iaxthreadcount < 1) { 09917 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09918 iaxthreadcount = 1; 09919 } else if (iaxthreadcount > 256) { 09920 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09921 iaxthreadcount = 256; 09922 } 09923 } 09924 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09925 if (reload) { 09926 AST_LIST_LOCK(&dynamic_list); 09927 iaxmaxthreadcount = atoi(v->value); 09928 AST_LIST_UNLOCK(&dynamic_list); 09929 } else { 09930 iaxmaxthreadcount = atoi(v->value); 09931 if (iaxmaxthreadcount < 0) { 09932 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09933 iaxmaxthreadcount = 0; 09934 } else if (iaxmaxthreadcount > 256) { 09935 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09936 iaxmaxthreadcount = 256; 09937 } 09938 } 09939 } else if (!strcasecmp(v->name, "nochecksums")) { 09940 #ifdef SO_NO_CHECK 09941 if (ast_true(v->value)) 09942 nochecksums = 1; 09943 else 09944 nochecksums = 0; 09945 #else 09946 if (ast_true(v->value)) 09947 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09948 #endif 09949 } 09950 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09951 maxjitterbuffer = atoi(v->value); 09952 else if (!strcasecmp(v->name, "resyncthreshold")) 09953 resyncthreshold = atoi(v->value); 09954 else if (!strcasecmp(v->name, "maxjitterinterps")) 09955 maxjitterinterps = atoi(v->value); 09956 else if (!strcasecmp(v->name, "lagrqtime")) 09957 lagrq_time = atoi(v->value); 09958 else if (!strcasecmp(v->name, "maxregexpire")) 09959 max_reg_expire = atoi(v->value); 09960 else if (!strcasecmp(v->name, "minregexpire")) 09961 min_reg_expire = atoi(v->value); 09962 else if (!strcasecmp(v->name, "bindaddr")) { 09963 if (reload) { 09964 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09965 } else { 09966 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09967 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09968 } else { 09969 if (option_verbose > 1) { 09970 if (strchr(v->value, ':')) 09971 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09972 else 09973 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09974 } 09975 if (defaultsockfd < 0) 09976 defaultsockfd = ast_netsock_sockfd(ns); 09977 ast_netsock_unref(ns); 09978 } 09979 } 09980 } else if (!strcasecmp(v->name, "authdebug")) 09981 authdebug = ast_true(v->value); 09982 else if (!strcasecmp(v->name, "encryption")) 09983 iax2_encryption = get_encrypt_methods(v->value); 09984 else if (!strcasecmp(v->name, "notransfer")) { 09985 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09986 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09987 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09988 } else if (!strcasecmp(v->name, "transfer")) { 09989 if (!strcasecmp(v->value, "mediaonly")) { 09990 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09991 } else if (ast_true(v->value)) { 09992 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09993 } else 09994 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09995 } else if (!strcasecmp(v->name, "codecpriority")) { 09996 if(!strcasecmp(v->value, "caller")) 09997 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09998 else if(!strcasecmp(v->value, "disabled")) 09999 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10000 else if(!strcasecmp(v->value, "reqonly")) { 10001 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10002 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10003 } 10004 } else if (!strcasecmp(v->name, "jitterbuffer")) 10005 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10006 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10007 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10008 else if (!strcasecmp(v->name, "delayreject")) 10009 delayreject = ast_true(v->value); 10010 else if (!strcasecmp(v->name, "allowfwdownload")) 10011 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10012 else if (!strcasecmp(v->name, "rtcachefriends")) 10013 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10014 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10015 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10016 else if (!strcasecmp(v->name, "rtupdate")) 10017 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10018 else if (!strcasecmp(v->name, "trunktimestamps")) 10019 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10020 else if (!strcasecmp(v->name, "rtautoclear")) { 10021 int i = atoi(v->value); 10022 if(i > 0) 10023 global_rtautoclear = i; 10024 else 10025 i = 0; 10026 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10027 } else if (!strcasecmp(v->name, "trunkfreq")) { 10028 trunkfreq = atoi(v->value); 10029 if (trunkfreq < 10) 10030 trunkfreq = 10; 10031 } else if (!strcasecmp(v->name, "autokill")) { 10032 if (sscanf(v->value, "%d", &x) == 1) { 10033 if (x >= 0) 10034 autokill = x; 10035 else 10036 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10037 } else if (ast_true(v->value)) { 10038 autokill = DEFAULT_MAXMS; 10039 } else { 10040 autokill = 0; 10041 } 10042 } else if (!strcasecmp(v->name, "bandwidth")) { 10043 if (!strcasecmp(v->value, "low")) { 10044 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10045 } else if (!strcasecmp(v->value, "medium")) { 10046 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10047 } else if (!strcasecmp(v->value, "high")) { 10048 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10049 } else 10050 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10051 } else if (!strcasecmp(v->name, "allow")) { 10052 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10053 } else if (!strcasecmp(v->name, "disallow")) { 10054 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10055 } else if (!strcasecmp(v->name, "register")) { 10056 iax2_register(v->value, v->lineno); 10057 } else if (!strcasecmp(v->name, "iaxcompat")) { 10058 iaxcompat = ast_true(v->value); 10059 } else if (!strcasecmp(v->name, "regcontext")) { 10060 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10061 /* Create context if it doesn't exist already */ 10062 if (!ast_context_find(regcontext)) 10063 ast_context_create(NULL, regcontext, "IAX2"); 10064 } else if (!strcasecmp(v->name, "tos")) { 10065 if (ast_str2tos(v->value, &tos)) 10066 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10067 } else if (!strcasecmp(v->name, "accountcode")) { 10068 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10069 } else if (!strcasecmp(v->name, "mohinterpret")) { 10070 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 10071 } else if (!strcasecmp(v->name, "mohsuggest")) { 10072 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 10073 } else if (!strcasecmp(v->name, "amaflags")) { 10074 format = ast_cdr_amaflags2int(v->value); 10075 if (format < 0) { 10076 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10077 } else { 10078 amaflags = format; 10079 } 10080 } else if (!strcasecmp(v->name, "language")) { 10081 ast_copy_string(language, v->value, sizeof(language)); 10082 } else if (!strcasecmp(v->name, "maxauthreq")) { 10083 maxauthreq = atoi(v->value); 10084 if (maxauthreq < 0) 10085 maxauthreq = 0; 10086 } else if (!strcasecmp(v->name, "adsi")) { 10087 adsi = ast_true(v->value); 10088 } /*else if (strcasecmp(v->name,"type")) */ 10089 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10090 v = v->next; 10091 } 10092 10093 if (defaultsockfd < 0) { 10094 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10095 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10096 } else { 10097 if (option_verbose > 1) 10098 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10099 defaultsockfd = ast_netsock_sockfd(ns); 10100 ast_netsock_unref(ns); 10101 } 10102 } 10103 if (reload) { 10104 ast_netsock_release(outsock); 10105 outsock = ast_netsock_list_alloc(); 10106 if (!outsock) { 10107 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10108 return -1; 10109 } 10110 ast_netsock_init(outsock); 10111 } 10112 10113 if (min_reg_expire > max_reg_expire) { 10114 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10115 min_reg_expire, max_reg_expire, max_reg_expire); 10116 min_reg_expire = max_reg_expire; 10117 } 10118 iax2_capability = capability; 10119 10120 ucfg = ast_config_load("users.conf"); 10121 if (ucfg) { 10122 struct ast_variable *gen; 10123 int genhasiax; 10124 int genregisteriax; 10125 const char *hasiax, *registeriax; 10126 10127 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10128 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10129 gen = ast_variable_browse(ucfg, "general"); 10130 cat = ast_category_browse(ucfg, NULL); 10131 while (cat) { 10132 if (strcasecmp(cat, "general")) { 10133 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10134 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10135 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10136 /* Start with general parameters, then specific parameters, user and peer */ 10137 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10138 if (user) { 10139 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10140 user = user_unref(user); 10141 } 10142 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10143 if (peer) { 10144 if (ast_test_flag(peer, IAX_DYNAMIC)) 10145 reg_source_db(peer); 10146 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10147 peer = peer_unref(peer); 10148 } 10149 } 10150 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10151 char tmp[256]; 10152 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10153 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10154 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10155 if (!host) 10156 host = ast_variable_retrieve(ucfg, "general", "host"); 10157 if (!username) 10158 username = ast_variable_retrieve(ucfg, "general", "username"); 10159 if (!secret) 10160 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10161 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10162 if (!ast_strlen_zero(secret)) 10163 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10164 else 10165 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10166 iax2_register(tmp, 0); 10167 } 10168 } 10169 } 10170 cat = ast_category_browse(ucfg, cat); 10171 } 10172 ast_config_destroy(ucfg); 10173 } 10174 10175 cat = ast_category_browse(cfg, NULL); 10176 while(cat) { 10177 if (strcasecmp(cat, "general")) { 10178 utype = ast_variable_retrieve(cfg, cat, "type"); 10179 if (utype) { 10180 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10181 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10182 if (user) { 10183 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10184 user = user_unref(user); 10185 } 10186 } 10187 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10188 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10189 if (peer) { 10190 if (ast_test_flag(peer, IAX_DYNAMIC)) 10191 reg_source_db(peer); 10192 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10193 peer = peer_unref(peer); 10194 } 10195 } else if (strcasecmp(utype, "user")) { 10196 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10197 } 10198 } else 10199 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10200 } 10201 cat = ast_category_browse(cfg, cat); 10202 } 10203 ast_config_destroy(cfg); 10204 set_timing(); 10205 return 1; 10206 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9833 of file chan_iax2.c.
References ast_clear_flag, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09834 { 09835 strcpy(accountcode, ""); 09836 strcpy(language, ""); 09837 strcpy(mohinterpret, "default"); 09838 strcpy(mohsuggest, ""); 09839 amaflags = 0; 09840 delayreject = 0; 09841 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09842 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09843 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09844 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09845 delete_users(); 09846 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9818 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09819 { 09820 #ifdef HAVE_ZAPTEL 09821 int bs = trunkfreq * 8; 09822 if (timingfd > -1) { 09823 if ( 09824 #ifdef ZT_TIMERACK 09825 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09826 #endif 09827 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09828 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09829 } 09830 #endif 09831 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 754 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().
00755 { 00756 ast_mutex_lock(lock); 00757 ast_cond_signal(cond); 00758 ast_mutex_unlock(lock); 00759 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6948 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HANGUP, 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_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(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, globalflags, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, 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, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, len, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), 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().
06949 { 06950 struct sockaddr_in sin; 06951 int res; 06952 int updatehistory=1; 06953 int new = NEW_PREVENT; 06954 void *ptr; 06955 int dcallno = 0; 06956 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06957 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06958 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06959 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06960 struct ast_iax2_meta_trunk_hdr *mth; 06961 struct ast_iax2_meta_trunk_entry *mte; 06962 struct ast_iax2_meta_trunk_mini *mtm; 06963 struct iax_frame *fr; 06964 struct iax_frame *cur; 06965 struct ast_frame f = { 0, }; 06966 struct ast_channel *c; 06967 struct iax2_dpcache *dp; 06968 struct iax2_peer *peer; 06969 struct iax2_trunk_peer *tpeer; 06970 struct timeval rxtrunktime; 06971 struct iax_ies ies; 06972 struct iax_ie_data ied0, ied1; 06973 int format; 06974 int fd; 06975 int exists; 06976 int minivid = 0; 06977 unsigned int ts; 06978 char empty[32]=""; /* Safety measure */ 06979 struct iax_frame *duped_fr; 06980 char host_pref_buf[128]; 06981 char caller_pref_buf[128]; 06982 struct ast_codec_pref pref; 06983 char *using_prefs = "mine"; 06984 06985 /* allocate an iax_frame with 4096 bytes of data buffer */ 06986 fr = alloca(sizeof(*fr) + 4096); 06987 memset(fr, 0, sizeof(*fr)); 06988 fr->afdatalen = 4096; /* From alloca() above */ 06989 06990 /* Copy frequently used parameters to the stack */ 06991 res = thread->buf_len; 06992 fd = thread->iofd; 06993 memcpy(&sin, &thread->iosin, sizeof(sin)); 06994 06995 if (res < sizeof(*mh)) { 06996 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06997 return 1; 06998 } 06999 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07000 if (res < sizeof(*vh)) { 07001 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)); 07002 return 1; 07003 } 07004 07005 /* This is a video frame, get call number */ 07006 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07007 minivid = 1; 07008 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07009 unsigned char metatype; 07010 07011 if (res < sizeof(*meta)) { 07012 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)); 07013 return 1; 07014 } 07015 07016 /* This is a meta header */ 07017 switch(meta->metacmd) { 07018 case IAX_META_TRUNK: 07019 if (res < (sizeof(*meta) + sizeof(*mth))) { 07020 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07021 sizeof(*meta) + sizeof(*mth)); 07022 return 1; 07023 } 07024 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07025 ts = ntohl(mth->ts); 07026 metatype = meta->cmddata; 07027 res -= (sizeof(*meta) + sizeof(*mth)); 07028 ptr = mth->data; 07029 tpeer = find_tpeer(&sin, fd); 07030 if (!tpeer) { 07031 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)); 07032 return 1; 07033 } 07034 tpeer->trunkact = ast_tvnow(); 07035 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07036 tpeer->rxtrunktime = tpeer->trunkact; 07037 rxtrunktime = tpeer->rxtrunktime; 07038 ast_mutex_unlock(&tpeer->lock); 07039 while(res >= sizeof(*mte)) { 07040 /* Process channels */ 07041 unsigned short callno, trunked_ts, len; 07042 07043 if (metatype == IAX_META_TRUNK_MINI) { 07044 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07045 ptr += sizeof(*mtm); 07046 res -= sizeof(*mtm); 07047 len = ntohs(mtm->len); 07048 callno = ntohs(mtm->mini.callno); 07049 trunked_ts = ntohs(mtm->mini.ts); 07050 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07051 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07052 ptr += sizeof(*mte); 07053 res -= sizeof(*mte); 07054 len = ntohs(mte->len); 07055 callno = ntohs(mte->callno); 07056 trunked_ts = 0; 07057 } else { 07058 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07059 break; 07060 } 07061 /* Stop if we don't have enough data */ 07062 if (len > res) 07063 break; 07064 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07065 if (fr->callno) { 07066 /* If it's a valid call, deliver the contents. If not, we 07067 drop it, since we don't have a scallno to use for an INVAL */ 07068 /* Process as a mini frame */ 07069 memset(&f, 0, sizeof(f)); 07070 f.frametype = AST_FRAME_VOICE; 07071 if (iaxs[fr->callno]) { 07072 if (iaxs[fr->callno]->voiceformat > 0) { 07073 f.subclass = iaxs[fr->callno]->voiceformat; 07074 f.datalen = len; 07075 if (f.datalen >= 0) { 07076 if (f.datalen) 07077 f.data = ptr; 07078 if(trunked_ts) { 07079 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07080 } else 07081 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07082 /* Don't pass any packets until we're started */ 07083 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07084 /* Common things */ 07085 f.src = "IAX2"; 07086 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07087 f.samples = ast_codec_get_samples(&f); 07088 iax_frame_wrap(fr, &f); 07089 duped_fr = iaxfrdup2(fr); 07090 if (duped_fr) { 07091 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07092 } 07093 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07094 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07095 iaxs[fr->callno]->last = fr->ts; 07096 #if 1 07097 if (option_debug && iaxdebug) 07098 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07099 #endif 07100 } 07101 } 07102 } else { 07103 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07104 } 07105 } else { 07106 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 07107 iax2_vnak(fr->callno); 07108 } 07109 } 07110 ast_mutex_unlock(&iaxsl[fr->callno]); 07111 } 07112 ptr += len; 07113 res -= len; 07114 } 07115 07116 } 07117 return 1; 07118 } 07119 07120 #ifdef DEBUG_SUPPORT 07121 if (iaxdebug && (res >= sizeof(*fh))) 07122 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07123 #endif 07124 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07125 if (res < sizeof(*fh)) { 07126 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)); 07127 return 1; 07128 } 07129 07130 /* Get the destination call number */ 07131 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07132 /* Retrieve the type and subclass */ 07133 f.frametype = fh->type; 07134 if (f.frametype == AST_FRAME_VIDEO) { 07135 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07136 } else { 07137 f.subclass = uncompress_subclass(fh->csub); 07138 } 07139 07140 /* Deal with POKE/PONG without allocating a callno */ 07141 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07142 /* Reply back with a PONG, but don't care about the result. */ 07143 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno); 07144 return 1; 07145 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07146 /* Ignore */ 07147 return 1; 07148 } 07149 07150 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07151 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07152 (f.subclass == IAX_COMMAND_REGREL))) 07153 new = NEW_ALLOW; 07154 } else { 07155 /* Don't know anything about it yet */ 07156 f.frametype = AST_FRAME_NULL; 07157 f.subclass = 0; 07158 } 07159 07160 if (!fr->callno) { 07161 int check_dcallno = 0; 07162 07163 /* 07164 * We enforce accurate destination call numbers for all full frames except 07165 * LAGRQ and PING commands. This is because older versions of Asterisk 07166 * schedule these commands to get sent very quickly, and they will sometimes 07167 * be sent before they receive the first frame from the other side. When 07168 * that happens, it doesn't contain the destination call number. However, 07169 * not checking it for these frames is safe. 07170 * 07171 * Discussed in the following thread: 07172 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07173 */ 07174 07175 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07176 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07177 } 07178 07179 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07180 } 07181 07182 if (fr->callno > 0) 07183 ast_mutex_lock(&iaxsl[fr->callno]); 07184 07185 if (!fr->callno || !iaxs[fr->callno]) { 07186 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07187 frame, reply with an inval */ 07188 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07189 /* We can only raw hangup control frames */ 07190 if (((f.subclass != IAX_COMMAND_INVAL) && 07191 (f.subclass != IAX_COMMAND_TXCNT) && 07192 (f.subclass != IAX_COMMAND_TXACC) && 07193 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07194 (f.frametype != AST_FRAME_IAX)) 07195 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07196 fd); 07197 } 07198 if (fr->callno > 0) 07199 ast_mutex_unlock(&iaxsl[fr->callno]); 07200 return 1; 07201 } 07202 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07203 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07204 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07205 ast_mutex_unlock(&iaxsl[fr->callno]); 07206 return 1; 07207 } 07208 #ifdef DEBUG_SUPPORT 07209 else if (iaxdebug) 07210 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07211 #endif 07212 } 07213 07214 /* count this frame */ 07215 iaxs[fr->callno]->frames_received++; 07216 07217 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07218 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07219 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07220 unsigned short new_peercallno; 07221 07222 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07223 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07224 if (iaxs[fr->callno]->peercallno) { 07225 remove_by_peercallno(iaxs[fr->callno]); 07226 } 07227 iaxs[fr->callno]->peercallno = new_peercallno; 07228 store_by_peercallno(iaxs[fr->callno]); 07229 } 07230 } 07231 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07232 if (option_debug && iaxdebug) 07233 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07234 /* Check if it's out of order (and not an ACK or INVAL) */ 07235 fr->oseqno = fh->oseqno; 07236 fr->iseqno = fh->iseqno; 07237 fr->ts = ntohl(fh->ts); 07238 #ifdef IAXTESTS 07239 if (test_resync) { 07240 if (option_debug) 07241 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07242 fr->ts += test_resync; 07243 } 07244 #endif /* IAXTESTS */ 07245 #if 0 07246 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07247 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07248 (f.subclass == IAX_COMMAND_NEW || 07249 f.subclass == IAX_COMMAND_AUTHREQ || 07250 f.subclass == IAX_COMMAND_ACCEPT || 07251 f.subclass == IAX_COMMAND_REJECT)) ) ) 07252 #endif 07253 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07254 updatehistory = 0; 07255 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07256 (iaxs[fr->callno]->iseqno || 07257 ((f.subclass != IAX_COMMAND_TXCNT) && 07258 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07259 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07260 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07261 (f.subclass != IAX_COMMAND_TXACC)) || 07262 (f.frametype != AST_FRAME_IAX))) { 07263 if ( 07264 ((f.subclass != IAX_COMMAND_ACK) && 07265 (f.subclass != IAX_COMMAND_INVAL) && 07266 (f.subclass != IAX_COMMAND_TXCNT) && 07267 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07268 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07269 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07270 (f.subclass != IAX_COMMAND_TXACC) && 07271 (f.subclass != IAX_COMMAND_VNAK)) || 07272 (f.frametype != AST_FRAME_IAX)) { 07273 /* If it's not an ACK packet, it's out of order. */ 07274 if (option_debug) 07275 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07276 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07277 /* Check to see if we need to request retransmission, 07278 * and take sequence number wraparound into account */ 07279 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07280 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07281 if ((f.frametype != AST_FRAME_IAX) || 07282 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07283 if (option_debug) 07284 ast_log(LOG_DEBUG, "Acking anyway\n"); 07285 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07286 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07287 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07288 } 07289 } else { 07290 /* Send a VNAK requesting retransmission */ 07291 iax2_vnak(fr->callno); 07292 } 07293 ast_mutex_unlock(&iaxsl[fr->callno]); 07294 return 1; 07295 } 07296 } else { 07297 /* Increment unless it's an ACK or VNAK */ 07298 if (((f.subclass != IAX_COMMAND_ACK) && 07299 (f.subclass != IAX_COMMAND_INVAL) && 07300 (f.subclass != IAX_COMMAND_TXCNT) && 07301 (f.subclass != IAX_COMMAND_TXACC) && 07302 (f.subclass != IAX_COMMAND_VNAK)) || 07303 (f.frametype != AST_FRAME_IAX)) 07304 iaxs[fr->callno]->iseqno++; 07305 } 07306 /* A full frame */ 07307 if (res < sizeof(*fh)) { 07308 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07309 ast_mutex_unlock(&iaxsl[fr->callno]); 07310 return 1; 07311 } 07312 /* Ensure text frames are NULL-terminated */ 07313 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07314 if (res < thread->buf_size) 07315 thread->buf[res++] = '\0'; 07316 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07317 thread->buf[res - 1] = '\0'; 07318 } 07319 f.datalen = res - sizeof(*fh); 07320 07321 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07322 from the real peer, not the transfer peer */ 07323 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07324 ((f.subclass != IAX_COMMAND_INVAL) || 07325 (f.frametype != AST_FRAME_IAX))) { 07326 unsigned char x; 07327 int call_to_destroy; 07328 /* XXX This code is not very efficient. Surely there is a better way which still 07329 properly handles boundary conditions? XXX */ 07330 /* First we have to qualify that the ACKed value is within our window */ 07331 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07332 if (fr->iseqno == x) 07333 break; 07334 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07335 /* The acknowledgement is within our window. Time to acknowledge everything 07336 that it says to */ 07337 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07338 /* Ack the packet with the given timestamp */ 07339 if (option_debug && iaxdebug) 07340 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07341 call_to_destroy = 0; 07342 AST_LIST_LOCK(&iaxq.queue); 07343 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07344 /* If it's our call, and our timestamp, mark -1 retries */ 07345 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07346 cur->retries = -1; 07347 /* Destroy call if this is the end */ 07348 if (cur->final) 07349 call_to_destroy = fr->callno; 07350 } 07351 } 07352 AST_LIST_UNLOCK(&iaxq.queue); 07353 if (call_to_destroy) { 07354 if (iaxdebug && option_debug) 07355 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07356 ast_mutex_lock(&iaxsl[call_to_destroy]); 07357 iax2_destroy(call_to_destroy); 07358 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07359 } 07360 } 07361 /* Note how much we've received acknowledgement for */ 07362 if (iaxs[fr->callno]) 07363 iaxs[fr->callno]->rseqno = fr->iseqno; 07364 else { 07365 /* Stop processing now */ 07366 ast_mutex_unlock(&iaxsl[fr->callno]); 07367 return 1; 07368 } 07369 } else if (option_debug) 07370 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07371 } 07372 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07373 ((f.frametype != AST_FRAME_IAX) || 07374 ((f.subclass != IAX_COMMAND_TXACC) && 07375 (f.subclass != IAX_COMMAND_TXCNT)))) { 07376 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07377 ast_mutex_unlock(&iaxsl[fr->callno]); 07378 return 1; 07379 } 07380 07381 if (f.datalen) { 07382 if (f.frametype == AST_FRAME_IAX) { 07383 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07384 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07385 ast_mutex_unlock(&iaxsl[fr->callno]); 07386 return 1; 07387 } 07388 f.data = NULL; 07389 f.datalen = 0; 07390 } else 07391 f.data = thread->buf + sizeof(*fh); 07392 } else { 07393 if (f.frametype == AST_FRAME_IAX) 07394 f.data = NULL; 07395 else 07396 f.data = empty; 07397 memset(&ies, 0, sizeof(ies)); 07398 } 07399 07400 /* when we receive the first full frame for a new incoming channel, 07401 it is safe to start the PBX on the channel because we have now 07402 completed a 3-way handshake with the peer */ 07403 if ((f.frametype == AST_FRAME_VOICE) || 07404 (f.frametype == AST_FRAME_VIDEO) || 07405 (f.frametype == AST_FRAME_IAX)) { 07406 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07407 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07408 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07409 ast_mutex_unlock(&iaxsl[fr->callno]); 07410 return 1; 07411 } 07412 } 07413 } 07414 07415 if (f.frametype == AST_FRAME_VOICE) { 07416 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07417 iaxs[fr->callno]->voiceformat = f.subclass; 07418 if (option_debug) 07419 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07420 if (iaxs[fr->callno]->owner) { 07421 int orignative; 07422 retryowner: 07423 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07424 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07425 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07426 } 07427 if (iaxs[fr->callno]) { 07428 if (iaxs[fr->callno]->owner) { 07429 orignative = iaxs[fr->callno]->owner->nativeformats; 07430 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07431 if (iaxs[fr->callno]->owner->readformat) 07432 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07433 iaxs[fr->callno]->owner->nativeformats = orignative; 07434 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07435 } 07436 } else { 07437 if (option_debug) 07438 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07439 ast_mutex_unlock(&iaxsl[fr->callno]); 07440 return 1; 07441 } 07442 } 07443 } 07444 } 07445 if (f.frametype == AST_FRAME_VIDEO) { 07446 if (f.subclass != iaxs[fr->callno]->videoformat) { 07447 if (option_debug) 07448 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07449 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07450 } 07451 } 07452 if (f.frametype == AST_FRAME_IAX) { 07453 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07454 /* Handle the IAX pseudo frame itself */ 07455 if (option_debug && iaxdebug) 07456 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07457 07458 /* Update last ts unless the frame's timestamp originated with us. */ 07459 if (iaxs[fr->callno]->last < fr->ts && 07460 f.subclass != IAX_COMMAND_ACK && 07461 f.subclass != IAX_COMMAND_PONG && 07462 f.subclass != IAX_COMMAND_LAGRP) { 07463 iaxs[fr->callno]->last = fr->ts; 07464 if (option_debug && iaxdebug) 07465 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07466 } 07467 07468 switch(f.subclass) { 07469 case IAX_COMMAND_ACK: 07470 /* Do nothing */ 07471 break; 07472 case IAX_COMMAND_QUELCH: 07473 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07474 /* Generate Manager Hold event, if necessary*/ 07475 if (iaxs[fr->callno]->owner) { 07476 manager_event(EVENT_FLAG_CALL, "Hold", 07477 "Channel: %s\r\n" 07478 "Uniqueid: %s\r\n", 07479 iaxs[fr->callno]->owner->name, 07480 iaxs[fr->callno]->owner->uniqueid); 07481 } 07482 07483 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07484 if (ies.musiconhold) { 07485 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07486 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07487 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07488 S_OR(mohsuggest, NULL), 07489 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07490 if (!iaxs[fr->callno]) { 07491 ast_mutex_unlock(&iaxsl[fr->callno]); 07492 return 1; 07493 } 07494 } 07495 } 07496 } 07497 break; 07498 case IAX_COMMAND_UNQUELCH: 07499 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07500 /* Generate Manager Unhold event, if necessary*/ 07501 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07502 manager_event(EVENT_FLAG_CALL, "Unhold", 07503 "Channel: %s\r\n" 07504 "Uniqueid: %s\r\n", 07505 iaxs[fr->callno]->owner->name, 07506 iaxs[fr->callno]->owner->uniqueid); 07507 } 07508 07509 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07510 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07511 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07512 if (!iaxs[fr->callno]) { 07513 ast_mutex_unlock(&iaxsl[fr->callno]); 07514 return 1; 07515 } 07516 } 07517 } 07518 break; 07519 case IAX_COMMAND_TXACC: 07520 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07521 /* Ack the packet with the given timestamp */ 07522 AST_LIST_LOCK(&iaxq.queue); 07523 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07524 /* Cancel any outstanding txcnt's */ 07525 if ((fr->callno == cur->callno) && (cur->transfer)) 07526 cur->retries = -1; 07527 } 07528 AST_LIST_UNLOCK(&iaxq.queue); 07529 memset(&ied1, 0, sizeof(ied1)); 07530 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07531 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07532 iaxs[fr->callno]->transferring = TRANSFER_READY; 07533 } 07534 break; 07535 case IAX_COMMAND_NEW: 07536 /* Ignore if it's already up */ 07537 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07538 break; 07539 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07540 ast_mutex_unlock(&iaxsl[fr->callno]); 07541 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07542 ast_mutex_lock(&iaxsl[fr->callno]); 07543 if (!iaxs[fr->callno]) { 07544 ast_mutex_unlock(&iaxsl[fr->callno]); 07545 return 1; 07546 } 07547 } 07548 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07549 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07550 int new_callno; 07551 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07552 fr->callno = new_callno; 07553 } 07554 /* For security, always ack immediately */ 07555 if (delayreject) 07556 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07557 if (check_access(fr->callno, &sin, &ies)) { 07558 /* They're not allowed on */ 07559 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07560 if (authdebug) 07561 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); 07562 break; 07563 } 07564 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07565 const char *context, *exten, *cid_num; 07566 07567 context = ast_strdupa(iaxs[fr->callno]->context); 07568 exten = ast_strdupa(iaxs[fr->callno]->exten); 07569 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07570 07571 /* This might re-enter the IAX code and need the lock */ 07572 ast_mutex_unlock(&iaxsl[fr->callno]); 07573 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07574 ast_mutex_lock(&iaxsl[fr->callno]); 07575 07576 if (!iaxs[fr->callno]) { 07577 ast_mutex_unlock(&iaxsl[fr->callno]); 07578 return 1; 07579 } 07580 } else 07581 exists = 0; 07582 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07583 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07584 memset(&ied0, 0, sizeof(ied0)); 07585 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07586 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07587 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07588 if (!iaxs[fr->callno]) { 07589 ast_mutex_unlock(&iaxsl[fr->callno]); 07590 return 1; 07591 } 07592 if (authdebug) 07593 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); 07594 } else { 07595 /* Select an appropriate format */ 07596 07597 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07598 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07599 using_prefs = "reqonly"; 07600 } else { 07601 using_prefs = "disabled"; 07602 } 07603 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07604 memset(&pref, 0, sizeof(pref)); 07605 strcpy(caller_pref_buf, "disabled"); 07606 strcpy(host_pref_buf, "disabled"); 07607 } else { 07608 using_prefs = "mine"; 07609 /* If the information elements are in here... use them */ 07610 if (ies.codec_prefs) 07611 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07612 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07613 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07614 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07615 pref = iaxs[fr->callno]->rprefs; 07616 using_prefs = "caller"; 07617 } else { 07618 pref = iaxs[fr->callno]->prefs; 07619 } 07620 } else 07621 pref = iaxs[fr->callno]->prefs; 07622 07623 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07624 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07625 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07626 } 07627 if (!format) { 07628 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07629 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07630 if (!format) { 07631 memset(&ied0, 0, sizeof(ied0)); 07632 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07633 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07634 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07635 if (!iaxs[fr->callno]) { 07636 ast_mutex_unlock(&iaxsl[fr->callno]); 07637 return 1; 07638 } 07639 if (authdebug) { 07640 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07641 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); 07642 else 07643 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); 07644 } 07645 } else { 07646 /* Pick one... */ 07647 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07648 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07649 format = 0; 07650 } else { 07651 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07652 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07653 memset(&pref, 0, sizeof(pref)); 07654 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07655 strcpy(caller_pref_buf,"disabled"); 07656 strcpy(host_pref_buf,"disabled"); 07657 } else { 07658 using_prefs = "mine"; 07659 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07660 /* Do the opposite of what we tried above. */ 07661 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07662 pref = iaxs[fr->callno]->prefs; 07663 } else { 07664 pref = iaxs[fr->callno]->rprefs; 07665 using_prefs = "caller"; 07666 } 07667 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07668 07669 } else /* if no codec_prefs IE do it the old way */ 07670 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07671 } 07672 } 07673 07674 if (!format) { 07675 memset(&ied0, 0, sizeof(ied0)); 07676 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07677 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07678 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07679 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07680 if (!iaxs[fr->callno]) { 07681 ast_mutex_unlock(&iaxsl[fr->callno]); 07682 return 1; 07683 } 07684 if (authdebug) 07685 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); 07686 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07687 break; 07688 } 07689 } 07690 } 07691 if (format) { 07692 /* No authentication required, let them in */ 07693 memset(&ied1, 0, sizeof(ied1)); 07694 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07695 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07696 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07697 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07698 if (option_verbose > 2) 07699 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07700 "%srequested format = %s,\n" 07701 "%srequested prefs = %s,\n" 07702 "%sactual format = %s,\n" 07703 "%shost prefs = %s,\n" 07704 "%spriority = %s\n", 07705 ast_inet_ntoa(sin.sin_addr), 07706 VERBOSE_PREFIX_4, 07707 ast_getformatname(iaxs[fr->callno]->peerformat), 07708 VERBOSE_PREFIX_4, 07709 caller_pref_buf, 07710 VERBOSE_PREFIX_4, 07711 ast_getformatname(format), 07712 VERBOSE_PREFIX_4, 07713 host_pref_buf, 07714 VERBOSE_PREFIX_4, 07715 using_prefs); 07716 07717 iaxs[fr->callno]->chosenformat = format; 07718 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07719 } else { 07720 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07721 /* If this is a TBD call, we're ready but now what... */ 07722 if (option_verbose > 2) 07723 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07724 } 07725 } 07726 } 07727 break; 07728 } 07729 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07730 merge_encryption(iaxs[fr->callno],ies.encmethods); 07731 else 07732 iaxs[fr->callno]->encmethods = 0; 07733 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07734 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07735 if (!iaxs[fr->callno]) { 07736 ast_mutex_unlock(&iaxsl[fr->callno]); 07737 return 1; 07738 } 07739 break; 07740 case IAX_COMMAND_DPREQ: 07741 /* Request status in the dialplan */ 07742 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07743 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07744 if (iaxcompat) { 07745 /* Spawn a thread for the lookup */ 07746 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07747 } else { 07748 /* Just look it up */ 07749 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07750 } 07751 } 07752 break; 07753 case IAX_COMMAND_HANGUP: 07754 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07755 if (option_debug) 07756 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07757 /* Set hangup cause according to remote */ 07758 if (ies.causecode && iaxs[fr->callno]->owner) 07759 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07760 /* Send ack immediately, before we destroy */ 07761 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07762 iax2_destroy(fr->callno); 07763 break; 07764 case IAX_COMMAND_REJECT: 07765 /* Set hangup cause according to remote */ 07766 if (ies.causecode && iaxs[fr->callno]->owner) 07767 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07768 07769 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07770 if (iaxs[fr->callno]->owner && authdebug) 07771 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07772 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07773 ies.cause ? ies.cause : "<Unknown>"); 07774 if (option_debug) 07775 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07776 fr->callno); 07777 } 07778 /* Send ack immediately, before we destroy */ 07779 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07780 fr->ts, NULL, 0, fr->iseqno); 07781 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07782 iaxs[fr->callno]->error = EPERM; 07783 iax2_destroy(fr->callno); 07784 break; 07785 case IAX_COMMAND_TRANSFER: 07786 { 07787 struct ast_channel *bridged_chan; 07788 07789 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07790 /* Set BLINDTRANSFER channel variables */ 07791 07792 ast_mutex_unlock(&iaxsl[fr->callno]); 07793 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07794 ast_mutex_lock(&iaxsl[fr->callno]); 07795 if (!iaxs[fr->callno]) { 07796 ast_mutex_unlock(&iaxsl[fr->callno]); 07797 return 1; 07798 } 07799 07800 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07801 if (!strcmp(ies.called_number, ast_parking_ext())) { 07802 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { 07803 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07804 } else { 07805 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07806 } 07807 } else { 07808 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07809 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07810 ies.called_number, iaxs[fr->callno]->context); 07811 else 07812 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07813 ies.called_number, iaxs[fr->callno]->context); 07814 } 07815 } else 07816 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07817 07818 break; 07819 } 07820 case IAX_COMMAND_ACCEPT: 07821 /* Ignore if call is already up or needs authentication or is a TBD */ 07822 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07823 break; 07824 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07825 /* Send ack immediately, before we destroy */ 07826 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07827 iax2_destroy(fr->callno); 07828 break; 07829 } 07830 if (ies.format) { 07831 iaxs[fr->callno]->peerformat = ies.format; 07832 } else { 07833 if (iaxs[fr->callno]->owner) 07834 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07835 else 07836 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07837 } 07838 if (option_verbose > 2) 07839 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)); 07840 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 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 if (authdebug) 07850 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); 07851 } else { 07852 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07853 if (iaxs[fr->callno]->owner) { 07854 /* Switch us to use a compatible format */ 07855 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07856 if (option_verbose > 2) 07857 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07858 retryowner2: 07859 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07860 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07861 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07862 } 07863 07864 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07865 /* Setup read/write formats properly. */ 07866 if (iaxs[fr->callno]->owner->writeformat) 07867 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07868 if (iaxs[fr->callno]->owner->readformat) 07869 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07870 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07871 } 07872 } 07873 } 07874 if (iaxs[fr->callno]) { 07875 ast_mutex_lock(&dpcache_lock); 07876 dp = iaxs[fr->callno]->dpentries; 07877 while(dp) { 07878 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07879 iax2_dprequest(dp, fr->callno); 07880 } 07881 dp = dp->peer; 07882 } 07883 ast_mutex_unlock(&dpcache_lock); 07884 } 07885 break; 07886 case IAX_COMMAND_POKE: 07887 /* Send back a pong packet with the original timestamp */ 07888 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07889 if (!iaxs[fr->callno]) { 07890 ast_mutex_unlock(&iaxsl[fr->callno]); 07891 return 1; 07892 } 07893 break; 07894 case IAX_COMMAND_PING: 07895 { 07896 struct iax_ie_data pingied; 07897 construct_rr(iaxs[fr->callno], &pingied); 07898 /* Send back a pong packet with the original timestamp */ 07899 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07900 } 07901 break; 07902 case IAX_COMMAND_PONG: 07903 /* Calculate ping time */ 07904 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07905 /* save RR info */ 07906 save_rr(fr, &ies); 07907 07908 if (iaxs[fr->callno]->peerpoke) { 07909 peer = iaxs[fr->callno]->peerpoke; 07910 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07911 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07912 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07913 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07914 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07915 } 07916 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07917 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07918 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07919 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07920 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07921 } 07922 } 07923 peer->lastms = iaxs[fr->callno]->pingtime; 07924 if (peer->smoothing && (peer->lastms > -1)) 07925 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07926 else if (peer->smoothing && peer->lastms < 0) 07927 peer->historicms = (0 + peer->historicms) / 2; 07928 else 07929 peer->historicms = iaxs[fr->callno]->pingtime; 07930 07931 /* Remove scheduled iax2_poke_noanswer */ 07932 if (peer->pokeexpire > -1) { 07933 if (!ast_sched_del(sched, peer->pokeexpire)) { 07934 peer_unref(peer); 07935 peer->pokeexpire = -1; 07936 } 07937 } 07938 /* Schedule the next cycle */ 07939 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07940 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07941 else 07942 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07943 if (peer->pokeexpire == -1) 07944 peer_unref(peer); 07945 /* and finally send the ack */ 07946 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07947 /* And wrap up the qualify call */ 07948 iax2_destroy(fr->callno); 07949 peer->callno = 0; 07950 if (option_debug) 07951 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07952 } 07953 break; 07954 case IAX_COMMAND_LAGRQ: 07955 case IAX_COMMAND_LAGRP: 07956 f.src = "LAGRQ"; 07957 f.mallocd = 0; 07958 f.offset = 0; 07959 f.samples = 0; 07960 iax_frame_wrap(fr, &f); 07961 if(f.subclass == IAX_COMMAND_LAGRQ) { 07962 /* Received a LAGRQ - echo back a LAGRP */ 07963 fr->af.subclass = IAX_COMMAND_LAGRP; 07964 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07965 } else { 07966 /* Received LAGRP in response to our LAGRQ */ 07967 unsigned int ts; 07968 /* This is a reply we've been given, actually measure the difference */ 07969 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07970 iaxs[fr->callno]->lag = ts - fr->ts; 07971 if (option_debug && iaxdebug) 07972 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07973 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07974 } 07975 break; 07976 case IAX_COMMAND_AUTHREQ: 07977 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07978 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>"); 07979 break; 07980 } 07981 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07982 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 07983 .subclass = AST_CONTROL_HANGUP, 07984 }; 07985 ast_log(LOG_WARNING, 07986 "I don't know how to authenticate %s to %s\n", 07987 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07988 iax2_queue_frame(fr->callno, &hangup_fr); 07989 } 07990 if (!iaxs[fr->callno]) { 07991 ast_mutex_unlock(&iaxsl[fr->callno]); 07992 return 1; 07993 } 07994 break; 07995 case IAX_COMMAND_AUTHREP: 07996 /* For security, always ack immediately */ 07997 if (delayreject) 07998 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07999 /* Ignore once we've started */ 08000 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08001 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>"); 08002 break; 08003 } 08004 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08005 if (authdebug) 08006 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); 08007 memset(&ied0, 0, sizeof(ied0)); 08008 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08009 break; 08010 } 08011 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08012 /* This might re-enter the IAX code and need the lock */ 08013 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08014 } else 08015 exists = 0; 08016 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08017 if (authdebug) 08018 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); 08019 memset(&ied0, 0, sizeof(ied0)); 08020 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08021 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08022 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08023 if (!iaxs[fr->callno]) { 08024 ast_mutex_unlock(&iaxsl[fr->callno]); 08025 return 1; 08026 } 08027 } else { 08028 /* Select an appropriate format */ 08029 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08030 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08031 using_prefs = "reqonly"; 08032 } else { 08033 using_prefs = "disabled"; 08034 } 08035 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08036 memset(&pref, 0, sizeof(pref)); 08037 strcpy(caller_pref_buf, "disabled"); 08038 strcpy(host_pref_buf, "disabled"); 08039 } else { 08040 using_prefs = "mine"; 08041 if (ies.codec_prefs) 08042 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08043 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08044 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08045 pref = iaxs[fr->callno]->rprefs; 08046 using_prefs = "caller"; 08047 } else { 08048 pref = iaxs[fr->callno]->prefs; 08049 } 08050 } else /* if no codec_prefs IE do it the old way */ 08051 pref = iaxs[fr->callno]->prefs; 08052 08053 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08054 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08055 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08056 } 08057 if (!format) { 08058 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08059 if (option_debug) 08060 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); 08061 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08062 } 08063 if (!format) { 08064 if (authdebug) { 08065 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08066 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); 08067 else 08068 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); 08069 } 08070 memset(&ied0, 0, sizeof(ied0)); 08071 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08072 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08073 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08074 if (!iaxs[fr->callno]) { 08075 ast_mutex_unlock(&iaxsl[fr->callno]); 08076 return 1; 08077 } 08078 } else { 08079 /* Pick one... */ 08080 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08081 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08082 format = 0; 08083 } else { 08084 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08085 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08086 memset(&pref, 0, sizeof(pref)); 08087 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08088 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08089 strcpy(caller_pref_buf,"disabled"); 08090 strcpy(host_pref_buf,"disabled"); 08091 } else { 08092 using_prefs = "mine"; 08093 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08094 /* Do the opposite of what we tried above. */ 08095 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08096 pref = iaxs[fr->callno]->prefs; 08097 } else { 08098 pref = iaxs[fr->callno]->rprefs; 08099 using_prefs = "caller"; 08100 } 08101 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08102 } else /* if no codec_prefs IE do it the old way */ 08103 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08104 } 08105 } 08106 if (!format) { 08107 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08108 if (authdebug) { 08109 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08110 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); 08111 else 08112 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); 08113 } 08114 memset(&ied0, 0, sizeof(ied0)); 08115 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08116 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08117 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08118 if (!iaxs[fr->callno]) { 08119 ast_mutex_unlock(&iaxsl[fr->callno]); 08120 return 1; 08121 } 08122 } 08123 } 08124 } 08125 if (format) { 08126 /* Authentication received */ 08127 memset(&ied1, 0, sizeof(ied1)); 08128 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08129 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08130 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08131 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08132 if (option_verbose > 2) 08133 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08134 "%srequested format = %s,\n" 08135 "%srequested prefs = %s,\n" 08136 "%sactual format = %s,\n" 08137 "%shost prefs = %s,\n" 08138 "%spriority = %s\n", 08139 ast_inet_ntoa(sin.sin_addr), 08140 VERBOSE_PREFIX_4, 08141 ast_getformatname(iaxs[fr->callno]->peerformat), 08142 VERBOSE_PREFIX_4, 08143 caller_pref_buf, 08144 VERBOSE_PREFIX_4, 08145 ast_getformatname(format), 08146 VERBOSE_PREFIX_4, 08147 host_pref_buf, 08148 VERBOSE_PREFIX_4, 08149 using_prefs); 08150 08151 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08152 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08153 iax2_destroy(fr->callno); 08154 } else { 08155 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08156 /* If this is a TBD call, we're ready but now what... */ 08157 if (option_verbose > 2) 08158 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08159 } 08160 } 08161 } 08162 break; 08163 case IAX_COMMAND_DIAL: 08164 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08165 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08166 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08167 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08168 if (authdebug) 08169 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); 08170 memset(&ied0, 0, sizeof(ied0)); 08171 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08172 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08173 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08174 if (!iaxs[fr->callno]) { 08175 ast_mutex_unlock(&iaxsl[fr->callno]); 08176 return 1; 08177 } 08178 } else { 08179 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08180 if (option_verbose > 2) 08181 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08182 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08183 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08184 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08185 iax2_destroy(fr->callno); 08186 } 08187 } 08188 break; 08189 case IAX_COMMAND_INVAL: 08190 iaxs[fr->callno]->error = ENOTCONN; 08191 if (option_debug) 08192 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08193 iax2_destroy(fr->callno); 08194 if (option_debug) 08195 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08196 break; 08197 case IAX_COMMAND_VNAK: 08198 if (option_debug) 08199 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08200 /* Force retransmission */ 08201 vnak_retransmit(fr->callno, fr->iseqno); 08202 break; 08203 case IAX_COMMAND_REGREQ: 08204 case IAX_COMMAND_REGREL: 08205 /* For security, always ack immediately */ 08206 if (delayreject) 08207 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08208 if (register_verify(fr->callno, &sin, &ies)) { 08209 if (!iaxs[fr->callno]) { 08210 ast_mutex_unlock(&iaxsl[fr->callno]); 08211 return 1; 08212 } 08213 /* Send delayed failure */ 08214 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08215 break; 08216 } 08217 if (!iaxs[fr->callno]) { 08218 ast_mutex_unlock(&iaxsl[fr->callno]); 08219 return 1; 08220 } 08221 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08222 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08223 if (f.subclass == IAX_COMMAND_REGREL) 08224 memset(&sin, 0, sizeof(sin)); 08225 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08226 ast_log(LOG_WARNING, "Registry error\n"); 08227 if (!iaxs[fr->callno]) { 08228 ast_mutex_unlock(&iaxsl[fr->callno]); 08229 return 1; 08230 } 08231 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08232 ast_mutex_unlock(&iaxsl[fr->callno]); 08233 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08234 ast_mutex_lock(&iaxsl[fr->callno]); 08235 if (!iaxs[fr->callno]) { 08236 ast_mutex_unlock(&iaxsl[fr->callno]); 08237 return 1; 08238 } 08239 } 08240 break; 08241 } 08242 registry_authrequest(fr->callno); 08243 if (!iaxs[fr->callno]) { 08244 ast_mutex_unlock(&iaxsl[fr->callno]); 08245 return 1; 08246 } 08247 break; 08248 case IAX_COMMAND_REGACK: 08249 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08250 ast_log(LOG_WARNING, "Registration failure\n"); 08251 /* Send ack immediately, before we destroy */ 08252 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08253 iax2_destroy(fr->callno); 08254 break; 08255 case IAX_COMMAND_REGREJ: 08256 if (iaxs[fr->callno]->reg) { 08257 if (authdebug) { 08258 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)); 08259 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>"); 08260 } 08261 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08262 } 08263 /* Send ack immediately, before we destroy */ 08264 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08265 iax2_destroy(fr->callno); 08266 break; 08267 case IAX_COMMAND_REGAUTH: 08268 /* Authentication request */ 08269 if (registry_rerequest(&ies, fr->callno, &sin)) { 08270 memset(&ied0, 0, sizeof(ied0)); 08271 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08272 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08273 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08274 if (!iaxs[fr->callno]) { 08275 ast_mutex_unlock(&iaxsl[fr->callno]); 08276 return 1; 08277 } 08278 } 08279 break; 08280 case IAX_COMMAND_TXREJ: 08281 iaxs[fr->callno]->transferring = 0; 08282 if (option_verbose > 2) 08283 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08284 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08285 if (iaxs[fr->callno]->bridgecallno) { 08286 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08287 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08288 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08289 } 08290 } 08291 break; 08292 case IAX_COMMAND_TXREADY: 08293 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08294 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08295 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08296 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08297 else 08298 iaxs[fr->callno]->transferring = TRANSFER_READY; 08299 if (option_verbose > 2) 08300 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08301 if (iaxs[fr->callno]->bridgecallno) { 08302 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08303 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08304 /* They're both ready, now release them. */ 08305 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08306 if (option_verbose > 2) 08307 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08308 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08309 08310 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08311 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08312 08313 memset(&ied0, 0, sizeof(ied0)); 08314 memset(&ied1, 0, sizeof(ied1)); 08315 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08316 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08317 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08318 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08319 } else { 08320 if (option_verbose > 2) 08321 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08322 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08323 08324 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08325 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08326 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08327 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08328 08329 /* Stop doing lag & ping requests */ 08330 stop_stuff(fr->callno); 08331 stop_stuff(iaxs[fr->callno]->bridgecallno); 08332 08333 memset(&ied0, 0, sizeof(ied0)); 08334 memset(&ied1, 0, sizeof(ied1)); 08335 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08336 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08337 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08338 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08339 } 08340 08341 } 08342 } 08343 } 08344 break; 08345 case IAX_COMMAND_TXREQ: 08346 try_transfer(iaxs[fr->callno], &ies); 08347 break; 08348 case IAX_COMMAND_TXCNT: 08349 if (iaxs[fr->callno]->transferring) 08350 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08351 break; 08352 case IAX_COMMAND_TXREL: 08353 /* Send ack immediately, rather than waiting until we've changed addresses */ 08354 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08355 complete_transfer(fr->callno, &ies); 08356 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08357 break; 08358 case IAX_COMMAND_TXMEDIA: 08359 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08360 AST_LIST_LOCK(&iaxq.queue); 08361 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08362 /* Cancel any outstanding frames and start anew */ 08363 if ((fr->callno == cur->callno) && (cur->transfer)) { 08364 cur->retries = -1; 08365 } 08366 } 08367 AST_LIST_UNLOCK(&iaxq.queue); 08368 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08369 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08370 } 08371 break; 08372 case IAX_COMMAND_DPREP: 08373 complete_dpreply(iaxs[fr->callno], &ies); 08374 break; 08375 case IAX_COMMAND_UNSUPPORT: 08376 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08377 break; 08378 case IAX_COMMAND_FWDOWNL: 08379 /* Firmware download */ 08380 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08381 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08382 break; 08383 } 08384 memset(&ied0, 0, sizeof(ied0)); 08385 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08386 if (res < 0) 08387 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08388 else if (res > 0) 08389 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08390 else 08391 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08392 if (!iaxs[fr->callno]) { 08393 ast_mutex_unlock(&iaxsl[fr->callno]); 08394 return 1; 08395 } 08396 break; 08397 default: 08398 if (option_debug) 08399 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08400 memset(&ied0, 0, sizeof(ied0)); 08401 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08402 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08403 } 08404 /* Don't actually pass these frames along */ 08405 if ((f.subclass != IAX_COMMAND_ACK) && 08406 (f.subclass != IAX_COMMAND_TXCNT) && 08407 (f.subclass != IAX_COMMAND_TXACC) && 08408 (f.subclass != IAX_COMMAND_INVAL) && 08409 (f.subclass != IAX_COMMAND_VNAK)) { 08410 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08411 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08412 } 08413 ast_mutex_unlock(&iaxsl[fr->callno]); 08414 return 1; 08415 } 08416 /* Unless this is an ACK or INVAL frame, ack it */ 08417 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08418 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08419 } else if (minivid) { 08420 f.frametype = AST_FRAME_VIDEO; 08421 if (iaxs[fr->callno]->videoformat > 0) 08422 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08423 else { 08424 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08425 iax2_vnak(fr->callno); 08426 ast_mutex_unlock(&iaxsl[fr->callno]); 08427 return 1; 08428 } 08429 f.datalen = res - sizeof(*vh); 08430 if (f.datalen) 08431 f.data = thread->buf + sizeof(*vh); 08432 else 08433 f.data = NULL; 08434 #ifdef IAXTESTS 08435 if (test_resync) { 08436 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08437 } else 08438 #endif /* IAXTESTS */ 08439 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08440 } else { 08441 /* A mini frame */ 08442 f.frametype = AST_FRAME_VOICE; 08443 if (iaxs[fr->callno]->voiceformat > 0) 08444 f.subclass = iaxs[fr->callno]->voiceformat; 08445 else { 08446 if (option_debug) 08447 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08448 iax2_vnak(fr->callno); 08449 ast_mutex_unlock(&iaxsl[fr->callno]); 08450 return 1; 08451 } 08452 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08453 if (f.datalen < 0) { 08454 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08455 ast_mutex_unlock(&iaxsl[fr->callno]); 08456 return 1; 08457 } 08458 if (f.datalen) 08459 f.data = thread->buf + sizeof(*mh); 08460 else 08461 f.data = NULL; 08462 #ifdef IAXTESTS 08463 if (test_resync) { 08464 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08465 } else 08466 #endif /* IAXTESTS */ 08467 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08468 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08469 } 08470 /* Don't pass any packets until we're started */ 08471 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08472 ast_mutex_unlock(&iaxsl[fr->callno]); 08473 return 1; 08474 } 08475 /* Common things */ 08476 f.src = "IAX2"; 08477 f.mallocd = 0; 08478 f.offset = 0; 08479 f.len = 0; 08480 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08481 f.samples = ast_codec_get_samples(&f); 08482 /* We need to byteswap incoming slinear samples from network byte order */ 08483 if (f.subclass == AST_FORMAT_SLINEAR) 08484 ast_frame_byteswap_be(&f); 08485 } else 08486 f.samples = 0; 08487 iax_frame_wrap(fr, &f); 08488 08489 /* If this is our most recent packet, use it as our basis for timestamping */ 08490 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08491 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08492 fr->outoforder = 0; 08493 } else { 08494 if (option_debug && iaxdebug && iaxs[fr->callno]) 08495 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); 08496 fr->outoforder = -1; 08497 } 08498 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08499 duped_fr = iaxfrdup2(fr); 08500 if (duped_fr) { 08501 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08502 } 08503 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08504 iaxs[fr->callno]->last = fr->ts; 08505 #if 1 08506 if (option_debug && iaxdebug) 08507 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08508 #endif 08509 } 08510 08511 /* Always run again */ 08512 ast_mutex_unlock(&iaxsl[fr->callno]); 08513 return 1; 08514 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6870 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), 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_WARNING, option_debug, 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().
06871 { 06872 struct iax2_thread *thread; 06873 socklen_t len; 06874 time_t t; 06875 static time_t last_errtime = 0; 06876 struct ast_iax2_full_hdr *fh; 06877 06878 if (!(thread = find_idle_thread())) { 06879 time(&t); 06880 if (t != last_errtime && option_debug) 06881 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 06882 last_errtime = t; 06883 usleep(1); 06884 return 1; 06885 } 06886 06887 len = sizeof(thread->iosin); 06888 thread->iofd = fd; 06889 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06890 thread->buf_size = sizeof(thread->readbuf); 06891 thread->buf = thread->readbuf; 06892 if (thread->buf_len < 0) { 06893 if (errno != ECONNREFUSED && errno != EAGAIN) 06894 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06895 handle_error(); 06896 thread->iostate = IAX_IOSTATE_IDLE; 06897 signal_condition(&thread->lock, &thread->cond); 06898 return 1; 06899 } 06900 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06901 thread->iostate = IAX_IOSTATE_IDLE; 06902 signal_condition(&thread->lock, &thread->cond); 06903 return 1; 06904 } 06905 06906 /* Determine if this frame is a full frame; if so, and any thread is currently 06907 processing a full frame for the same callno from this peer, then drop this 06908 frame (and the peer will retransmit it) */ 06909 fh = (struct ast_iax2_full_hdr *) thread->buf; 06910 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06911 struct iax2_thread *cur = NULL; 06912 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06913 06914 AST_LIST_LOCK(&active_list); 06915 AST_LIST_TRAVERSE(&active_list, cur, list) { 06916 if ((cur->ffinfo.callno == callno) && 06917 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06918 break; 06919 } 06920 if (cur) { 06921 /* we found another thread processing a full frame for this call, 06922 so queue it up for processing later. */ 06923 defer_full_frame(thread, cur); 06924 AST_LIST_UNLOCK(&active_list); 06925 thread->iostate = IAX_IOSTATE_IDLE; 06926 signal_condition(&thread->lock, &thread->cond); 06927 return 1; 06928 } else { 06929 /* this thread is going to process this frame, so mark it */ 06930 thread->ffinfo.callno = callno; 06931 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06932 thread->ffinfo.type = fh->type; 06933 thread->ffinfo.csub = fh->csub; 06934 } 06935 AST_LIST_UNLOCK(&active_list); 06936 } 06937 06938 /* Mark as ready and send on its way */ 06939 thread->iostate = IAX_IOSTATE_READY; 06940 #ifdef DEBUG_SCHED_MULTITHREAD 06941 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06942 #endif 06943 signal_condition(&thread->lock, &thread->cond); 06944 06945 return 1; 06946 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6657 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06658 { 06659 pthread_t newthread; 06660 struct dpreq_data *dpr; 06661 pthread_attr_t attr; 06662 06663 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06664 return; 06665 06666 pthread_attr_init(&attr); 06667 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06668 06669 dpr->callno = callno; 06670 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06671 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06672 if (callerid) 06673 dpr->callerid = ast_strdup(callerid); 06674 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06675 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06676 } 06677 06678 pthread_attr_destroy(&attr); 06679 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9116 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().
09117 { 09118 pthread_attr_t attr; 09119 int threadcount = 0; 09120 int x; 09121 for (x = 0; x < iaxthreadcount; x++) { 09122 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09123 if (thread) { 09124 thread->type = IAX_TYPE_POOL; 09125 thread->threadnum = ++threadcount; 09126 ast_mutex_init(&thread->lock); 09127 ast_cond_init(&thread->cond, NULL); 09128 pthread_attr_init(&attr); 09129 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09130 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09131 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09132 free(thread); 09133 thread = NULL; 09134 } 09135 AST_LIST_LOCK(&idle_list); 09136 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09137 AST_LIST_UNLOCK(&idle_list); 09138 } 09139 } 09140 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09141 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09142 if (option_verbose > 1) 09143 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 09144 return 0; 09145 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6339 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06340 { 06341 iax2_destroy_helper(iaxs[callno]); 06342 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1236 of file chan_iax2.c.
References ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01237 { 01238 if (!pvt->peercallno) { 01239 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01240 return; 01241 } 01242 01243 ao2_link(iax_peercallno_pvts, pvt); 01244 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6526 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_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().
06527 { 06528 char buf[1024]; 06529 int res; 06530 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06531 int processed = 0; 06532 int totalcalls = 0; 06533 #ifdef ZT_TIMERACK 06534 int x = 1; 06535 #endif 06536 struct timeval now; 06537 if (iaxtrunkdebug) 06538 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06539 gettimeofday(&now, NULL); 06540 if (events & AST_IO_PRI) { 06541 #ifdef ZT_TIMERACK 06542 /* Great, this is a timing interface, just call the ioctl */ 06543 if (ioctl(fd, ZT_TIMERACK, &x)) { 06544 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); 06545 usleep(1); 06546 return -1; 06547 } 06548 #endif 06549 } else { 06550 /* Read and ignore from the pseudo channel for timing */ 06551 res = read(fd, buf, sizeof(buf)); 06552 if (res < 1) { 06553 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06554 return 1; 06555 } 06556 } 06557 /* For each peer that supports trunking... */ 06558 ast_mutex_lock(&tpeerlock); 06559 tpeer = tpeers; 06560 while(tpeer) { 06561 processed++; 06562 res = 0; 06563 ast_mutex_lock(&tpeer->lock); 06564 /* We can drop a single tpeer per pass. That makes all this logic 06565 substantially easier */ 06566 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06567 /* Take it out of the list, but don't free it yet, because it 06568 could be in use */ 06569 if (prev) 06570 prev->next = tpeer->next; 06571 else 06572 tpeers = tpeer->next; 06573 drop = tpeer; 06574 } else { 06575 res = send_trunk(tpeer, &now); 06576 if (iaxtrunkdebug) 06577 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); 06578 } 06579 totalcalls += res; 06580 res = 0; 06581 ast_mutex_unlock(&tpeer->lock); 06582 prev = tpeer; 06583 tpeer = tpeer->next; 06584 } 06585 ast_mutex_unlock(&tpeerlock); 06586 if (drop) { 06587 ast_mutex_lock(&drop->lock); 06588 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06589 because by the time they could get tpeerlock, we've already grabbed it */ 06590 if (option_debug) 06591 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06592 if (drop->trunkdata) { 06593 free(drop->trunkdata); 06594 drop->trunkdata = NULL; 06595 } 06596 ast_mutex_unlock(&drop->lock); 06597 ast_mutex_destroy(&drop->lock); 06598 free(drop); 06599 06600 } 06601 if (iaxtrunkdebug) 06602 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06603 iaxtrunkdebug =0; 06604 return 1; 06605 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2062 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02063 { 02064 int res; 02065 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02066 sizeof(*sin)); 02067 if (res < 0) { 02068 if (option_debug) 02069 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02070 handle_error(); 02071 } else 02072 res = 0; 02073 return res; 02074 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1750 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, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01751 { 01752 struct stat stbuf; 01753 struct iax_firmware *cur; 01754 int ifd; 01755 int fd; 01756 int res; 01757 01758 struct ast_iax2_firmware_header *fwh, fwh2; 01759 struct MD5Context md5; 01760 unsigned char sum[16]; 01761 unsigned char buf[1024]; 01762 int len, chunk; 01763 char *s2; 01764 char *last; 01765 s2 = alloca(strlen(s) + 100); 01766 if (!s2) { 01767 ast_log(LOG_WARNING, "Alloca failed!\n"); 01768 return -1; 01769 } 01770 last = strrchr(s, '/'); 01771 if (last) 01772 last++; 01773 else 01774 last = s; 01775 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01776 res = stat(s, &stbuf); 01777 if (res < 0) { 01778 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01779 return -1; 01780 } 01781 /* Make sure it's not a directory */ 01782 if (S_ISDIR(stbuf.st_mode)) 01783 return -1; 01784 ifd = open(s, O_RDONLY); 01785 if (ifd < 0) { 01786 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01787 return -1; 01788 } 01789 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01790 if (fd < 0) { 01791 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01792 close(ifd); 01793 return -1; 01794 } 01795 /* Unlink our newly created file */ 01796 unlink(s2); 01797 01798 /* Now copy the firmware into it */ 01799 len = stbuf.st_size; 01800 while(len) { 01801 chunk = len; 01802 if (chunk > sizeof(buf)) 01803 chunk = sizeof(buf); 01804 res = read(ifd, buf, chunk); 01805 if (res != chunk) { 01806 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01807 close(ifd); 01808 close(fd); 01809 return -1; 01810 } 01811 res = write(fd, buf, chunk); 01812 if (res != chunk) { 01813 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01814 close(ifd); 01815 close(fd); 01816 return -1; 01817 } 01818 len -= chunk; 01819 } 01820 close(ifd); 01821 /* Return to the beginning */ 01822 lseek(fd, 0, SEEK_SET); 01823 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01824 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01825 close(fd); 01826 return -1; 01827 } 01828 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01829 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01830 close(fd); 01831 return -1; 01832 } 01833 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01834 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01835 close(fd); 01836 return -1; 01837 } 01838 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01839 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01840 close(fd); 01841 return -1; 01842 } 01843 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01844 if (fwh == (void *) -1) { 01845 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01846 close(fd); 01847 return -1; 01848 } 01849 MD5Init(&md5); 01850 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01851 MD5Final(sum, &md5); 01852 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01853 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01854 munmap((void*)fwh, stbuf.st_size); 01855 close(fd); 01856 return -1; 01857 } 01858 cur = waresl.wares; 01859 while(cur) { 01860 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01861 /* Found a candidate */ 01862 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01863 /* The version we have on loaded is older, load this one instead */ 01864 break; 01865 /* This version is no newer than what we have. Don't worry about it. 01866 We'll consider it a proper load anyhow though */ 01867 munmap((void*)fwh, stbuf.st_size); 01868 close(fd); 01869 return 0; 01870 } 01871 cur = cur->next; 01872 } 01873 if (!cur) { 01874 /* Allocate a new one and link it */ 01875 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01876 cur->fd = -1; 01877 cur->next = waresl.wares; 01878 waresl.wares = cur; 01879 } 01880 } 01881 if (cur) { 01882 if (cur->fwh) { 01883 munmap((void*)cur->fwh, cur->mmaplen); 01884 } 01885 if (cur->fd > -1) 01886 close(cur->fd); 01887 cur->fwh = fwh; 01888 cur->fd = fd; 01889 cur->mmaplen = stbuf.st_size; 01890 cur->dead = 0; 01891 } 01892 return 0; 01893 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5741 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05742 { 05743 int newcall = 0; 05744 char newip[256]; 05745 struct iax_ie_data ied; 05746 struct sockaddr_in new; 05747 05748 05749 memset(&ied, 0, sizeof(ied)); 05750 if (ies->apparent_addr) 05751 bcopy(ies->apparent_addr, &new, sizeof(new)); 05752 if (ies->callno) 05753 newcall = ies->callno; 05754 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05755 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05756 return -1; 05757 } 05758 pvt->transfercallno = newcall; 05759 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05760 inet_aton(newip, &pvt->transfer.sin_addr); 05761 pvt->transfer.sin_family = AF_INET; 05762 pvt->transferring = TRANSFER_BEGIN; 05763 pvt->transferid = ies->transferid; 05764 if (ies->transferid) 05765 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05766 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05767 return 0; 05768 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1081 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01082 { 01083 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01084 if (csub & IAX_FLAG_SC_LOG) { 01085 /* special case for 'compressed' -1 */ 01086 if (csub == 0xff) 01087 return -1; 01088 else 01089 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01090 } 01091 else 01092 return csub; 01093 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6013 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
06014 { 06015 if (peer->expire > -1) { 06016 if (!ast_sched_del(sched, peer->expire)) { 06017 peer->expire = -1; 06018 peer_unref(peer); 06019 } 06020 } 06021 06022 if (peer->pokeexpire > -1) { 06023 if (!ast_sched_del(sched, peer->pokeexpire)) { 06024 peer->pokeexpire = -1; 06025 peer_unref(peer); 06026 } 06027 } 06028 06029 ao2_unlink(peers, peer); 06030 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11041 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11042 { 11043 ast_custom_function_unregister(&iaxpeer_function); 11044 return __unload_module(); 11045 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3469 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03470 { 03471 ast_mutex_unlock(&iaxsl[callno1]); 03472 ast_mutex_unlock(&iaxsl[callno0]); 03473 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2496 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().
02497 { 02498 int x; 02499 02500 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02501 x = fr->ts - iaxs[fr->callno]->last; 02502 if (x < -50000) { 02503 /* Sudden big jump backwards in timestamp: 02504 What likely happened here is that miniframe timestamp has circled but we haven't 02505 gotten the update from the main packet. We'll just pretend that we did, and 02506 update the timestamp appropriately. */ 02507 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02508 if (option_debug && iaxdebug) 02509 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02510 } 02511 if (x > 50000) { 02512 /* Sudden apparent big jump forwards in timestamp: 02513 What's likely happened is this is an old miniframe belonging to the previous 02514 top-16-bit timestamp that has turned up out of order. 02515 Adjust the timestamp appropriately. */ 02516 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02517 if (option_debug && iaxdebug) 02518 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02519 } 02520 } 02521 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2525 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, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
02526 { 02527 int when; 02528 02529 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02530 02531 when = jb_next(pvt->jb) - when; 02532 02533 AST_SCHED_DEL(sched, pvt->jbid); 02534 02535 if(when <= 0) { 02536 /* XXX should really just empty until when > 0.. */ 02537 when = 1; 02538 } 02539 02540 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02541 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1449 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, maxnontrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01450 { 01451 int max = 1; 01452 int x; 01453 /* XXX Prolly don't need locks here XXX */ 01454 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01455 if (iaxs[x]) 01456 max = x + 1; 01457 } 01458 maxnontrunkcall = max; 01459 if (option_debug && iaxdebug) 01460 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01461 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1256 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), LOG_DEBUG, maxtrunkcall, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01257 { 01258 int max = TRUNK_CALL_START; 01259 int x; 01260 01261 /* XXX Prolly don't need locks here XXX */ 01262 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01263 if (iaxs[x]) { 01264 max = x + 1; 01265 } 01266 } 01267 01268 maxtrunkcall = max; 01269 if (option_debug && iaxdebug) 01270 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01271 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2133 of file chan_iax2.c.
References ast_iax2_full_hdr::dcallno, f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
02134 { 02135 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02136 struct ast_iax2_full_hdr *fh = f->data; 02137 /* Mark this as a retransmission */ 02138 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02139 /* Update iseqno */ 02140 f->iseqno = iaxs[f->callno]->iseqno; 02141 fh->iseqno = f->iseqno; 02142 return 0; 02143 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6124 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(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, 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(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
06125 { 06126 /* Called from IAX thread only, with proper iaxsl lock */ 06127 struct iax_ie_data ied; 06128 struct iax2_peer *p; 06129 int msgcount; 06130 char data[80]; 06131 int version; 06132 const char *peer_name; 06133 int res = -1; 06134 06135 memset(&ied, 0, sizeof(ied)); 06136 06137 peer_name = ast_strdupa(iaxs[callno]->peer); 06138 06139 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06140 ast_mutex_unlock(&iaxsl[callno]); 06141 if (!(p = find_peer(peer_name, 1))) { 06142 ast_mutex_lock(&iaxsl[callno]); 06143 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06144 return -1; 06145 } 06146 ast_mutex_lock(&iaxsl[callno]); 06147 if (!iaxs[callno]) 06148 goto return_unref; 06149 06150 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06151 if (sin->sin_addr.s_addr) { 06152 time_t nowtime; 06153 time(&nowtime); 06154 realtime_update_peer(peer_name, sin, nowtime); 06155 } else { 06156 realtime_update_peer(peer_name, sin, 0); 06157 } 06158 } 06159 if (inaddrcmp(&p->addr, sin)) { 06160 if (iax2_regfunk) 06161 iax2_regfunk(p->name, 1); 06162 /* Stash the IP address from which they registered */ 06163 memcpy(&p->addr, sin, sizeof(p->addr)); 06164 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06165 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06166 ast_db_put("IAX/Registry", p->name, data); 06167 if (option_verbose > 2) 06168 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06169 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06170 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06171 register_peer_exten(p, 1); 06172 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06173 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06174 if (option_verbose > 2) 06175 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06176 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06177 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06178 register_peer_exten(p, 0); 06179 ast_db_del("IAX/Registry", p->name); 06180 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06181 } 06182 /* Update the host */ 06183 /* Verify that the host is really there */ 06184 iax2_poke_peer(p, callno); 06185 } 06186 06187 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06188 if (!iaxs[callno]) { 06189 res = 0; 06190 goto return_unref; 06191 } 06192 06193 /* Store socket fd */ 06194 p->sockfd = fd; 06195 /* Setup the expiry */ 06196 if (p->expire > -1) { 06197 if (!ast_sched_del(sched, p->expire)) { 06198 p->expire = -1; 06199 peer_unref(p); 06200 } 06201 } 06202 /* treat an unspecified refresh interval as the minimum */ 06203 if (!refresh) 06204 refresh = min_reg_expire; 06205 if (refresh > max_reg_expire) { 06206 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06207 p->name, max_reg_expire, refresh); 06208 p->expiry = max_reg_expire; 06209 } else if (refresh < min_reg_expire) { 06210 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06211 p->name, min_reg_expire, refresh); 06212 p->expiry = min_reg_expire; 06213 } else { 06214 p->expiry = refresh; 06215 } 06216 if (p->expiry && sin->sin_addr.s_addr) { 06217 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06218 if (p->expire == -1) 06219 peer_unref(p); 06220 } 06221 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06222 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06223 if (sin->sin_addr.s_addr) { 06224 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06225 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06226 if (!ast_strlen_zero(p->mailbox)) { 06227 int new, old; 06228 ast_app_inboxcount(p->mailbox, &new, &old); 06229 if (new > 255) 06230 new = 255; 06231 if (old > 255) 06232 old = 255; 06233 msgcount = (old << 8) | new; 06234 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06235 } 06236 if (ast_test_flag(p, IAX_HASCALLERID)) { 06237 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06238 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06239 } 06240 } 06241 version = iax_check_version(devtype); 06242 if (version) 06243 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06244 06245 res = 0; 06246 06247 return_unref: 06248 peer_unref(p); 06249 06250 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06251 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1128 of file chan_iax2.c.
Referenced by load_module().
01129 { 01130 struct iax2_user *user = obj, *user2 = arg; 01131 01132 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01133 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9756 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09757 { 09758 struct iax2_user *user = obj; 09759 09760 ast_set_flag(user, IAX_DELME); 09761 09762 return 0; 09763 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9520 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().
09521 { 09522 struct iax2_user *user = obj; 09523 09524 ast_free_ha(user->ha); 09525 free_context(user->contexts); 09526 if(user->vars) { 09527 ast_variables_destroy(user->vars); 09528 user->vars = NULL; 09529 } 09530 ast_string_field_free_memory(user); 09531 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1118 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01119 { 01120 const struct iax2_user *user = obj; 01121 01122 return ast_str_hash(user->name); 01123 }
Definition at line 1167 of file chan_iax2.c.
References ao2_ref().
01168 { 01169 ao2_ref(user, +1); 01170 return user; 01171 }
Definition at line 1173 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().
01174 { 01175 ao2_ref(user, -1); 01176 return NULL; 01177 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6440 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, and send_packet().
Referenced by socket_process().
06441 { 06442 struct iax_frame *f; 06443 06444 AST_LIST_LOCK(&iaxq.queue); 06445 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06446 /* Send a copy immediately */ 06447 if ((f->callno == callno) && iaxs[f->callno] && 06448 ((unsigned char ) (f->oseqno - last) < 128) && 06449 (f->retries >= 0)) { 06450 send_packet(f); 06451 } 06452 } 06453 AST_LIST_UNLOCK(&iaxq.queue); 06454 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 215 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
int amaflags = 0 [static] |
int authdebug = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 156 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 10837 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 10842 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 10852 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 10847 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 10832 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 142 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 10806 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 10798 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 10790 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 172 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 220 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 274 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 223 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 201 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 221 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 174 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 10748 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 863 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 10814 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 822 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_peercallno(), and store_by_peercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 157 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 203 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 159 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 161 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 449 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 809 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __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(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), 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_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 810 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __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(), 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 447 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 205 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 198 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 150 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 144 of file chan_iax2.c.
Definition at line 811 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 166 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 148 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 147 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 153 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 829 of file chan_iax2.c.
Referenced by __find_callno(), and update_max_nontrunk().
int maxtrunkcall = TRUNK_CALL_START [static] |
int min_reg_expire [static] |
Definition at line 165 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 216 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 217 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 170 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 225 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 10810 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 10802 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 10794 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 171 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 8763 of file chan_iax2.c.
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 8765 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 647 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(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 149 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 138 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10744 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8764 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 199 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 228 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 226 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 10736 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 10764 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 10782 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 10768 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 10740 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 10776 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10752 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 10786 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 10732 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 10772 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 10759 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 140 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 207 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 168 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 163 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 154 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 650 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(), 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().