#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"
Include dependency graph for chan_iax2.c:
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START 0x4000 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2), IAX_STATE_UNCHANGED = (1 << 3) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (void *data) |
static void | __auth_reject (void *nothing) |
static void | __auto_congest (void *nothing) |
static void | __auto_hangup (void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (void *data) |
static void | __get_from_jb (void *p) |
static void | __iax2_do_register_s (void *data) |
static void | __iax2_poke_noanswer (void *data) |
static void | __iax2_poke_peer_s (void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static int | __schedule_action (void(*func)(void *data), 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 (void *data) |
static void | __send_ping (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 (void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (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 (void *data) |
static int | auto_hangup (void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (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 (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 (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 (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_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) |
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 | prune_peers (void) |
static void | prune_users (void) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (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 (void) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ast_cli_entry | cli_iax2 [] |
static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static struct timeval | lastused [IAX_MAX_CALLS] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static 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 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 663 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 659 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 673 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 661 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 665 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 667 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 669 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 671 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 122 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 110 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 133 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 128 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 200 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 199 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 198 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 124 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 442 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 138 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 181 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 189 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 194 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 183 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 696 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 700 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 113 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 439 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 645 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 445 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 443 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 127 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 440 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 1227 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 121 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 106 of file chan_iax2.c.
Definition at line 963 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START 0x4000 |
Definition at line 131 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 448 of file chan_iax2.c.
anonymous enum |
Definition at line 234 of file chan_iax2.c.
00234 { 00235 IAX_STATE_STARTED = (1 << 0), 00236 IAX_STATE_AUTHENTICATED = (1 << 1), 00237 IAX_STATE_TBD = (1 << 2), 00238 IAX_STATE_UNCHANGED = (1 << 3), 00239 } iax2_state;
anonymous enum |
Definition at line 246 of file chan_iax2.c.
00246 { 00247 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00248 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00249 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00250 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00251 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00252 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00253 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00254 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00255 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00256 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00257 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00258 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00259 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00260 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00261 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00262 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00263 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00264 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00265 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00266 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00267 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00268 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00269 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00270 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00271 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00272 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00273 response, so that we've achieved a three-way handshake with 00274 them before sending voice or anything else*/ 00275 } 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 394 of file chan_iax2.c.
00394 { 00395 REG_STATE_UNREGISTERED = 0, 00396 REG_STATE_REGSENT, 00397 REG_STATE_AUTHSENT, 00398 REG_STATE_REGISTERED, 00399 REG_STATE_REJECTED, 00400 REG_STATE_TIMEOUT, 00401 REG_STATE_NOAUTH 00402 };
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 404 of file chan_iax2.c.
00404 { 00405 TRANSFER_NONE = 0, 00406 TRANSFER_BEGIN, 00407 TRANSFER_READY, 00408 TRANSFER_RELEASED, 00409 TRANSFER_PASSTHROUGH, 00410 TRANSFER_MBEGIN, 00411 TRANSFER_MREADY, 00412 TRANSFER_MRELEASED, 00413 TRANSFER_MPASSTHROUGH, 00414 TRANSFER_MEDIA, 00415 TRANSFER_MEDIAPASS 00416 };
static void __attempt_transmit | ( | void * | data | ) | [static] |
Definition at line 2032 of file chan_iax2.c.
References chan_iax2_pvt::addr, 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(), ast_sched_add(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, 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().
02033 { 02034 /* Attempt to transmit the frame to the remote peer... 02035 Called without iaxsl held. */ 02036 struct iax_frame *f = data; 02037 int freeme=0; 02038 int callno = f->callno; 02039 /* Make sure this call is still active */ 02040 if (callno) 02041 ast_mutex_lock(&iaxsl[callno]); 02042 if (callno && iaxs[callno]) { 02043 if ((f->retries < 0) /* Already ACK'd */ || 02044 (f->retries >= max_retries) /* Too many attempts */) { 02045 /* Record an error if we've transmitted too many times */ 02046 if (f->retries >= max_retries) { 02047 if (f->transfer) { 02048 /* Transfer timeout */ 02049 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02050 } else if (f->final) { 02051 if (f->final) 02052 iax2_destroy(callno); 02053 } else { 02054 if (iaxs[callno]->owner) 02055 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); 02056 iaxs[callno]->error = ETIMEDOUT; 02057 if (iaxs[callno]->owner) { 02058 struct ast_frame fr = { 0, }; 02059 /* Hangup the fd */ 02060 fr.frametype = AST_FRAME_CONTROL; 02061 fr.subclass = AST_CONTROL_HANGUP; 02062 iax2_queue_frame(callno, &fr); // XXX 02063 /* Remember, owner could disappear */ 02064 if (iaxs[callno] && iaxs[callno]->owner) 02065 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02066 } else { 02067 if (iaxs[callno]->reg) { 02068 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02069 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02070 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02071 } 02072 iax2_destroy(callno); 02073 } 02074 } 02075 02076 } 02077 freeme++; 02078 } else { 02079 /* Update it if it needs it */ 02080 update_packet(f); 02081 /* Attempt transmission */ 02082 send_packet(f); 02083 f->retries++; 02084 /* Try again later after 10 times as long */ 02085 f->retrytime *= 10; 02086 if (f->retrytime > MAX_RETRY_TIME) 02087 f->retrytime = MAX_RETRY_TIME; 02088 /* Transfer messages max out at one second */ 02089 if (f->transfer && (f->retrytime > 1000)) 02090 f->retrytime = 1000; 02091 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 02092 } 02093 } else { 02094 /* Make sure it gets freed */ 02095 f->retries = -1; 02096 freeme++; 02097 } 02098 if (callno) 02099 ast_mutex_unlock(&iaxsl[callno]); 02100 /* Do not try again */ 02101 if (freeme) { 02102 /* Don't attempt delivery, just remove it from the queue */ 02103 AST_LIST_LOCK(&iaxq.queue); 02104 AST_LIST_REMOVE(&iaxq.queue, f, list); 02105 iaxq.count--; 02106 AST_LIST_UNLOCK(&iaxq.queue); 02107 f->retrans = -1; 02108 /* Free the IAX frame */ 02109 iax2_frame_free(f); 02110 } 02111 }
static void __auth_reject | ( | void * | nothing | ) | [static] |
Definition at line 6072 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().
06073 { 06074 /* Called from IAX thread only, without iaxs lock */ 06075 int callno = (int)(long)(nothing); 06076 struct iax_ie_data ied; 06077 ast_mutex_lock(&iaxsl[callno]); 06078 if (iaxs[callno]) { 06079 memset(&ied, 0, sizeof(ied)); 06080 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06081 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06082 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06083 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06084 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06085 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06086 } 06087 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06088 } 06089 ast_mutex_unlock(&iaxsl[callno]); 06090 }
static void __auto_congest | ( | void * | nothing | ) | [static] |
Definition at line 2921 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
02922 { 02923 int callno = PTR_TO_CALLNO(nothing); 02924 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02925 ast_mutex_lock(&iaxsl[callno]); 02926 if (iaxs[callno]) { 02927 iaxs[callno]->initid = -1; 02928 iax2_queue_frame(callno, &f); 02929 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02930 } 02931 ast_mutex_unlock(&iaxsl[callno]); 02932 }
static void __auto_hangup | ( | void * | nothing | ) | [static] |
Definition at line 6122 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().
06123 { 06124 /* Called from IAX thread only, without iaxs lock */ 06125 int callno = (int)(long)(nothing); 06126 struct iax_ie_data ied; 06127 ast_mutex_lock(&iaxsl[callno]); 06128 if (iaxs[callno]) { 06129 memset(&ied, 0, sizeof(ied)); 06130 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06131 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06132 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06133 } 06134 ast_mutex_unlock(&iaxsl[callno]); 06135 }
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 1783 of file chan_iax2.c.
References iax_frame::af, ast_test_flag, iax_frame::callno, ast_frame::has_timing_info, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
01784 { 01785 /* Just deliver the packet by using queueing. This is called by 01786 the IAX thread with the iaxsl lock held. */ 01787 struct iax_frame *fr = data; 01788 fr->retrans = -1; 01789 fr->af.has_timing_info = 0; 01790 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01791 iax2_queue_frame(fr->callno, &fr->af); 01792 /* Free our iax frame */ 01793 iax2_frame_free(fr); 01794 /* And don't run again */ 01795 return 0; 01796 }
static void __expire_registry | ( | void * | data | ) | [static] |
Definition at line 5769 of file chan_iax2.c.
References iax2_peer::addr, ao2_find(), ao2_unlink(), 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(), name, peer_unref(), peers, realtime_update_peer(), and register_peer_exten().
Referenced by expire_registry().
05770 { 05771 char *name = data; 05772 struct iax2_peer *peer = NULL; 05773 struct iax2_peer tmp_peer = { 05774 .name = name, 05775 }; 05776 05777 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 05778 if (!peer) 05779 return; 05780 05781 peer->expire = -1; 05782 05783 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 05784 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05785 realtime_update_peer(peer->name, &peer->addr, 0); 05786 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05787 /* Reset the address */ 05788 memset(&peer->addr, 0, sizeof(peer->addr)); 05789 /* Reset expiry value */ 05790 peer->expiry = min_reg_expire; 05791 if (!ast_test_flag(peer, IAX_TEMPONLY)) 05792 ast_db_del("IAX/Registry", peer->name); 05793 register_peer_exten(peer, 0); 05794 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 05795 if (iax2_regfunk) 05796 iax2_regfunk(peer->name, 0); 05797 05798 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 05799 ao2_unlink(peers, peer); 05800 05801 peer_unref(peer); 05802 }
static void __get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2432 of file chan_iax2.c.
References __do_deliver(), ast_backtrace(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), 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, LOG_ERROR, 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().
02433 { 02434 int callno = PTR_TO_CALLNO(p); 02435 struct chan_iax2_pvt *pvt = NULL; 02436 struct iax_frame *fr; 02437 jb_frame frame; 02438 int ret; 02439 long now; 02440 long next; 02441 struct timeval tv; 02442 02443 /* Make sure we have a valid private structure before going on */ 02444 ast_mutex_lock(&iaxsl[callno]); 02445 pvt = iaxs[callno]; 02446 if (!pvt) { 02447 /* No go! */ 02448 ast_mutex_unlock(&iaxsl[callno]); 02449 return; 02450 } 02451 02452 if( pvt->jb == NULL ) { 02453 ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" ); 02454 ast_backtrace(); 02455 return; 02456 } 02457 02458 pvt->jbid = -1; 02459 02460 gettimeofday(&tv,NULL); 02461 /* round up a millisecond since ast_sched_runq does; */ 02462 /* prevents us from spinning while waiting for our now */ 02463 /* to catch up with runq's now */ 02464 tv.tv_usec += 1000; 02465 02466 now = ast_tvdiff_ms(tv, pvt->rxcore); 02467 02468 if(now >= (next = jb_next(pvt->jb))) { 02469 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02470 switch(ret) { 02471 case JB_OK: 02472 fr = frame.data; 02473 __do_deliver(fr); 02474 /* __do_deliver() can cause the call to disappear */ 02475 pvt = iaxs[callno]; 02476 break; 02477 case JB_INTERP: 02478 { 02479 struct ast_frame af = { 0, }; 02480 02481 /* create an interpolation frame */ 02482 af.frametype = AST_FRAME_VOICE; 02483 af.subclass = pvt->voiceformat; 02484 af.samples = frame.ms * 8; 02485 af.src = "IAX2 JB interpolation"; 02486 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02487 af.offset = AST_FRIENDLY_OFFSET; 02488 02489 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02490 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02491 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02492 iax2_queue_frame(callno, &af); 02493 /* iax2_queue_frame() could cause the call to disappear */ 02494 pvt = iaxs[callno]; 02495 } 02496 } 02497 break; 02498 case JB_DROP: 02499 iax2_frame_free(frame.data); 02500 break; 02501 case JB_NOFRAME: 02502 case JB_EMPTY: 02503 /* do nothing */ 02504 break; 02505 default: 02506 /* shouldn't happen */ 02507 break; 02508 } 02509 } 02510 if (pvt) 02511 update_jbsched(pvt); 02512 ast_mutex_unlock(&iaxsl[callno]); 02513 }
static void __iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5486 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05487 { 05488 struct iax2_registry *reg = data; 05489 reg->expire = -1; 05490 iax2_do_register(reg); 05491 }
static void __iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 8477 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
08478 { 08479 struct iax2_peer *peer = data; 08480 if (peer->lastms > -1) { 08481 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08482 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08483 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08484 } 08485 if (peer->callno > 0) { 08486 ast_mutex_lock(&iaxsl[peer->callno]); 08487 iax2_destroy(peer->callno); 08488 ast_mutex_unlock(&iaxsl[peer->callno]); 08489 } 08490 peer->callno = 0; 08491 peer->lastms = -1; 08492 /* Try again quickly */ 08493 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 08494 }
static void __iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 6186 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by iax2_poke_peer_s().
06187 { 06188 struct iax2_peer *peer = data; 06189 iax2_poke_peer(peer, 0); 06190 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4275 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().
04276 { 04277 regex_t regexbuf; 04278 int havepattern = 0; 04279 int total_peers = 0; 04280 int online_peers = 0; 04281 int offline_peers = 0; 04282 int unmonitored_peers = 0; 04283 ao2_iterator i; 04284 04285 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04286 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04287 04288 struct iax2_peer *peer = NULL; 04289 char name[256]; 04290 int registeredonly=0; 04291 char *term = manager ? "\r\n" : "\n"; 04292 04293 switch (argc) { 04294 case 6: 04295 if (!strcasecmp(argv[3], "registered")) 04296 registeredonly = 1; 04297 else 04298 return RESULT_SHOWUSAGE; 04299 if (!strcasecmp(argv[4], "like")) { 04300 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04301 return RESULT_SHOWUSAGE; 04302 havepattern = 1; 04303 } else 04304 return RESULT_SHOWUSAGE; 04305 break; 04306 case 5: 04307 if (!strcasecmp(argv[3], "like")) { 04308 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04309 return RESULT_SHOWUSAGE; 04310 havepattern = 1; 04311 } else 04312 return RESULT_SHOWUSAGE; 04313 break; 04314 case 4: 04315 if (!strcasecmp(argv[3], "registered")) 04316 registeredonly = 1; 04317 else 04318 return RESULT_SHOWUSAGE; 04319 break; 04320 case 3: 04321 break; 04322 default: 04323 return RESULT_SHOWUSAGE; 04324 } 04325 04326 04327 if (s) 04328 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04329 else 04330 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04331 04332 i = ao2_iterator_init(peers, 0); 04333 for (peer = ao2_iterator_next(&i); peer; 04334 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04335 char nm[20]; 04336 char status[20]; 04337 char srch[2000]; 04338 int retstatus; 04339 04340 if (registeredonly && !peer->addr.sin_addr.s_addr) 04341 continue; 04342 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04343 continue; 04344 04345 if (!ast_strlen_zero(peer->username)) 04346 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04347 else 04348 ast_copy_string(name, peer->name, sizeof(name)); 04349 04350 retstatus = peer_status(peer, status, sizeof(status)); 04351 if (retstatus > 0) 04352 online_peers++; 04353 else if (!retstatus) 04354 offline_peers++; 04355 else 04356 unmonitored_peers++; 04357 04358 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04359 04360 snprintf(srch, sizeof(srch), FORMAT, name, 04361 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04362 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04363 nm, 04364 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04365 peer->encmethods ? "(E)" : " ", status, term); 04366 04367 if (s) 04368 astman_append(s, FORMAT, name, 04369 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04370 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04371 nm, 04372 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04373 peer->encmethods ? "(E)" : " ", status, term); 04374 else 04375 ast_cli(fd, FORMAT, name, 04376 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04377 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04378 nm, 04379 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04380 peer->encmethods ? "(E)" : " ", status, term); 04381 total_peers++; 04382 } 04383 04384 if (s) 04385 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04386 else 04387 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04388 04389 if (havepattern) 04390 regfree(®exbuf); 04391 04392 return RESULT_SUCCESS; 04393 #undef FORMAT 04394 #undef FORMAT2 04395 }
static int __schedule_action | ( | void(*)(void *data) | func, | |
void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 938 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), t, and thread.
00939 { 00940 struct iax2_thread *thread = NULL; 00941 static time_t lasterror; 00942 static time_t t; 00943 00944 thread = find_idle_thread(); 00945 00946 if (thread != NULL) { 00947 thread->schedfunc = func; 00948 thread->scheddata = data; 00949 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00950 #ifdef DEBUG_SCHED_MULTITHREAD 00951 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00952 #endif 00953 signal_condition(&thread->lock, &thread->cond); 00954 return 0; 00955 } 00956 time(&t); 00957 if (t != lasterror) 00958 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n"); 00959 lasterror = t; 00960 00961 return -1; 00962 }
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 4775 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04777 { 04778 struct ast_frame f = { 0, }; 04779 04780 f.frametype = type; 04781 f.subclass = command; 04782 f.datalen = datalen; 04783 f.src = __FUNCTION__; 04784 f.data = (void *) data; 04785 04786 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04787 }
static void __send_lagrq | ( | void * | data | ) | [static] |
Definition at line 1002 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_registry::callno, IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01003 { 01004 int callno = (long)data; 01005 /* Ping only if it's real not if it's bridged */ 01006 ast_mutex_lock(&iaxsl[callno]); 01007 if (iaxs[callno] && iaxs[callno]->lagid != -1) { 01008 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01009 iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01010 } 01011 ast_mutex_unlock(&iaxsl[callno]); 01012 }
static void __send_ping | ( | void * | data | ) | [static] |
Definition at line 968 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_registry::callno, IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
00969 { 00970 int callno = (long)data; 00971 ast_mutex_lock(&iaxsl[callno]); 00972 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00973 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00974 iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data); 00975 } 00976 ast_mutex_unlock(&iaxsl[callno]); 00977 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10570 of file chan_iax2.c.
References ao2_ref(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, netsock, outsock, peers, sched, sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10571 { 10572 struct iax2_thread *thread = NULL; 10573 int x; 10574 10575 /* Make sure threads do not hold shared resources when they are canceled */ 10576 10577 /* Grab the sched lock resource to keep it away from threads about to die */ 10578 /* Cancel the network thread, close the net socket */ 10579 if (netthreadid != AST_PTHREADT_NULL) { 10580 AST_LIST_LOCK(&iaxq.queue); 10581 ast_mutex_lock(&sched_lock); 10582 pthread_cancel(netthreadid); 10583 ast_cond_signal(&sched_cond); 10584 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10585 AST_LIST_UNLOCK(&iaxq.queue); 10586 pthread_join(netthreadid, NULL); 10587 } 10588 if (schedthreadid != AST_PTHREADT_NULL) { 10589 ast_mutex_lock(&sched_lock); 10590 pthread_cancel(schedthreadid); 10591 ast_cond_signal(&sched_cond); 10592 ast_mutex_unlock(&sched_lock); 10593 pthread_join(schedthreadid, NULL); 10594 } 10595 10596 /* Call for all threads to halt */ 10597 AST_LIST_LOCK(&idle_list); 10598 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10599 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10600 pthread_cancel(thread->threadid); 10601 } 10602 AST_LIST_TRAVERSE_SAFE_END 10603 AST_LIST_UNLOCK(&idle_list); 10604 10605 AST_LIST_LOCK(&active_list); 10606 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10607 AST_LIST_REMOVE_CURRENT(&active_list, list); 10608 pthread_cancel(thread->threadid); 10609 } 10610 AST_LIST_TRAVERSE_SAFE_END 10611 AST_LIST_UNLOCK(&active_list); 10612 10613 AST_LIST_LOCK(&dynamic_list); 10614 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10615 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10616 pthread_cancel(thread->threadid); 10617 } 10618 AST_LIST_TRAVERSE_SAFE_END 10619 AST_LIST_UNLOCK(&dynamic_list); 10620 10621 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10622 10623 /* Wait for threads to exit */ 10624 while(0 < iaxactivethreadcount) 10625 usleep(10000); 10626 10627 ast_netsock_release(netsock); 10628 ast_netsock_release(outsock); 10629 for (x=0;x<IAX_MAX_CALLS;x++) 10630 if (iaxs[x]) 10631 iax2_destroy(x); 10632 ast_manager_unregister( "IAXpeers" ); 10633 ast_manager_unregister( "IAXnetstats" ); 10634 ast_unregister_application(papp); 10635 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10636 ast_unregister_switch(&iax2_switch); 10637 ast_channel_unregister(&iax2_tech); 10638 delete_users(); 10639 iax_provision_unload(); 10640 sched_context_destroy(sched); 10641 10642 ast_mutex_destroy(&waresl.lock); 10643 10644 for (x = 0; x < IAX_MAX_CALLS; x++) 10645 ast_mutex_destroy(&iaxsl[x]); 10646 10647 ao2_ref(peers, -1); 10648 ao2_ref(users, -1); 10649 10650 return 0; 10651 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 4828 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04829 { 04830 while(con) { 04831 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04832 return -1; 04833 con = con->next; 04834 } 04835 return 0; 04836 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4603 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04604 { 04605 int x; 04606 int numchans = 0; 04607 for (x=0;x<IAX_MAX_CALLS;x++) { 04608 ast_mutex_lock(&iaxsl[x]); 04609 if (iaxs[x]) { 04610 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04611 char *fmt; 04612 jb_info jbinfo; 04613 04614 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04615 jb_getinfo(iaxs[x]->jb, &jbinfo); 04616 localjitter = jbinfo.jitter; 04617 localdelay = jbinfo.current - jbinfo.min; 04618 locallost = jbinfo.frames_lost; 04619 locallosspct = jbinfo.losspct/1000; 04620 localdropped = jbinfo.frames_dropped; 04621 localooo = jbinfo.frames_ooo; 04622 } else { 04623 localjitter = -1; 04624 localdelay = 0; 04625 locallost = -1; 04626 locallosspct = -1; 04627 localdropped = 0; 04628 localooo = -1; 04629 } 04630 if (limit_fmt) 04631 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04632 else 04633 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04634 if (s) 04635 04636 astman_append(s, fmt, 04637 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04638 iaxs[x]->pingtime, 04639 localjitter, 04640 localdelay, 04641 locallost, 04642 locallosspct, 04643 localdropped, 04644 localooo, 04645 iaxs[x]->frames_received/1000, 04646 iaxs[x]->remote_rr.jitter, 04647 iaxs[x]->remote_rr.delay, 04648 iaxs[x]->remote_rr.losscnt, 04649 iaxs[x]->remote_rr.losspct, 04650 iaxs[x]->remote_rr.dropped, 04651 iaxs[x]->remote_rr.ooo, 04652 iaxs[x]->remote_rr.packets/1000); 04653 else 04654 ast_cli(fd, fmt, 04655 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04656 iaxs[x]->pingtime, 04657 localjitter, 04658 localdelay, 04659 locallost, 04660 locallosspct, 04661 localdropped, 04662 localooo, 04663 iaxs[x]->frames_received/1000, 04664 iaxs[x]->remote_rr.jitter, 04665 iaxs[x]->remote_rr.delay, 04666 iaxs[x]->remote_rr.losscnt, 04667 iaxs[x]->remote_rr.losspct, 04668 iaxs[x]->remote_rr.dropped, 04669 iaxs[x]->remote_rr.ooo, 04670 iaxs[x]->remote_rr.packets/1000 04671 ); 04672 numchans++; 04673 } 04674 ast_mutex_unlock(&iaxsl[x]); 04675 } 04676 return numchans; 04677 }
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 3513 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, iax2_tech, iaxs, iaxsl, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
03514 { 03515 struct ast_channel *tmp; 03516 struct chan_iax2_pvt *i; 03517 struct ast_variable *v = NULL; 03518 03519 if (!(i = iaxs[callno])) { 03520 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03521 return NULL; 03522 } 03523 03524 /* Don't hold call lock */ 03525 ast_mutex_unlock(&iaxsl[callno]); 03526 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); 03527 ast_mutex_lock(&iaxsl[callno]); 03528 if (!tmp) 03529 return NULL; 03530 tmp->tech = &iax2_tech; 03531 /* We can support any format by default, until we get restricted */ 03532 tmp->nativeformats = capability; 03533 tmp->readformat = ast_best_codec(capability); 03534 tmp->writeformat = ast_best_codec(capability); 03535 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03536 03537 /* Don't use ast_set_callerid() here because it will 03538 * generate a NewCallerID event before the NewChannel event */ 03539 if (!ast_strlen_zero(i->ani)) 03540 tmp->cid.cid_ani = ast_strdup(i->ani); 03541 else 03542 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03543 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03544 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03545 tmp->cid.cid_pres = i->calling_pres; 03546 tmp->cid.cid_ton = i->calling_ton; 03547 tmp->cid.cid_tns = i->calling_tns; 03548 if (!ast_strlen_zero(i->language)) 03549 ast_string_field_set(tmp, language, i->language); 03550 if (!ast_strlen_zero(i->accountcode)) 03551 ast_string_field_set(tmp, accountcode, i->accountcode); 03552 if (i->amaflags) 03553 tmp->amaflags = i->amaflags; 03554 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03555 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03556 if (i->adsi) 03557 tmp->adsicpe = i->peeradsicpe; 03558 else 03559 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03560 i->owner = tmp; 03561 i->capability = capability; 03562 03563 for (v = i->vars ; v ; v = v->next) 03564 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03565 03566 if (state != AST_STATE_DOWN) { 03567 if (ast_pbx_start(tmp)) { 03568 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03569 ast_hangup(tmp); 03570 i->owner = NULL; 03571 return NULL; 03572 } 03573 } 03574 03575 ast_module_ref(ast_module_info->self); 03576 03577 return tmp; 03578 }
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 | ( | void * | data | ) | [static] |
Definition at line 2113 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02114 { 02115 #ifdef SCHED_MULTITHREADED 02116 if (schedule_action(__attempt_transmit, data)) 02117 #endif 02118 __attempt_transmit(data); 02119 return 0; 02120 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6106 of file chan_iax2.c.
References ast_sched_add(), ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iaxs, and sched.
Referenced by socket_process().
06107 { 06108 /* Schedule sending the authentication failure in one second, to prevent 06109 guessing */ 06110 if (iaxs[callno]) { 06111 iaxs[callno]->authfail = failcode; 06112 if (delayreject) { 06113 if (iaxs[callno]->authid > -1) 06114 ast_sched_del(sched, iaxs[callno]->authid); 06115 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06116 } else 06117 auth_reject((void *)(long)callno); 06118 } 06119 return 0; 06120 }
static int auth_reject | ( | void * | data | ) | [static] |
Definition at line 6092 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().
06093 { 06094 int callno = (int)(long)(data); 06095 ast_mutex_lock(&iaxsl[callno]); 06096 if (iaxs[callno]) 06097 iaxs[callno]->authid = -1; 06098 ast_mutex_unlock(&iaxsl[callno]); 06099 #ifdef SCHED_MULTITHREADED 06100 if (schedule_action(__auth_reject, data)) 06101 #endif 06102 __auth_reject(data); 06103 return 0; 06104 }
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 5355 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05356 { 05357 int res = -1; 05358 int x; 05359 if (!ast_strlen_zero(keyn)) { 05360 if (!(authmethods & IAX_AUTH_RSA)) { 05361 if (ast_strlen_zero(secret)) 05362 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)); 05363 } else if (ast_strlen_zero(challenge)) { 05364 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05365 } else { 05366 char sig[256]; 05367 struct ast_key *key; 05368 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05369 if (!key) { 05370 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05371 } else { 05372 if (ast_sign(key, (char*)challenge, sig)) { 05373 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05374 res = -1; 05375 } else { 05376 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05377 res = 0; 05378 } 05379 } 05380 } 05381 } 05382 /* Fall back */ 05383 if (res && !ast_strlen_zero(secret)) { 05384 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05385 struct MD5Context md5; 05386 unsigned char digest[16]; 05387 char digres[128]; 05388 MD5Init(&md5); 05389 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05390 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05391 MD5Final(digest, &md5); 05392 /* If they support md5, authenticate with it. */ 05393 for (x=0;x<16;x++) 05394 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05395 if (ecx && dcx) 05396 build_enc_keys(digest, ecx, dcx); 05397 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05398 res = 0; 05399 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05400 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05401 res = 0; 05402 } else 05403 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05404 } 05405 return res; 05406 }
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 5412 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().
05413 { 05414 struct iax2_peer *peer = NULL; 05415 /* Start pessimistic */ 05416 int res = -1; 05417 int authmethods = 0; 05418 struct iax_ie_data ied; 05419 uint16_t callno = p->callno; 05420 05421 memset(&ied, 0, sizeof(ied)); 05422 05423 if (ies->username) 05424 ast_string_field_set(p, username, ies->username); 05425 if (ies->challenge) 05426 ast_string_field_set(p, challenge, ies->challenge); 05427 if (ies->authmethods) 05428 authmethods = ies->authmethods; 05429 if (authmethods & IAX_AUTH_MD5) 05430 merge_encryption(p, ies->encmethods); 05431 else 05432 p->encmethods = 0; 05433 05434 /* Check for override RSA authentication first */ 05435 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05436 /* Normal password authentication */ 05437 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05438 } else { 05439 ao2_iterator i = ao2_iterator_init(peers, 0); 05440 while ((peer = ao2_iterator_next(&i))) { 05441 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05442 /* No peer specified at our end, or this is the peer */ 05443 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05444 /* No username specified in peer rule, or this is the right username */ 05445 && (!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))) 05446 /* No specified host, or this is our host */ 05447 ) { 05448 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05449 if (!res) { 05450 peer_unref(peer); 05451 break; 05452 } 05453 } 05454 peer_unref(peer); 05455 } 05456 if (!peer) { 05457 /* We checked our list and didn't find one. It's unlikely, but possible, 05458 that we're trying to authenticate *to* a realtime peer */ 05459 const char *peer_name = ast_strdupa(p->peer); 05460 ast_mutex_unlock(&iaxsl[callno]); 05461 if ((peer = realtime_peer(peer_name, NULL))) { 05462 ast_mutex_lock(&iaxsl[callno]); 05463 if (!(p = iaxs[callno])) { 05464 peer_unref(peer); 05465 return -1; 05466 } 05467 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05468 peer_unref(peer); 05469 } 05470 if (!peer) { 05471 ast_mutex_lock(&iaxsl[callno]); 05472 if (!(p = iaxs[callno])) 05473 return -1; 05474 } 05475 } 05476 } 05477 if (ies->encmethods) 05478 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05479 if (!res) 05480 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05481 return res; 05482 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5090 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().
05091 { 05092 struct iax_ie_data ied; 05093 int res = -1, authreq_restrict = 0; 05094 char challenge[10]; 05095 struct chan_iax2_pvt *p = iaxs[call_num]; 05096 05097 memset(&ied, 0, sizeof(ied)); 05098 05099 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05100 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05101 struct iax2_user *user, tmp_user = { 05102 .name = p->username, 05103 }; 05104 05105 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05106 if (user) { 05107 if (user->curauthreq == user->maxauthreq) 05108 authreq_restrict = 1; 05109 else 05110 user->curauthreq++; 05111 user = user_unref(user); 05112 } 05113 } 05114 05115 /* If the AUTHREQ limit test failed, send back an error */ 05116 if (authreq_restrict) { 05117 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05118 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05119 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05120 return 0; 05121 } 05122 05123 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05124 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05125 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05126 ast_string_field_set(p, challenge, challenge); 05127 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05128 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05129 } 05130 if (p->encmethods) 05131 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05132 05133 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05134 05135 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05136 05137 if (p->encmethods) 05138 ast_set_flag(p, IAX_ENCRYPTED); 05139 05140 return res; 05141 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5143 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, key(), LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05144 { 05145 char requeststr[256]; 05146 char md5secret[256] = ""; 05147 char secret[256] = ""; 05148 char rsasecret[256] = ""; 05149 int res = -1; 05150 int x; 05151 struct iax2_user *user, tmp_user = { 05152 .name = p->username, 05153 }; 05154 05155 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05156 if (user) { 05157 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05158 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05159 ast_clear_flag(p, IAX_MAXAUTHREQ); 05160 } 05161 ast_string_field_set(p, host, user->name); 05162 user = user_unref(user); 05163 } 05164 05165 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05166 return res; 05167 if (ies->password) 05168 ast_copy_string(secret, ies->password, sizeof(secret)); 05169 if (ies->md5_result) 05170 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05171 if (ies->rsa_result) 05172 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05173 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05174 struct ast_key *key; 05175 char *keyn; 05176 char tmpkey[256]; 05177 char *stringp=NULL; 05178 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05179 stringp=tmpkey; 05180 keyn = strsep(&stringp, ":"); 05181 while(keyn) { 05182 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05183 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05184 res = 0; 05185 break; 05186 } else if (!key) 05187 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05188 keyn = strsep(&stringp, ":"); 05189 } 05190 } else if (p->authmethods & IAX_AUTH_MD5) { 05191 struct MD5Context md5; 05192 unsigned char digest[16]; 05193 char *tmppw, *stringp; 05194 05195 tmppw = ast_strdupa(p->secret); 05196 stringp = tmppw; 05197 while((tmppw = strsep(&stringp, ";"))) { 05198 MD5Init(&md5); 05199 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05200 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05201 MD5Final(digest, &md5); 05202 /* If they support md5, authenticate with it. */ 05203 for (x=0;x<16;x++) 05204 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05205 if (!strcasecmp(requeststr, md5secret)) { 05206 res = 0; 05207 break; 05208 } 05209 } 05210 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05211 if (!strcmp(secret, p->secret)) 05212 res = 0; 05213 } 05214 return res; 05215 }
static int auto_congest | ( | void * | data | ) | [static] |
Definition at line 2934 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
02935 { 02936 #ifdef SCHED_MULTITHREADED 02937 if (schedule_action(__auto_congest, data)) 02938 #endif 02939 __auto_congest(data); 02940 return 0; 02941 }
static int auto_hangup | ( | void * | data | ) | [static] |
Definition at line 6137 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().
06138 { 06139 int callno = (int)(long)(data); 06140 ast_mutex_lock(&iaxsl[callno]); 06141 if (iaxs[callno]) { 06142 iaxs[callno]->autoid = -1; 06143 } 06144 ast_mutex_unlock(&iaxsl[callno]); 06145 #ifdef SCHED_MULTITHREADED 06146 if (schedule_action(__auto_hangup, data)) 06147 #endif 06148 __auto_hangup(data); 06149 return 0; 06150 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 8783 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
08784 { 08785 struct iax2_context *con; 08786 08787 if ((con = ast_calloc(1, sizeof(*con)))) 08788 ast_copy_string(con->context, context, sizeof(con->context)); 08789 08790 return con; 08791 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3872 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03873 { 03874 aes_encrypt_key128(digest, ecx); 03875 aes_decrypt_key128(digest, dcx); 03876 }
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 8932 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ao2_unlink(), 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_free_pools, 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, and ast_variable::value.
08933 { 08934 struct iax2_peer *peer = NULL; 08935 struct ast_ha *oldha = NULL; 08936 int maskfound=0; 08937 int found=0; 08938 int firstpass=1; 08939 struct iax2_peer tmp_peer = { 08940 .name = name, 08941 }; 08942 08943 if (!temponly) { 08944 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 08945 if (peer && !ast_test_flag(peer, IAX_DELME)) 08946 firstpass = 0; 08947 } 08948 08949 if (peer) { 08950 found++; 08951 if (firstpass) { 08952 oldha = peer->ha; 08953 peer->ha = NULL; 08954 } 08955 ao2_unlink(peers, peer); 08956 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 08957 peer->expire = -1; 08958 peer->pokeexpire = -1; 08959 peer->sockfd = defaultsockfd; 08960 if (ast_string_field_init(peer, 32)) 08961 peer = peer_unref(peer); 08962 } 08963 08964 if (peer) { 08965 if (firstpass) { 08966 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08967 peer->encmethods = iax2_encryption; 08968 peer->adsi = adsi; 08969 ast_string_field_set(peer,secret,""); 08970 if (!found) { 08971 ast_string_field_set(peer, name, name); 08972 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08973 peer->expiry = min_reg_expire; 08974 } 08975 peer->prefs = prefs; 08976 peer->capability = iax2_capability; 08977 peer->smoothing = 0; 08978 peer->pokefreqok = DEFAULT_FREQ_OK; 08979 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08980 ast_string_field_set(peer,context,""); 08981 ast_string_field_set(peer,peercontext,""); 08982 ast_clear_flag(peer, IAX_HASCALLERID); 08983 ast_string_field_set(peer, cid_name, ""); 08984 ast_string_field_set(peer, cid_num, ""); 08985 } 08986 08987 if (!v) { 08988 v = alt; 08989 alt = NULL; 08990 } 08991 while(v) { 08992 if (!strcasecmp(v->name, "secret")) { 08993 ast_string_field_set(peer, secret, v->value); 08994 } else if (!strcasecmp(v->name, "mailbox")) { 08995 ast_string_field_set(peer, mailbox, v->value); 08996 } else if (!strcasecmp(v->name, "mohinterpret")) { 08997 ast_string_field_set(peer, mohinterpret, v->value); 08998 } else if (!strcasecmp(v->name, "mohsuggest")) { 08999 ast_string_field_set(peer, mohsuggest, v->value); 09000 } else if (!strcasecmp(v->name, "dbsecret")) { 09001 ast_string_field_set(peer, dbsecret, v->value); 09002 } else if (!strcasecmp(v->name, "trunk")) { 09003 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09004 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09005 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09006 ast_clear_flag(peer, IAX_TRUNK); 09007 } 09008 } else if (!strcasecmp(v->name, "auth")) { 09009 peer->authmethods = get_auth_methods(v->value); 09010 } else if (!strcasecmp(v->name, "encryption")) { 09011 peer->encmethods = get_encrypt_methods(v->value); 09012 } else if (!strcasecmp(v->name, "notransfer")) { 09013 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09014 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09015 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09016 } else if (!strcasecmp(v->name, "transfer")) { 09017 if (!strcasecmp(v->value, "mediaonly")) { 09018 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09019 } else if (ast_true(v->value)) { 09020 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09021 } else 09022 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09023 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09024 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09025 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09026 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09027 } else if (!strcasecmp(v->name, "host")) { 09028 if (!strcasecmp(v->value, "dynamic")) { 09029 /* They'll register with us */ 09030 ast_set_flag(peer, IAX_DYNAMIC); 09031 if (!found) { 09032 /* Initialize stuff iff we're not found, otherwise 09033 we keep going with what we had */ 09034 memset(&peer->addr.sin_addr, 0, 4); 09035 if (peer->addr.sin_port) { 09036 /* If we've already got a port, make it the default rather than absolute */ 09037 peer->defaddr.sin_port = peer->addr.sin_port; 09038 peer->addr.sin_port = 0; 09039 } 09040 } 09041 } else { 09042 /* Non-dynamic. Make sure we become that way if we're not */ 09043 if (peer->expire > -1) 09044 ast_sched_del(sched, peer->expire); 09045 peer->expire = -1; 09046 ast_clear_flag(peer, IAX_DYNAMIC); 09047 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 09048 ast_string_field_free_pools(peer); 09049 return peer_unref(peer); 09050 } 09051 if (!peer->addr.sin_port) 09052 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09053 } 09054 if (!maskfound) 09055 inet_aton("255.255.255.255", &peer->mask); 09056 } else if (!strcasecmp(v->name, "defaultip")) { 09057 if (ast_get_ip(&peer->defaddr, v->value)) { 09058 ast_string_field_free_pools(peer); 09059 return peer_unref(peer); 09060 } 09061 } else if (!strcasecmp(v->name, "sourceaddress")) { 09062 peer_set_srcaddr(peer, v->value); 09063 } else if (!strcasecmp(v->name, "permit") || 09064 !strcasecmp(v->name, "deny")) { 09065 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09066 } else if (!strcasecmp(v->name, "mask")) { 09067 maskfound++; 09068 inet_aton(v->value, &peer->mask); 09069 } else if (!strcasecmp(v->name, "context")) { 09070 ast_string_field_set(peer, context, v->value); 09071 } else if (!strcasecmp(v->name, "regexten")) { 09072 ast_string_field_set(peer, regexten, v->value); 09073 } else if (!strcasecmp(v->name, "peercontext")) { 09074 ast_string_field_set(peer, peercontext, v->value); 09075 } else if (!strcasecmp(v->name, "port")) { 09076 if (ast_test_flag(peer, IAX_DYNAMIC)) 09077 peer->defaddr.sin_port = htons(atoi(v->value)); 09078 else 09079 peer->addr.sin_port = htons(atoi(v->value)); 09080 } else if (!strcasecmp(v->name, "username")) { 09081 ast_string_field_set(peer, username, v->value); 09082 } else if (!strcasecmp(v->name, "allow")) { 09083 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09084 } else if (!strcasecmp(v->name, "disallow")) { 09085 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09086 } else if (!strcasecmp(v->name, "callerid")) { 09087 if (!ast_strlen_zero(v->value)) { 09088 char name2[80]; 09089 char num2[80]; 09090 ast_callerid_split(v->value, name2, 80, num2, 80); 09091 ast_string_field_set(peer, cid_name, name2); 09092 ast_string_field_set(peer, cid_num, num2); 09093 ast_set_flag(peer, IAX_HASCALLERID); 09094 } else { 09095 ast_clear_flag(peer, IAX_HASCALLERID); 09096 ast_string_field_set(peer, cid_name, ""); 09097 ast_string_field_set(peer, cid_num, ""); 09098 } 09099 } else if (!strcasecmp(v->name, "fullname")) { 09100 if (!ast_strlen_zero(v->value)) { 09101 ast_string_field_set(peer, cid_name, v->value); 09102 ast_set_flag(peer, IAX_HASCALLERID); 09103 } else { 09104 ast_string_field_set(peer, cid_name, ""); 09105 if (ast_strlen_zero(peer->cid_num)) 09106 ast_clear_flag(peer, IAX_HASCALLERID); 09107 } 09108 } else if (!strcasecmp(v->name, "cid_number")) { 09109 if (!ast_strlen_zero(v->value)) { 09110 ast_string_field_set(peer, cid_num, v->value); 09111 ast_set_flag(peer, IAX_HASCALLERID); 09112 } else { 09113 ast_string_field_set(peer, cid_num, ""); 09114 if (ast_strlen_zero(peer->cid_name)) 09115 ast_clear_flag(peer, IAX_HASCALLERID); 09116 } 09117 } else if (!strcasecmp(v->name, "sendani")) { 09118 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09119 } else if (!strcasecmp(v->name, "inkeys")) { 09120 ast_string_field_set(peer, inkeys, v->value); 09121 } else if (!strcasecmp(v->name, "outkey")) { 09122 ast_string_field_set(peer, outkey, v->value); 09123 } else if (!strcasecmp(v->name, "qualify")) { 09124 if (!strcasecmp(v->value, "no")) { 09125 peer->maxms = 0; 09126 } else if (!strcasecmp(v->value, "yes")) { 09127 peer->maxms = DEFAULT_MAXMS; 09128 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09129 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); 09130 peer->maxms = 0; 09131 } 09132 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09133 peer->smoothing = ast_true(v->value); 09134 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09135 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09136 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); 09137 } 09138 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09139 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09140 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); 09141 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09142 } else if (!strcasecmp(v->name, "timezone")) { 09143 ast_string_field_set(peer, zonetag, v->value); 09144 } else if (!strcasecmp(v->name, "adsi")) { 09145 peer->adsi = ast_true(v->value); 09146 }/* else if (strcasecmp(v->name,"type")) */ 09147 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09148 v = v->next; 09149 if (!v) { 09150 v = alt; 09151 alt = NULL; 09152 } 09153 } 09154 if (!peer->authmethods) 09155 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09156 ast_clear_flag(peer, IAX_DELME); 09157 /* Make sure these are IPv4 addresses */ 09158 peer->addr.sin_family = AF_INET; 09159 } 09160 if (oldha) 09161 ast_free_ha(oldha); 09162 return peer; 09163 }
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 9179 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_pools, 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.
09180 { 09181 struct iax2_user *user = NULL; 09182 struct iax2_context *con, *conl = NULL; 09183 struct ast_ha *oldha = NULL; 09184 struct iax2_context *oldcon = NULL; 09185 int format; 09186 int firstpass=1; 09187 int oldcurauthreq = 0; 09188 char *varname = NULL, *varval = NULL; 09189 struct ast_variable *tmpvar = NULL; 09190 struct iax2_user tmp_user = { 09191 .name = name, 09192 }; 09193 09194 if (!temponly) { 09195 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09196 if (user && !ast_test_flag(user, IAX_DELME)) 09197 firstpass = 0; 09198 } 09199 09200 if (user) { 09201 if (firstpass) { 09202 oldcurauthreq = user->curauthreq; 09203 oldha = user->ha; 09204 oldcon = user->contexts; 09205 user->ha = NULL; 09206 user->contexts = NULL; 09207 } 09208 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09209 ao2_unlink(users, user); 09210 } else { 09211 user = ao2_alloc(sizeof(*user), user_destructor); 09212 } 09213 09214 if (user) { 09215 if (firstpass) { 09216 ast_string_field_free_pools(user); 09217 memset(user, 0, sizeof(struct iax2_user)); 09218 if (ast_string_field_init(user, 32)) { 09219 user = user_unref(user); 09220 goto cleanup; 09221 } 09222 user->maxauthreq = maxauthreq; 09223 user->curauthreq = oldcurauthreq; 09224 user->prefs = prefs; 09225 user->capability = iax2_capability; 09226 user->encmethods = iax2_encryption; 09227 user->adsi = adsi; 09228 ast_string_field_set(user, name, name); 09229 ast_string_field_set(user, language, language); 09230 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09231 ast_clear_flag(user, IAX_HASCALLERID); 09232 ast_string_field_set(user, cid_name, ""); 09233 ast_string_field_set(user, cid_num, ""); 09234 } 09235 if (!v) { 09236 v = alt; 09237 alt = NULL; 09238 } 09239 while(v) { 09240 if (!strcasecmp(v->name, "context")) { 09241 con = build_context(v->value); 09242 if (con) { 09243 if (conl) 09244 conl->next = con; 09245 else 09246 user->contexts = con; 09247 conl = con; 09248 } 09249 } else if (!strcasecmp(v->name, "permit") || 09250 !strcasecmp(v->name, "deny")) { 09251 user->ha = ast_append_ha(v->name, v->value, user->ha); 09252 } else if (!strcasecmp(v->name, "setvar")) { 09253 varname = ast_strdupa(v->value); 09254 if (varname && (varval = strchr(varname,'='))) { 09255 *varval = '\0'; 09256 varval++; 09257 if((tmpvar = ast_variable_new(varname, varval))) { 09258 tmpvar->next = user->vars; 09259 user->vars = tmpvar; 09260 } 09261 } 09262 } else if (!strcasecmp(v->name, "allow")) { 09263 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09264 } else if (!strcasecmp(v->name, "disallow")) { 09265 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09266 } else if (!strcasecmp(v->name, "trunk")) { 09267 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09268 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09269 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09270 ast_clear_flag(user, IAX_TRUNK); 09271 } 09272 } else if (!strcasecmp(v->name, "auth")) { 09273 user->authmethods = get_auth_methods(v->value); 09274 } else if (!strcasecmp(v->name, "encryption")) { 09275 user->encmethods = get_encrypt_methods(v->value); 09276 } else if (!strcasecmp(v->name, "notransfer")) { 09277 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09278 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09279 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09280 } else if (!strcasecmp(v->name, "transfer")) { 09281 if (!strcasecmp(v->value, "mediaonly")) { 09282 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09283 } else if (ast_true(v->value)) { 09284 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09285 } else 09286 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09287 } else if (!strcasecmp(v->name, "codecpriority")) { 09288 if(!strcasecmp(v->value, "caller")) 09289 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09290 else if(!strcasecmp(v->value, "disabled")) 09291 ast_set_flag(user, IAX_CODEC_NOPREFS); 09292 else if(!strcasecmp(v->value, "reqonly")) { 09293 ast_set_flag(user, IAX_CODEC_NOCAP); 09294 ast_set_flag(user, IAX_CODEC_NOPREFS); 09295 } 09296 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09297 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09298 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09299 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09300 } else if (!strcasecmp(v->name, "dbsecret")) { 09301 ast_string_field_set(user, dbsecret, v->value); 09302 } else if (!strcasecmp(v->name, "secret")) { 09303 if (!ast_strlen_zero(user->secret)) { 09304 char *old = ast_strdupa(user->secret); 09305 09306 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09307 } else 09308 ast_string_field_set(user, secret, v->value); 09309 } else if (!strcasecmp(v->name, "callerid")) { 09310 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09311 char name2[80]; 09312 char num2[80]; 09313 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09314 ast_string_field_set(user, cid_name, name2); 09315 ast_string_field_set(user, cid_num, num2); 09316 ast_set_flag(user, IAX_HASCALLERID); 09317 } else { 09318 ast_clear_flag(user, IAX_HASCALLERID); 09319 ast_string_field_set(user, cid_name, ""); 09320 ast_string_field_set(user, cid_num, ""); 09321 } 09322 } else if (!strcasecmp(v->name, "fullname")) { 09323 if (!ast_strlen_zero(v->value)) { 09324 ast_string_field_set(user, cid_name, v->value); 09325 ast_set_flag(user, IAX_HASCALLERID); 09326 } else { 09327 ast_string_field_set(user, cid_name, ""); 09328 if (ast_strlen_zero(user->cid_num)) 09329 ast_clear_flag(user, IAX_HASCALLERID); 09330 } 09331 } else if (!strcasecmp(v->name, "cid_number")) { 09332 if (!ast_strlen_zero(v->value)) { 09333 ast_string_field_set(user, cid_num, v->value); 09334 ast_set_flag(user, IAX_HASCALLERID); 09335 } else { 09336 ast_string_field_set(user, cid_num, ""); 09337 if (ast_strlen_zero(user->cid_name)) 09338 ast_clear_flag(user, IAX_HASCALLERID); 09339 } 09340 } else if (!strcasecmp(v->name, "accountcode")) { 09341 ast_string_field_set(user, accountcode, v->value); 09342 } else if (!strcasecmp(v->name, "mohinterpret")) { 09343 ast_string_field_set(user, mohinterpret, v->value); 09344 } else if (!strcasecmp(v->name, "mohsuggest")) { 09345 ast_string_field_set(user, mohsuggest, v->value); 09346 } else if (!strcasecmp(v->name, "language")) { 09347 ast_string_field_set(user, language, v->value); 09348 } else if (!strcasecmp(v->name, "amaflags")) { 09349 format = ast_cdr_amaflags2int(v->value); 09350 if (format < 0) { 09351 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09352 } else { 09353 user->amaflags = format; 09354 } 09355 } else if (!strcasecmp(v->name, "inkeys")) { 09356 ast_string_field_set(user, inkeys, v->value); 09357 } else if (!strcasecmp(v->name, "maxauthreq")) { 09358 user->maxauthreq = atoi(v->value); 09359 if (user->maxauthreq < 0) 09360 user->maxauthreq = 0; 09361 } else if (!strcasecmp(v->name, "adsi")) { 09362 user->adsi = ast_true(v->value); 09363 }/* else if (strcasecmp(v->name,"type")) */ 09364 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09365 v = v->next; 09366 if (!v) { 09367 v = alt; 09368 alt = NULL; 09369 } 09370 } 09371 if (!user->authmethods) { 09372 if (!ast_strlen_zero(user->secret)) { 09373 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09374 if (!ast_strlen_zero(user->inkeys)) 09375 user->authmethods |= IAX_AUTH_RSA; 09376 } else if (!ast_strlen_zero(user->inkeys)) { 09377 user->authmethods = IAX_AUTH_RSA; 09378 } else { 09379 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09380 } 09381 } 09382 ast_clear_flag(user, IAX_DELME); 09383 } 09384 cleanup: 09385 if (oldha) 09386 ast_free_ha(oldha); 09387 if (oldcon) 09388 free_context(oldcon); 09389 return user; 09390 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 9875 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::capability, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_MAX_CALLS, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
09876 { 09877 struct sockaddr_in sin; 09878 int x; 09879 int callno; 09880 struct iax_ie_data ied; 09881 struct create_addr_info cai; 09882 struct parsed_dial_string pds; 09883 char *tmpstr; 09884 09885 for (x=0; x<IAX_MAX_CALLS; x++) { 09886 /* Look for an *exact match* call. Once a call is negotiated, it can only 09887 look up entries for a single context */ 09888 if (!ast_mutex_trylock(&iaxsl[x])) { 09889 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 09890 return x; 09891 ast_mutex_unlock(&iaxsl[x]); 09892 } 09893 } 09894 09895 /* No match found, we need to create a new one */ 09896 09897 memset(&cai, 0, sizeof(cai)); 09898 memset(&ied, 0, sizeof(ied)); 09899 memset(&pds, 0, sizeof(pds)); 09900 09901 tmpstr = ast_strdupa(data); 09902 parse_dial_string(tmpstr, &pds); 09903 09904 /* Populate our address from the given */ 09905 if (create_addr(pds.peer, &sin, &cai)) 09906 return -1; 09907 09908 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 09909 pds.peer, pds.username, pds.password, pds.context); 09910 09911 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 09912 if (callno < 1) { 09913 ast_log(LOG_WARNING, "Unable to create call\n"); 09914 return -1; 09915 } 09916 09917 ast_mutex_lock(&iaxsl[callno]); 09918 ast_string_field_set(iaxs[callno], dproot, data); 09919 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 09920 09921 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 09922 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 09923 /* the string format is slightly different from a standard dial string, 09924 because the context appears in the 'exten' position 09925 */ 09926 if (pds.exten) 09927 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 09928 if (pds.username) 09929 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 09930 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 09931 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 09932 /* Keep password handy */ 09933 if (pds.password) 09934 ast_string_field_set(iaxs[callno], secret, pds.password); 09935 if (pds.key) 09936 ast_string_field_set(iaxs[callno], outkey, pds.key); 09937 /* Start the call going */ 09938 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 09939 09940 return callno; 09941 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3742 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03743 { 03744 /* Returns where in "receive time" we are. That is, how many ms 03745 since we received (or would have received) the frame with timestamp 0 */ 03746 int ms; 03747 #ifdef IAXTESTS 03748 int jit; 03749 #endif /* IAXTESTS */ 03750 /* Setup rxcore if necessary */ 03751 if (ast_tvzero(p->rxcore)) { 03752 p->rxcore = ast_tvnow(); 03753 if (option_debug && iaxdebug) 03754 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03755 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03756 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03757 #if 1 03758 if (option_debug && iaxdebug) 03759 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03760 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03761 #endif 03762 } 03763 03764 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03765 #ifdef IAXTESTS 03766 if (test_jit) { 03767 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03768 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03769 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03770 jit = -jit; 03771 ms += jit; 03772 } 03773 } 03774 if (test_late) { 03775 ms += test_late; 03776 test_late = 0; 03777 } 03778 #endif /* IAXTESTS */ 03779 return ms; 03780 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3624 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, and chan_iax2_pvt::peercallno.
Referenced by iax2_send(), and socket_process().
03625 { 03626 int ms; 03627 int voice = 0; 03628 int genuine = 0; 03629 int adjust; 03630 struct timeval *delivery = NULL; 03631 03632 03633 /* What sort of frame do we have?: voice is self-explanatory 03634 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03635 non-genuine frames are CONTROL frames [ringing etc], DTMF 03636 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03637 the others need a timestamp slaved to the voice frames so that they go in sequence 03638 */ 03639 if (f) { 03640 if (f->frametype == AST_FRAME_VOICE) { 03641 voice = 1; 03642 delivery = &f->delivery; 03643 } else if (f->frametype == AST_FRAME_IAX) { 03644 genuine = 1; 03645 } else if (f->frametype == AST_FRAME_CNG) { 03646 p->notsilenttx = 0; 03647 } 03648 } 03649 if (ast_tvzero(p->offset)) { 03650 gettimeofday(&p->offset, NULL); 03651 /* Round to nearest 20ms for nice looking traces */ 03652 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03653 } 03654 /* If the timestamp is specified, just send it as is */ 03655 if (ts) 03656 return ts; 03657 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03658 if (delivery && !ast_tvzero(*delivery)) { 03659 ms = ast_tvdiff_ms(*delivery, p->offset); 03660 if (option_debug > 2 && iaxdebug) 03661 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03662 } else { 03663 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03664 if (ms < 0) 03665 ms = 0; 03666 if (voice) { 03667 /* On a voice frame, use predicted values if appropriate */ 03668 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03669 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03670 /* AN EXPLANATION: 03671 When we send voice, we usually send "calculated" timestamps worked out 03672 on the basis of the number of samples sent. When we send other frames, 03673 we usually send timestamps worked out from the real clock. 03674 The problem is that they can tend to drift out of step because the 03675 source channel's clock and our clock may not be exactly at the same rate. 03676 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03677 for this call. Moving it adjusts timestamps for non-voice frames. 03678 We make the adjustment in the style of a moving average. Each time we 03679 adjust p->offset by 10% of the difference between our clock-derived 03680 timestamp and the predicted timestamp. That's why you see "10000" 03681 below even though IAX2 timestamps are in milliseconds. 03682 The use of a moving average avoids offset moving too radically. 03683 Generally, "adjust" roams back and forth around 0, with offset hardly 03684 changing at all. But if a consistent different starts to develop it 03685 will be eliminated over the course of 10 frames (200-300msecs) 03686 */ 03687 adjust = (ms - p->nextpred); 03688 if (adjust < 0) 03689 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03690 else if (adjust > 0) 03691 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03692 03693 if (!p->nextpred) { 03694 p->nextpred = ms; /*f->samples / 8;*/ 03695 if (p->nextpred <= p->lastsent) 03696 p->nextpred = p->lastsent + 3; 03697 } 03698 ms = p->nextpred; 03699 } else { 03700 /* in this case, just use the actual 03701 * time, since we're either way off 03702 * (shouldn't happen), or we're ending a 03703 * silent period -- and seed the next 03704 * predicted time. Also, round ms to the 03705 * next multiple of frame size (so our 03706 * silent periods are multiples of 03707 * frame size too) */ 03708 03709 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03710 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03711 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03712 03713 if (f->samples >= 8) /* check to make sure we dont core dump */ 03714 { 03715 int diff = ms % (f->samples / 8); 03716 if (diff) 03717 ms += f->samples/8 - diff; 03718 } 03719 03720 p->nextpred = ms; 03721 p->notsilenttx = 1; 03722 } 03723 } else { 03724 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03725 it's a genuine frame */ 03726 if (genuine) { 03727 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03728 if (ms <= p->lastsent) 03729 ms = p->lastsent + 3; 03730 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03731 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03732 ms = p->lastsent + 3; 03733 } 03734 } 03735 } 03736 p->lastsent = ms; 03737 if (voice) 03738 p->nextpred = p->nextpred + f->samples / 8; 03739 return ms; 03740 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3580 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().
03581 { 03582 unsigned long int mssincetx; /* unsigned to handle overflows */ 03583 long int ms, pred; 03584 03585 tpeer->trunkact = *tv; 03586 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03587 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03588 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03589 tpeer->txtrunktime = *tv; 03590 tpeer->lastsent = 999999; 03591 } 03592 /* Update last transmit time now */ 03593 tpeer->lasttxtime = *tv; 03594 03595 /* Calculate ms offset */ 03596 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03597 /* Predict from last value */ 03598 pred = tpeer->lastsent + sampms; 03599 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03600 ms = pred; 03601 03602 /* We never send the same timestamp twice, so fudge a little if we must */ 03603 if (ms == tpeer->lastsent) 03604 ms = tpeer->lastsent + 1; 03605 tpeer->lastsent = ms; 03606 return ms; 03607 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4839 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, key(), 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().
04840 { 04841 /* Start pessimistic */ 04842 int res = -1; 04843 int version = 2; 04844 struct iax2_user *user = NULL, *best = NULL; 04845 int bestscore = 0; 04846 int gotcapability = 0; 04847 struct ast_variable *v = NULL, *tmpvar = NULL; 04848 ao2_iterator i; 04849 04850 if (!iaxs[callno]) 04851 return res; 04852 if (ies->called_number) 04853 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04854 if (ies->calling_number) { 04855 ast_shrink_phone_number(ies->calling_number); 04856 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04857 } 04858 if (ies->calling_name) 04859 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04860 if (ies->calling_ani) 04861 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04862 if (ies->dnid) 04863 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04864 if (ies->rdnis) 04865 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04866 if (ies->called_context) 04867 ast_string_field_set(iaxs[callno], context, ies->called_context); 04868 if (ies->language) 04869 ast_string_field_set(iaxs[callno], language, ies->language); 04870 if (ies->username) 04871 ast_string_field_set(iaxs[callno], username, ies->username); 04872 if (ies->calling_ton > -1) 04873 iaxs[callno]->calling_ton = ies->calling_ton; 04874 if (ies->calling_tns > -1) 04875 iaxs[callno]->calling_tns = ies->calling_tns; 04876 if (ies->calling_pres > -1) 04877 iaxs[callno]->calling_pres = ies->calling_pres; 04878 if (ies->format) 04879 iaxs[callno]->peerformat = ies->format; 04880 if (ies->adsicpe) 04881 iaxs[callno]->peeradsicpe = ies->adsicpe; 04882 if (ies->capability) { 04883 gotcapability = 1; 04884 iaxs[callno]->peercapability = ies->capability; 04885 } 04886 if (ies->version) 04887 version = ies->version; 04888 04889 /* Use provided preferences until told otherwise for actual preferences */ 04890 if(ies->codec_prefs) { 04891 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04892 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04893 } 04894 04895 if (!gotcapability) 04896 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04897 if (version > IAX_PROTO_VERSION) { 04898 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04899 ast_inet_ntoa(sin->sin_addr), version); 04900 return res; 04901 } 04902 /* Search the userlist for a compatible entry, and fill in the rest */ 04903 i = ao2_iterator_init(users, 0); 04904 while ((user = ao2_iterator_next(&i))) { 04905 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04906 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04907 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04908 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04909 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04910 if (!ast_strlen_zero(iaxs[callno]->username)) { 04911 /* Exact match, stop right now. */ 04912 if (best) 04913 user_unref(best); 04914 best = user; 04915 break; 04916 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04917 /* No required authentication */ 04918 if (user->ha) { 04919 /* There was host authentication and we passed, bonus! */ 04920 if (bestscore < 4) { 04921 bestscore = 4; 04922 if (best) 04923 user_unref(best); 04924 best = user; 04925 continue; 04926 } 04927 } else { 04928 /* No host access, but no secret, either, not bad */ 04929 if (bestscore < 3) { 04930 bestscore = 3; 04931 if (best) 04932 user_unref(best); 04933 best = user; 04934 continue; 04935 } 04936 } 04937 } else { 04938 if (user->ha) { 04939 /* Authentication, but host access too, eh, it's something.. */ 04940 if (bestscore < 2) { 04941 bestscore = 2; 04942 if (best) 04943 user_unref(best); 04944 best = user; 04945 continue; 04946 } 04947 } else { 04948 /* Authentication and no host access... This is our baseline */ 04949 if (bestscore < 1) { 04950 bestscore = 1; 04951 if (best) 04952 user_unref(best); 04953 best = user; 04954 continue; 04955 } 04956 } 04957 } 04958 } 04959 user_unref(user); 04960 } 04961 user = best; 04962 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 04963 user = realtime_user(iaxs[callno]->username); 04964 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04965 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04966 user = user_unref(user); 04967 } 04968 } 04969 if (user) { 04970 /* We found our match (use the first) */ 04971 /* copy vars */ 04972 for (v = user->vars ; v ; v = v->next) { 04973 if((tmpvar = ast_variable_new(v->name, v->value))) { 04974 tmpvar->next = iaxs[callno]->vars; 04975 iaxs[callno]->vars = tmpvar; 04976 } 04977 } 04978 /* If a max AUTHREQ restriction is in place, activate it */ 04979 if (user->maxauthreq > 0) 04980 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 04981 iaxs[callno]->prefs = user->prefs; 04982 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04983 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04984 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04985 iaxs[callno]->encmethods = user->encmethods; 04986 /* Store the requested username if not specified */ 04987 if (ast_strlen_zero(iaxs[callno]->username)) 04988 ast_string_field_set(iaxs[callno], username, user->name); 04989 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04990 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04991 iaxs[callno]->capability = user->capability; 04992 /* And use the default context */ 04993 if (ast_strlen_zero(iaxs[callno]->context)) { 04994 if (user->contexts) 04995 ast_string_field_set(iaxs[callno], context, user->contexts->context); 04996 else 04997 ast_string_field_set(iaxs[callno], context, context); 04998 } 04999 /* And any input keys */ 05000 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05001 /* And the permitted authentication methods */ 05002 iaxs[callno]->authmethods = user->authmethods; 05003 iaxs[callno]->adsi = user->adsi; 05004 /* If they have callerid, override the given caller id. Always store the ANI */ 05005 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05006 if (ast_test_flag(user, IAX_HASCALLERID)) { 05007 iaxs[callno]->calling_tns = 0; 05008 iaxs[callno]->calling_ton = 0; 05009 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05010 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05011 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05012 } 05013 if (ast_strlen_zero(iaxs[callno]->ani)) 05014 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05015 } else { 05016 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05017 } 05018 if (!ast_strlen_zero(user->accountcode)) 05019 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05020 if (!ast_strlen_zero(user->mohinterpret)) 05021 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05022 if (!ast_strlen_zero(user->mohsuggest)) 05023 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05024 if (user->amaflags) 05025 iaxs[callno]->amaflags = user->amaflags; 05026 if (!ast_strlen_zero(user->language)) 05027 ast_string_field_set(iaxs[callno], language, user->language); 05028 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05029 /* Keep this check last */ 05030 if (!ast_strlen_zero(user->dbsecret)) { 05031 char *family, *key=NULL; 05032 char buf[80]; 05033 family = ast_strdupa(user->dbsecret); 05034 key = strchr(family, '/'); 05035 if (key) { 05036 *key = '\0'; 05037 key++; 05038 } 05039 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05040 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05041 else 05042 ast_string_field_set(iaxs[callno], secret, buf); 05043 } else 05044 ast_string_field_set(iaxs[callno], secret, user->secret); 05045 res = 0; 05046 user = user_unref(user); 05047 } 05048 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05049 return res; 05050 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6488 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06489 { 06490 unsigned int ourver; 06491 char rsi[80]; 06492 snprintf(rsi, sizeof(rsi), "si-%s", si); 06493 if (iax_provision_version(&ourver, rsi, 1)) 06494 return 0; 06495 if (option_debug) 06496 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06497 if (ourver != ver) 06498 iax2_provision(sin, sockfd, NULL, rsi, 1); 06499 return 0; 06500 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 8809 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by peer_set_srcaddr().
08810 { 08811 int sd; 08812 int res; 08813 08814 sd = socket(AF_INET, SOCK_DGRAM, 0); 08815 if (sd < 0) { 08816 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08817 return -1; 08818 } 08819 08820 res = bind(sd, sa, salen); 08821 if (res < 0) { 08822 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08823 close(sd); 08824 return 1; 08825 } 08826 08827 close(sd); 08828 return 0; 08829 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5531 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().
05532 { 05533 char exten[256] = ""; 05534 int status = CACHE_FLAG_UNKNOWN; 05535 int expiry = iaxdefaultdpcache; 05536 int x; 05537 int matchmore = 0; 05538 struct iax2_dpcache *dp, *prev; 05539 05540 if (ies->called_number) 05541 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05542 05543 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05544 status = CACHE_FLAG_EXISTS; 05545 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05546 status = CACHE_FLAG_CANEXIST; 05547 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05548 status = CACHE_FLAG_NONEXISTENT; 05549 05550 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05551 /* Don't really do anything with this */ 05552 } 05553 if (ies->refresh) 05554 expiry = ies->refresh; 05555 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05556 matchmore = CACHE_FLAG_MATCHMORE; 05557 ast_mutex_lock(&dpcache_lock); 05558 prev = NULL; 05559 dp = pvt->dpentries; 05560 while(dp) { 05561 if (!strcmp(dp->exten, exten)) { 05562 /* Let them go */ 05563 if (prev) 05564 prev->peer = dp->peer; 05565 else 05566 pvt->dpentries = dp->peer; 05567 dp->peer = NULL; 05568 dp->callno = 0; 05569 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05570 if (dp->flags & CACHE_FLAG_PENDING) { 05571 dp->flags &= ~CACHE_FLAG_PENDING; 05572 dp->flags |= status; 05573 dp->flags |= matchmore; 05574 } 05575 /* Wake up waiters */ 05576 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05577 if (dp->waiters[x] > -1) 05578 write(dp->waiters[x], "asdf", 4); 05579 } 05580 prev = dp; 05581 dp = dp->peer; 05582 } 05583 ast_mutex_unlock(&dpcache_lock); 05584 return 0; 05585 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2275 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02276 { 02277 int which = 0; 02278 struct iax2_peer *peer; 02279 char *res = NULL; 02280 int wordlen = strlen(word); 02281 ao2_iterator i; 02282 02283 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02284 if (pos != 3) 02285 return NULL; 02286 02287 i = ao2_iterator_init(peers, 0); 02288 while ((peer = ao2_iterator_next(&i))) { 02289 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02290 res = ast_strdup(peer->name); 02291 peer_unref(peer); 02292 break; 02293 } 02294 peer_unref(peer); 02295 } 02296 02297 return res; 02298 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5587 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, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
05588 { 05589 int peercallno = 0; 05590 struct chan_iax2_pvt *pvt = iaxs[callno]; 05591 struct iax_frame *cur; 05592 jb_frame frame; 05593 05594 if (ies->callno) 05595 peercallno = ies->callno; 05596 05597 if (peercallno < 1) { 05598 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05599 return -1; 05600 } 05601 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05602 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05603 /* Reset sequence numbers */ 05604 pvt->oseqno = 0; 05605 pvt->rseqno = 0; 05606 pvt->iseqno = 0; 05607 pvt->aseqno = 0; 05608 pvt->peercallno = peercallno; 05609 pvt->transferring = TRANSFER_NONE; 05610 pvt->svoiceformat = -1; 05611 pvt->voiceformat = 0; 05612 pvt->svideoformat = -1; 05613 pvt->videoformat = 0; 05614 pvt->transfercallno = -1; 05615 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05616 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05617 /* reset jitterbuffer */ 05618 while(jb_getall(pvt->jb,&frame) == JB_OK) 05619 iax2_frame_free(frame.data); 05620 jb_reset(pvt->jb); 05621 pvt->lag = 0; 05622 pvt->last = 0; 05623 pvt->lastsent = 0; 05624 pvt->nextpred = 0; 05625 pvt->pingtime = DEFAULT_RETRY_TIME; 05626 AST_LIST_LOCK(&iaxq.queue); 05627 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05628 /* We must cancel any packets that would have been transmitted 05629 because now we're talking to someone new. It's okay, they 05630 were transmitted to someone that didn't care anyway. */ 05631 if (callno == cur->callno) 05632 cur->retries = -1; 05633 } 05634 AST_LIST_UNLOCK(&iaxq.queue); 05635 return 0; 05636 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1023 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), and raw_hangup().
01024 { 01025 int x; 01026 int power=-1; 01027 /* If it's 128 or smaller, just return it */ 01028 if (subclass < IAX_FLAG_SC_LOG) 01029 return subclass; 01030 /* Otherwise find its power */ 01031 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01032 if (subclass & (1 << x)) { 01033 if (power > -1) { 01034 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01035 return 0; 01036 } else 01037 power = x; 01038 } 01039 } 01040 return power | IAX_FLAG_SC_LOG; 01041 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6502 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().
06503 { 06504 jb_info stats; 06505 jb_getinfo(pvt->jb, &stats); 06506 06507 memset(iep, 0, sizeof(*iep)); 06508 06509 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06510 if(stats.frames_in == 0) stats.frames_in = 1; 06511 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06512 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06513 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06514 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06515 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06516 }
static int create_addr | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2837 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_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
02838 { 02839 struct ast_hostent ahp; 02840 struct hostent *hp; 02841 struct iax2_peer *peer; 02842 int res = -1; 02843 02844 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02845 cai->sockfd = defaultsockfd; 02846 cai->maxtime = 0; 02847 sin->sin_family = AF_INET; 02848 02849 if (!(peer = find_peer(peername, 1))) { 02850 cai->found = 0; 02851 02852 hp = ast_gethostbyname(peername, &ahp); 02853 if (hp) { 02854 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02855 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02856 /* use global iax prefs for unknown peer/user */ 02857 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02858 return 0; 02859 } else { 02860 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02861 return -1; 02862 } 02863 } 02864 02865 cai->found = 1; 02866 02867 /* if the peer has no address (current or default), return failure */ 02868 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 02869 goto return_unref; 02870 02871 /* if the peer is being monitored and is currently unreachable, return failure */ 02872 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 02873 goto return_unref; 02874 02875 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02876 cai->maxtime = peer->maxms; 02877 cai->capability = peer->capability; 02878 cai->encmethods = peer->encmethods; 02879 cai->sockfd = peer->sockfd; 02880 cai->adsi = peer->adsi; 02881 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02882 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02883 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02884 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02885 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02886 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02887 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02888 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02889 if (ast_strlen_zero(peer->dbsecret)) { 02890 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02891 } else { 02892 char *family; 02893 char *key = NULL; 02894 02895 family = ast_strdupa(peer->dbsecret); 02896 key = strchr(family, '/'); 02897 if (key) 02898 *key++ = '\0'; 02899 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02900 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02901 goto return_unref; 02902 } 02903 } 02904 02905 if (peer->addr.sin_addr.s_addr) { 02906 sin->sin_addr = peer->addr.sin_addr; 02907 sin->sin_port = peer->addr.sin_port; 02908 } else { 02909 sin->sin_addr = peer->defaddr.sin_addr; 02910 sin->sin_port = peer->defaddr.sin_port; 02911 } 02912 02913 res = 0; 02914 02915 return_unref: 02916 peer_unref(peer); 02917 02918 return res; 02919 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 3926 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().
03927 { 03928 int padding; 03929 unsigned char *workspace; 03930 03931 workspace = alloca(*datalen); 03932 memset(f, 0, sizeof(*f)); 03933 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03934 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03935 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03936 return -1; 03937 /* Decrypt */ 03938 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03939 03940 padding = 16 + (workspace[15] & 0xf); 03941 if (option_debug && iaxdebug) 03942 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03943 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03944 return -1; 03945 03946 *datalen -= padding; 03947 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03948 f->frametype = fh->type; 03949 if (f->frametype == AST_FRAME_VIDEO) { 03950 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03951 } else { 03952 f->subclass = uncompress_subclass(fh->csub); 03953 } 03954 } else { 03955 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03956 if (option_debug && iaxdebug) 03957 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03958 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03959 return -1; 03960 /* Decrypt */ 03961 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03962 padding = 16 + (workspace[15] & 0x0f); 03963 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03964 return -1; 03965 *datalen -= padding; 03966 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03967 } 03968 return 0; 03969 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4012 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().
04013 { 04014 int res=-1; 04015 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04016 /* Search for possible keys, given secrets */ 04017 struct MD5Context md5; 04018 unsigned char digest[16]; 04019 char *tmppw, *stringp; 04020 04021 tmppw = ast_strdupa(iaxs[callno]->secret); 04022 stringp = tmppw; 04023 while ((tmppw = strsep(&stringp, ";"))) { 04024 MD5Init(&md5); 04025 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04026 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04027 MD5Final(digest, &md5); 04028 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04029 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04030 if (!res) { 04031 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04032 break; 04033 } 04034 } 04035 } else 04036 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04037 return res; 04038 }
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 6564 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().
06565 { 06566 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06567 struct ast_iax2_full_hdr *fh, *cur_fh; 06568 06569 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06570 return; 06571 06572 pkt_buf->len = from_here->buf_len; 06573 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06574 06575 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06576 ast_mutex_lock(&to_here->lock); 06577 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06578 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06579 if (fh->oseqno < cur_fh->oseqno) { 06580 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06581 break; 06582 } 06583 } 06584 AST_LIST_TRAVERSE_SAFE_END 06585 06586 if (!cur_pkt_buf) 06587 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06588 06589 ast_mutex_unlock(&to_here->lock); 06590 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9410 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.
09411 { 09412 struct iax2_registry *reg; 09413 09414 ao2_callback(users, 0, user_delme_cb, NULL); 09415 09416 AST_LIST_LOCK(®istrations); 09417 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09418 if (reg->expire > -1) 09419 ast_sched_del(sched, reg->expire); 09420 if (reg->callno) { 09421 ast_mutex_lock(&iaxsl[reg->callno]); 09422 if (iaxs[reg->callno]) { 09423 iaxs[reg->callno]->reg = NULL; 09424 iax2_destroy(reg->callno); 09425 } 09426 ast_mutex_unlock(&iaxsl[reg->callno]); 09427 } 09428 if (reg->dnsmgr) 09429 ast_dnsmgr_release(reg->dnsmgr); 09430 free(reg); 09431 } 09432 AST_LIST_UNLOCK(®istrations); 09433 09434 ao2_callback(peers, 0, peer_delme_cb, NULL); 09435 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1513 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01514 { 01515 /* Close firmware */ 01516 if (cur->fwh) { 01517 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01518 } 01519 close(cur->fd); 01520 free(cur); 01521 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6336 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().
06337 { 06338 unsigned short dpstatus = 0; 06339 struct iax_ie_data ied1; 06340 int mm; 06341 06342 memset(&ied1, 0, sizeof(ied1)); 06343 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06344 /* Must be started */ 06345 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06346 dpstatus = IAX_DPSTATUS_EXISTS; 06347 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06348 dpstatus = IAX_DPSTATUS_CANEXIST; 06349 } else { 06350 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06351 } 06352 if (ast_ignore_pattern(context, callednum)) 06353 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06354 if (mm) 06355 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06356 if (!skiplock) 06357 ast_mutex_lock(&iaxsl[callno]); 06358 if (iaxs[callno]) { 06359 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06360 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06361 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06362 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06363 } 06364 if (!skiplock) 06365 ast_mutex_unlock(&iaxsl[callno]); 06366 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6368 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().
06369 { 06370 /* Look up for dpreq */ 06371 struct dpreq_data *dpr = data; 06372 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06373 if (dpr->callerid) 06374 free(dpr->callerid); 06375 free(dpr); 06376 return NULL; 06377 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 3971 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().
03972 { 03973 int padding; 03974 unsigned char *workspace; 03975 workspace = alloca(*datalen + 32); 03976 if (!workspace) 03977 return -1; 03978 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03979 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03980 if (option_debug && iaxdebug) 03981 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03982 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03983 padding = 16 + (padding & 0xf); 03984 memcpy(workspace, poo, padding); 03985 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03986 workspace[15] &= 0xf0; 03987 workspace[15] |= (padding & 0xf); 03988 if (option_debug && iaxdebug) 03989 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]); 03990 *datalen += padding; 03991 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03992 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03993 memcpy(poo, workspace + *datalen - 32, 32); 03994 } else { 03995 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03996 if (option_debug && iaxdebug) 03997 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03998 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03999 padding = 16 + (padding & 0xf); 04000 memcpy(workspace, poo, padding); 04001 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04002 workspace[15] &= 0xf0; 04003 workspace[15] |= (padding & 0x0f); 04004 *datalen += padding; 04005 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04006 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04007 memcpy(poo, workspace + *datalen - 32, 32); 04008 } 04009 return 0; 04010 }
static int expire_registry | ( | void * | data | ) | [static] |
Definition at line 5804 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
05805 { 05806 #ifdef SCHED_MULTITHREADED 05807 if (schedule_action(__expire_registry, data)) 05808 #endif 05809 __expire_registry(data); 05810 return 0; 05811 }
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 9943 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, timeout, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
09944 { 09945 struct iax2_dpcache *dp, *prev = NULL, *next; 09946 struct timeval tv; 09947 int x; 09948 int com[2]; 09949 int timeout; 09950 int old=0; 09951 int outfd; 09952 int abort; 09953 int callno; 09954 struct ast_channel *c; 09955 struct ast_frame *f; 09956 gettimeofday(&tv, NULL); 09957 dp = dpcache; 09958 while(dp) { 09959 next = dp->next; 09960 /* Expire old caches */ 09961 if (ast_tvcmp(tv, dp->expiry) > 0) { 09962 /* It's expired, let it disappear */ 09963 if (prev) 09964 prev->next = dp->next; 09965 else 09966 dpcache = dp->next; 09967 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 09968 /* Free memory and go again */ 09969 free(dp); 09970 } else { 09971 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); 09972 } 09973 dp = next; 09974 continue; 09975 } 09976 /* We found an entry that matches us! */ 09977 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 09978 break; 09979 prev = dp; 09980 dp = next; 09981 } 09982 if (!dp) { 09983 /* No matching entry. Create a new one. */ 09984 /* First, can we make a callno? */ 09985 callno = cache_get_callno_locked(data); 09986 if (callno < 0) { 09987 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09988 return NULL; 09989 } 09990 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 09991 ast_mutex_unlock(&iaxsl[callno]); 09992 return NULL; 09993 } 09994 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09995 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09996 gettimeofday(&dp->expiry, NULL); 09997 dp->orig = dp->expiry; 09998 /* Expires in 30 mins by default */ 09999 dp->expiry.tv_sec += iaxdefaultdpcache; 10000 dp->next = dpcache; 10001 dp->flags = CACHE_FLAG_PENDING; 10002 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10003 dp->waiters[x] = -1; 10004 dpcache = dp; 10005 dp->peer = iaxs[callno]->dpentries; 10006 iaxs[callno]->dpentries = dp; 10007 /* Send the request if we're already up */ 10008 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10009 iax2_dprequest(dp, callno); 10010 ast_mutex_unlock(&iaxsl[callno]); 10011 } 10012 /* By here we must have a dp */ 10013 if (dp->flags & CACHE_FLAG_PENDING) { 10014 /* Okay, here it starts to get nasty. We need a pipe now to wait 10015 for a reply to come back so long as it's pending */ 10016 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10017 /* Find an empty slot */ 10018 if (dp->waiters[x] < 0) 10019 break; 10020 } 10021 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10022 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10023 return NULL; 10024 } 10025 if (pipe(com)) { 10026 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10027 return NULL; 10028 } 10029 dp->waiters[x] = com[1]; 10030 /* Okay, now we wait */ 10031 timeout = iaxdefaulttimeout * 1000; 10032 /* Temporarily unlock */ 10033 ast_mutex_unlock(&dpcache_lock); 10034 /* Defer any dtmf */ 10035 if (chan) 10036 old = ast_channel_defer_dtmf(chan); 10037 abort = 0; 10038 while(timeout) { 10039 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10040 if (outfd > -1) { 10041 break; 10042 } 10043 if (c) { 10044 f = ast_read(c); 10045 if (f) 10046 ast_frfree(f); 10047 else { 10048 /* Got hung up on, abort! */ 10049 break; 10050 abort = 1; 10051 } 10052 } 10053 } 10054 if (!timeout) { 10055 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10056 } 10057 ast_mutex_lock(&dpcache_lock); 10058 dp->waiters[x] = -1; 10059 close(com[1]); 10060 close(com[0]); 10061 if (abort) { 10062 /* Don't interpret anything, just abort. Not sure what th epoint 10063 of undeferring dtmf on a hung up channel is but hey whatever */ 10064 if (!old && chan) 10065 ast_channel_undefer_dtmf(chan); 10066 return NULL; 10067 } 10068 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10069 /* Now to do non-independent analysis the results of our wait */ 10070 if (dp->flags & CACHE_FLAG_PENDING) { 10071 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10072 pending. Don't let it take as long to timeout. */ 10073 dp->flags &= ~CACHE_FLAG_PENDING; 10074 dp->flags |= CACHE_FLAG_TIMEOUT; 10075 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10076 systems without leaving it unavailable once the server comes back online */ 10077 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10078 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10079 if (dp->waiters[x] > -1) 10080 write(dp->waiters[x], "asdf", 4); 10081 } 10082 } 10083 /* Our caller will obtain the rest */ 10084 if (!old && chan) 10085 ast_channel_undefer_dtmf(chan); 10086 } 10087 return dp; 10088 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd | |||
) | [static] |
Definition at line 1327 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_process().
01328 { 01329 int res = 0; 01330 int x; 01331 struct timeval now; 01332 char host[80]; 01333 01334 if (new <= NEW_ALLOW) { 01335 /* Look for an existing connection first */ 01336 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01337 ast_mutex_lock(&iaxsl[x]); 01338 if (iaxs[x]) { 01339 /* Look for an exact match */ 01340 if (match(sin, callno, dcallno, iaxs[x])) { 01341 res = x; 01342 } 01343 } 01344 ast_mutex_unlock(&iaxsl[x]); 01345 } 01346 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01347 ast_mutex_lock(&iaxsl[x]); 01348 if (iaxs[x]) { 01349 /* Look for an exact match */ 01350 if (match(sin, callno, dcallno, iaxs[x])) { 01351 res = x; 01352 } 01353 } 01354 ast_mutex_unlock(&iaxsl[x]); 01355 } 01356 } 01357 if ((res < 1) && (new >= NEW_ALLOW)) { 01358 /* It may seem odd that we look through the peer list for a name for 01359 * this *incoming* call. Well, it is weird. However, users don't 01360 * have an IP address/port number that we can match against. So, 01361 * this is just checking for a peer that has that IP/port and 01362 * assuming that we have a user of the same name. This isn't always 01363 * correct, but it will be changed if needed after authentication. */ 01364 if (!iax2_getpeername(*sin, host, sizeof(host))) 01365 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01366 gettimeofday(&now, NULL); 01367 for (x=1;x<TRUNK_CALL_START;x++) { 01368 /* Find first unused call number that hasn't been used in a while */ 01369 ast_mutex_lock(&iaxsl[x]); 01370 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01371 ast_mutex_unlock(&iaxsl[x]); 01372 } 01373 /* We've still got lock held if we found a spot */ 01374 if (x >= TRUNK_CALL_START) { 01375 ast_log(LOG_WARNING, "No more space\n"); 01376 return 0; 01377 } 01378 iaxs[x] = new_iax(sin, host); 01379 update_max_nontrunk(); 01380 if (iaxs[x]) { 01381 if (option_debug && iaxdebug) 01382 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01383 iaxs[x]->sockfd = sockfd; 01384 iaxs[x]->addr.sin_port = sin->sin_port; 01385 iaxs[x]->addr.sin_family = sin->sin_family; 01386 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01387 iaxs[x]->peercallno = callno; 01388 iaxs[x]->callno = x; 01389 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01390 iaxs[x]->expiry = min_reg_expire; 01391 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01392 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01393 iaxs[x]->amaflags = amaflags; 01394 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01395 01396 ast_string_field_set(iaxs[x], accountcode, accountcode); 01397 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01398 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01399 } else { 01400 ast_log(LOG_WARNING, "Out of resources\n"); 01401 ast_mutex_unlock(&iaxsl[x]); 01402 return 0; 01403 } 01404 ast_mutex_unlock(&iaxsl[x]); 01405 res = x; 01406 } 01407 return res; 01408 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 889 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().
00890 { 00891 pthread_attr_t attr; 00892 struct iax2_thread *thread = NULL; 00893 00894 /* Pop the head of the list off */ 00895 AST_LIST_LOCK(&idle_list); 00896 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00897 AST_LIST_UNLOCK(&idle_list); 00898 00899 /* If no idle thread is available from the regular list, try dynamic */ 00900 if (thread == NULL) { 00901 AST_LIST_LOCK(&dynamic_list); 00902 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00903 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00904 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00905 /* We need to MAKE a thread! */ 00906 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00907 thread->threadnum = iaxdynamicthreadcount; 00908 thread->type = IAX_TYPE_DYNAMIC; 00909 ast_mutex_init(&thread->lock); 00910 ast_cond_init(&thread->cond, NULL); 00911 pthread_attr_init(&attr); 00912 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00913 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00914 free(thread); 00915 thread = NULL; 00916 } else { 00917 /* All went well and the thread is up, so increment our count */ 00918 iaxdynamicthreadcount++; 00919 00920 /* Wait for the thread to be ready before returning it to the caller */ 00921 while (!thread->ready_for_signal) 00922 usleep(1); 00923 } 00924 } 00925 } 00926 AST_LIST_UNLOCK(&dynamic_list); 00927 } 00928 00929 /* this thread is not processing a full frame (since it is idle), 00930 so ensure that the field for the full frame call number is empty */ 00931 if (thread) 00932 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00933 00934 return thread; 00935 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1101 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01102 { 01103 struct iax2_peer *peer = NULL; 01104 struct iax2_peer tmp_peer = { 01105 .name = name, 01106 }; 01107 01108 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01109 01110 /* Now go for realtime if applicable */ 01111 if(!peer && realtime) 01112 peer = realtime_peer(name, NULL); 01113 01114 return peer; 01115 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 3782 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().
03783 { 03784 struct iax2_trunk_peer *tpeer; 03785 03786 /* Finds and locks trunk peer */ 03787 ast_mutex_lock(&tpeerlock); 03788 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03789 /* We don't lock here because tpeer->addr *never* changes */ 03790 if (!inaddrcmp(&tpeer->addr, sin)) { 03791 ast_mutex_lock(&tpeer->lock); 03792 break; 03793 } 03794 } 03795 if (!tpeer) { 03796 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03797 ast_mutex_init(&tpeer->lock); 03798 tpeer->lastsent = 9999; 03799 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03800 tpeer->trunkact = ast_tvnow(); 03801 ast_mutex_lock(&tpeer->lock); 03802 tpeer->next = tpeers; 03803 tpeer->sockfd = fd; 03804 tpeers = tpeer; 03805 #ifdef SO_NO_CHECK 03806 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03807 #endif 03808 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03809 } 03810 } 03811 ast_mutex_unlock(&tpeerlock); 03812 return tpeer; 03813 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3609 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03610 { 03611 long ms; /* NOT unsigned */ 03612 if (ast_tvzero(iaxs[callno]->rxcore)) { 03613 /* Initialize rxcore time if appropriate */ 03614 gettimeofday(&iaxs[callno]->rxcore, NULL); 03615 /* Round to nearest 20ms so traces look pretty */ 03616 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03617 } 03618 /* Calculate difference between trunk and channel */ 03619 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03620 /* Return as the sum of trunk time and the difference between trunk and real time */ 03621 return ms + ts; 03622 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8564 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08565 { 08566 struct iax2_context *conl; 08567 while(con) { 08568 conl = con; 08569 con = con->next; 08570 free(conl); 08571 } 08572 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10212 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.
10213 { 10214 struct iax2_peer *peer; 10215 char *peername, *colname; 10216 10217 peername = ast_strdupa(data); 10218 10219 /* if our channel, return the IP address of the endpoint of current channel */ 10220 if (!strcmp(peername,"CURRENTCHANNEL")) { 10221 unsigned short callno; 10222 if (chan->tech != &iax2_tech) 10223 return -1; 10224 callno = PTR_TO_CALLNO(chan->tech_pvt); 10225 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10226 return 0; 10227 } 10228 10229 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10230 *colname++ = '\0'; 10231 else if ((colname = strchr(peername, '|'))) 10232 *colname++ = '\0'; 10233 else 10234 colname = "ip"; 10235 10236 if (!(peer = find_peer(peername, 1))) 10237 return -1; 10238 10239 if (!strcasecmp(colname, "ip")) { 10240 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10241 } else if (!strcasecmp(colname, "status")) { 10242 peer_status(peer, buf, len); 10243 } else if (!strcasecmp(colname, "mailbox")) { 10244 ast_copy_string(buf, peer->mailbox, len); 10245 } else if (!strcasecmp(colname, "context")) { 10246 ast_copy_string(buf, peer->context, len); 10247 } else if (!strcasecmp(colname, "expire")) { 10248 snprintf(buf, len, "%d", peer->expire); 10249 } else if (!strcasecmp(colname, "dynamic")) { 10250 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10251 } else if (!strcasecmp(colname, "callerid_name")) { 10252 ast_copy_string(buf, peer->cid_name, len); 10253 } else if (!strcasecmp(colname, "callerid_num")) { 10254 ast_copy_string(buf, peer->cid_num, len); 10255 } else if (!strcasecmp(colname, "codecs")) { 10256 ast_getformatname_multiple(buf, len -1, peer->capability); 10257 } else if (!strncasecmp(colname, "codec[", 6)) { 10258 char *codecnum, *ptr; 10259 int index = 0, codec = 0; 10260 10261 codecnum = strchr(colname, '['); 10262 *codecnum = '\0'; 10263 codecnum++; 10264 if ((ptr = strchr(codecnum, ']'))) { 10265 *ptr = '\0'; 10266 } 10267 index = atoi(codecnum); 10268 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10269 ast_copy_string(buf, ast_getformatname(codec), len); 10270 } 10271 } 10272 10273 peer_unref(peer); 10274 10275 return 0; 10276 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8793 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08794 { 08795 int methods = 0; 08796 if (strstr(value, "rsa")) 08797 methods |= IAX_AUTH_RSA; 08798 if (strstr(value, "md5")) 08799 methods |= IAX_AUTH_MD5; 08800 if (strstr(value, "plaintext")) 08801 methods |= IAX_AUTH_PLAINTEXT; 08802 return methods; 08803 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 988 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
00989 { 00990 int e; 00991 if (!strcasecmp(s, "aes128")) 00992 e = IAX_ENCRYPT_AES128; 00993 else if (ast_true(s)) 00994 e = IAX_ENCRYPT_AES128; 00995 else 00996 e = 0; 00997 return e; 00998 }
static int get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2515 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02516 { 02517 #ifdef SCHED_MULTITHREADED 02518 if (schedule_action(__get_from_jb, data)) 02519 #endif 02520 __get_from_jb(data); 02521 return 0; 02522 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6534 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), socket_process(), and thread.
06535 { 06536 struct iax2_pkt_buf *pkt_buf; 06537 06538 ast_mutex_lock(&thread->lock); 06539 06540 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06541 ast_mutex_unlock(&thread->lock); 06542 06543 thread->buf = pkt_buf->buf; 06544 thread->buf_len = pkt_buf->len; 06545 thread->buf_size = pkt_buf->len + 1; 06546 06547 socket_process(thread); 06548 06549 thread->buf = NULL; 06550 ast_free(pkt_buf); 06551 06552 ast_mutex_lock(&thread->lock); 06553 } 06554 06555 ast_mutex_unlock(&thread->lock); 06556 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1798 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
01799 { 01800 /* XXX Ideally we should figure out why an error occured and then abort those 01801 rather than continuing to try. Unfortunately, the published interface does 01802 not seem to work XXX */ 01803 #if 0 01804 struct sockaddr_in *sin; 01805 int res; 01806 struct msghdr m; 01807 struct sock_extended_err e; 01808 m.msg_name = NULL; 01809 m.msg_namelen = 0; 01810 m.msg_iov = NULL; 01811 m.msg_control = &e; 01812 m.msg_controllen = sizeof(e); 01813 m.msg_flags = 0; 01814 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01815 if (res < 0) 01816 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01817 else { 01818 if (m.msg_controllen) { 01819 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01820 if (sin) 01821 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01822 else 01823 ast_log(LOG_WARNING, "No address detected??\n"); 01824 } else { 01825 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01826 } 01827 } 01828 #endif 01829 return 0; 01830 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5639 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), 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().
05640 { 05641 struct iax2_registry *reg; 05642 /* Start pessimistic */ 05643 char peer[256] = ""; 05644 char msgstatus[60]; 05645 int refresh = 60; 05646 char ourip[256] = "<Unspecified>"; 05647 struct sockaddr_in oldus; 05648 struct sockaddr_in us; 05649 int oldmsgs; 05650 05651 memset(&us, 0, sizeof(us)); 05652 if (ies->apparent_addr) 05653 bcopy(ies->apparent_addr, &us, sizeof(us)); 05654 if (ies->username) 05655 ast_copy_string(peer, ies->username, sizeof(peer)); 05656 if (ies->refresh) 05657 refresh = ies->refresh; 05658 if (ies->calling_number) { 05659 /* We don't do anything with it really, but maybe we should */ 05660 } 05661 reg = iaxs[callno]->reg; 05662 if (!reg) { 05663 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05664 return -1; 05665 } 05666 memcpy(&oldus, ®->us, sizeof(oldus)); 05667 oldmsgs = reg->messages; 05668 if (inaddrcmp(®->addr, sin)) { 05669 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05670 return -1; 05671 } 05672 memcpy(®->us, &us, sizeof(reg->us)); 05673 if (ies->msgcount >= 0) 05674 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05675 /* always refresh the registration at the interval requested by the server 05676 we are registering to 05677 */ 05678 reg->refresh = refresh; 05679 if (reg->expire > -1) 05680 ast_sched_del(sched, reg->expire); 05681 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05682 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05683 if (option_verbose > 2) { 05684 if (reg->messages > 255) 05685 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05686 else if (reg->messages > 1) 05687 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05688 else if (reg->messages > 0) 05689 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05690 else 05691 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05692 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05693 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05694 } 05695 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05696 } 05697 reg->regstate = REG_STATE_REGISTERED; 05698 return 0; 05699 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3430 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.
03431 { 03432 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03433 if (option_debug) 03434 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03435 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03436 }
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 3280 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.
03281 { 03282 struct ast_channel *cs[3]; 03283 struct ast_channel *who, *other; 03284 int to = -1; 03285 int res = -1; 03286 int transferstarted=0; 03287 struct ast_frame *f; 03288 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03289 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03290 struct timeval waittimer = {0, 0}, tv; 03291 03292 lock_both(callno0, callno1); 03293 if (!iaxs[callno0] || !iaxs[callno1]) { 03294 unlock_both(callno0, callno1); 03295 return AST_BRIDGE_FAILED; 03296 } 03297 /* Put them in native bridge mode */ 03298 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03299 iaxs[callno0]->bridgecallno = callno1; 03300 iaxs[callno1]->bridgecallno = callno0; 03301 } 03302 unlock_both(callno0, callno1); 03303 03304 /* If not, try to bridge until we can execute a transfer, if we can */ 03305 cs[0] = c0; 03306 cs[1] = c1; 03307 for (/* ever */;;) { 03308 /* Check in case we got masqueraded into */ 03309 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03310 if (option_verbose > 2) 03311 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03312 /* Remove from native mode */ 03313 if (c0->tech == &iax2_tech) { 03314 ast_mutex_lock(&iaxsl[callno0]); 03315 iaxs[callno0]->bridgecallno = 0; 03316 ast_mutex_unlock(&iaxsl[callno0]); 03317 } 03318 if (c1->tech == &iax2_tech) { 03319 ast_mutex_lock(&iaxsl[callno1]); 03320 iaxs[callno1]->bridgecallno = 0; 03321 ast_mutex_unlock(&iaxsl[callno1]); 03322 } 03323 return AST_BRIDGE_FAILED_NOWARN; 03324 } 03325 if (c0->nativeformats != c1->nativeformats) { 03326 if (option_verbose > 2) { 03327 char buf0[255]; 03328 char buf1[255]; 03329 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03330 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03331 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03332 } 03333 /* Remove from native mode */ 03334 lock_both(callno0, callno1); 03335 if (iaxs[callno0]) 03336 iaxs[callno0]->bridgecallno = 0; 03337 if (iaxs[callno1]) 03338 iaxs[callno1]->bridgecallno = 0; 03339 unlock_both(callno0, callno1); 03340 return AST_BRIDGE_FAILED_NOWARN; 03341 } 03342 /* check if transfered and if we really want native bridging */ 03343 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03344 /* Try the transfer */ 03345 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03346 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03347 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03348 transferstarted = 1; 03349 } 03350 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03351 /* Call has been transferred. We're no longer involved */ 03352 gettimeofday(&tv, NULL); 03353 if (ast_tvzero(waittimer)) { 03354 waittimer = tv; 03355 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03356 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03357 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03358 *fo = NULL; 03359 *rc = c0; 03360 res = AST_BRIDGE_COMPLETE; 03361 break; 03362 } 03363 } 03364 to = 1000; 03365 who = ast_waitfor_n(cs, 2, &to); 03366 if (timeoutms > -1) { 03367 timeoutms -= (1000 - to); 03368 if (timeoutms < 0) 03369 timeoutms = 0; 03370 } 03371 if (!who) { 03372 if (!timeoutms) { 03373 res = AST_BRIDGE_RETRY; 03374 break; 03375 } 03376 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03377 res = AST_BRIDGE_FAILED; 03378 break; 03379 } 03380 continue; 03381 } 03382 f = ast_read(who); 03383 if (!f) { 03384 *fo = NULL; 03385 *rc = who; 03386 res = AST_BRIDGE_COMPLETE; 03387 break; 03388 } 03389 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03390 *fo = f; 03391 *rc = who; 03392 res = AST_BRIDGE_COMPLETE; 03393 break; 03394 } 03395 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03396 if ((f->frametype == AST_FRAME_VOICE) || 03397 (f->frametype == AST_FRAME_TEXT) || 03398 (f->frametype == AST_FRAME_VIDEO) || 03399 (f->frametype == AST_FRAME_IMAGE) || 03400 (f->frametype == AST_FRAME_DTMF)) { 03401 /* monitored dtmf take out of the bridge. 03402 * check if we monitor the specific source. 03403 */ 03404 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03405 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03406 *rc = who; 03407 *fo = f; 03408 res = AST_BRIDGE_COMPLETE; 03409 /* Remove from native mode */ 03410 break; 03411 } 03412 /* everything else goes to the other side */ 03413 ast_write(other, f); 03414 } 03415 ast_frfree(f); 03416 /* Swap who gets priority */ 03417 cs[2] = cs[0]; 03418 cs[0] = cs[1]; 03419 cs[1] = cs[2]; 03420 } 03421 lock_both(callno0, callno1); 03422 if(iaxs[callno0]) 03423 iaxs[callno0]->bridgecallno = 0; 03424 if(iaxs[callno1]) 03425 iaxs[callno1]->bridgecallno = 0; 03426 unlock_both(callno0, callno1); 03427 return res; 03428 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3031 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_sched_add(), 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(), 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.
03032 { 03033 struct sockaddr_in sin; 03034 char *l=NULL, *n=NULL, *tmpstr; 03035 struct iax_ie_data ied; 03036 char *defaultrdest = "s"; 03037 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03038 struct parsed_dial_string pds; 03039 struct create_addr_info cai; 03040 03041 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03042 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03043 return -1; 03044 } 03045 03046 memset(&cai, 0, sizeof(cai)); 03047 cai.encmethods = iax2_encryption; 03048 03049 memset(&pds, 0, sizeof(pds)); 03050 tmpstr = ast_strdupa(dest); 03051 parse_dial_string(tmpstr, &pds); 03052 03053 if (!pds.exten) 03054 pds.exten = defaultrdest; 03055 03056 if (create_addr(pds.peer, &sin, &cai)) { 03057 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03058 return -1; 03059 } 03060 03061 if (!pds.username && !ast_strlen_zero(cai.username)) 03062 pds.username = cai.username; 03063 if (!pds.password && !ast_strlen_zero(cai.secret)) 03064 pds.password = cai.secret; 03065 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03066 pds.key = cai.outkey; 03067 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03068 pds.context = cai.peercontext; 03069 03070 /* Keep track of the context for outgoing calls too */ 03071 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03072 03073 if (pds.port) 03074 sin.sin_port = htons(atoi(pds.port)); 03075 03076 l = c->cid.cid_num; 03077 n = c->cid.cid_name; 03078 03079 /* Now build request */ 03080 memset(&ied, 0, sizeof(ied)); 03081 03082 /* On new call, first IE MUST be IAX version of caller */ 03083 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03084 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03085 if (pds.options && strchr(pds.options, 'a')) { 03086 /* Request auto answer */ 03087 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03088 } 03089 03090 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03091 03092 if (l) { 03093 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03094 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03095 } else { 03096 if (n) 03097 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03098 else 03099 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03100 } 03101 03102 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03103 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03104 03105 if (n) 03106 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03107 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03108 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03109 03110 if (!ast_strlen_zero(c->language)) 03111 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03112 if (!ast_strlen_zero(c->cid.cid_dnid)) 03113 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03114 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03115 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03116 03117 if (pds.context) 03118 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03119 03120 if (pds.username) 03121 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03122 03123 if (cai.encmethods) 03124 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03125 03126 ast_mutex_lock(&iaxsl[callno]); 03127 03128 if (!ast_strlen_zero(c->context)) 03129 ast_string_field_set(iaxs[callno], context, c->context); 03130 03131 if (pds.username) 03132 ast_string_field_set(iaxs[callno], username, pds.username); 03133 03134 iaxs[callno]->encmethods = cai.encmethods; 03135 03136 iaxs[callno]->adsi = cai.adsi; 03137 03138 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03139 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03140 03141 if (pds.key) 03142 ast_string_field_set(iaxs[callno], outkey, pds.key); 03143 if (pds.password) 03144 ast_string_field_set(iaxs[callno], secret, pds.password); 03145 03146 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03147 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03148 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03149 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03150 03151 if (iaxs[callno]->maxtime) { 03152 /* Initialize pingtime and auto-congest time */ 03153 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03154 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03155 } else if (autokill) { 03156 iaxs[callno]->pingtime = autokill / 2; 03157 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03158 } 03159 03160 /* send the command using the appropriate socket for this peer */ 03161 iaxs[callno]->sockfd = cai.sockfd; 03162 03163 /* Transmit the string in a "NEW" request */ 03164 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03165 03166 ast_mutex_unlock(&iaxsl[callno]); 03167 ast_setstate(c, AST_STATE_RINGING); 03168 03169 return 0; 03170 }
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 10114 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.
10115 { 10116 int res = 0; 10117 struct iax2_dpcache *dp; 10118 #if 0 10119 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10120 #endif 10121 if ((priority != 1) && (priority != 2)) 10122 return 0; 10123 ast_mutex_lock(&dpcache_lock); 10124 dp = find_cache(chan, data, context, exten, priority); 10125 if (dp) { 10126 if (dp->flags & CACHE_FLAG_CANEXIST) 10127 res= 1; 10128 } 10129 ast_mutex_unlock(&dpcache_lock); 10130 if (!dp) { 10131 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10132 } 10133 return res; 10134 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 2943 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
02944 { 02945 time_t t; 02946 struct tm tm; 02947 unsigned int tmp; 02948 time(&t); 02949 if (!ast_strlen_zero(tz)) 02950 ast_localtime(&t, &tm, tz); 02951 else 02952 ast_localtime(&t, &tm, NULL); 02953 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02954 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02955 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02956 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02957 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02958 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02959 return tmp; 02960 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1949 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_string_field_free_pools, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, lastused, ast_channel::lock, LOG_NOTICE, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, update_max_trunk(), and chan_iax2_pvt::vars.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01950 { 01951 struct chan_iax2_pvt *pvt; 01952 struct iax_frame *cur; 01953 struct ast_channel *owner; 01954 01955 retry: 01956 pvt = iaxs[callno]; 01957 gettimeofday(&lastused[callno], NULL); 01958 01959 owner = pvt ? pvt->owner : NULL; 01960 01961 if (owner) { 01962 if (ast_mutex_trylock(&owner->lock)) { 01963 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01964 ast_mutex_unlock(&iaxsl[callno]); 01965 usleep(1); 01966 ast_mutex_lock(&iaxsl[callno]); 01967 goto retry; 01968 } 01969 } 01970 if (!owner) 01971 iaxs[callno] = NULL; 01972 if (pvt) { 01973 if (!owner) 01974 pvt->owner = NULL; 01975 iax2_destroy_helper(pvt); 01976 01977 /* Already gone */ 01978 ast_set_flag(pvt, IAX_ALREADYGONE); 01979 01980 if (owner) { 01981 /* If there's an owner, prod it to give up */ 01982 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01983 * because we already hold the owner channel lock. */ 01984 ast_queue_hangup(owner); 01985 } 01986 01987 AST_LIST_LOCK(&iaxq.queue); 01988 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01989 /* Cancel any pending transmissions */ 01990 if (cur->callno == pvt->callno) 01991 cur->retries = -1; 01992 } 01993 AST_LIST_UNLOCK(&iaxq.queue); 01994 01995 if (pvt->reg) 01996 pvt->reg->callno = 0; 01997 if (!owner) { 01998 jb_frame frame; 01999 if (pvt->vars) { 02000 ast_variables_destroy(pvt->vars); 02001 pvt->vars = NULL; 02002 } 02003 02004 while (jb_getall(pvt->jb, &frame) == JB_OK) 02005 iax2_frame_free(frame.data); 02006 jb_destroy(pvt->jb); 02007 /* gotta free up the stringfields */ 02008 ast_string_field_free_pools(pvt); 02009 free(pvt); 02010 } 02011 } 02012 if (owner) { 02013 ast_mutex_unlock(&owner->lock); 02014 } 02015 if (callno & 0x4000) 02016 update_max_trunk(); 02017 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1886 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_destroy(), iax2_predestroy(), and stop_stuff().
01887 { 01888 /* Decrement AUTHREQ count if needed */ 01889 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01890 struct iax2_user *user; 01891 struct iax2_user tmp_user = { 01892 .name = pvt->username, 01893 }; 01894 01895 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01896 if (user) { 01897 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01898 user_unref(user); 01899 } 01900 01901 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01902 } 01903 /* No more pings or lagrq's */ 01904 if (pvt->pingid > -1) 01905 ast_sched_del(sched, pvt->pingid); 01906 pvt->pingid = -1; 01907 if (pvt->lagid > -1) 01908 ast_sched_del(sched, pvt->lagid); 01909 pvt->lagid = -1; 01910 if (pvt->autoid > -1) 01911 ast_sched_del(sched, pvt->autoid); 01912 pvt->autoid = -1; 01913 if (pvt->authid > -1) 01914 ast_sched_del(sched, pvt->authid); 01915 pvt->authid = -1; 01916 if (pvt->initid > -1) 01917 ast_sched_del(sched, pvt->initid); 01918 pvt->initid = -1; 01919 if (pvt->jbid > -1) 01920 ast_sched_del(sched, pvt->jbid); 01921 pvt->jbid = -1; 01922 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10301 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, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().
10302 { 10303 struct parsed_dial_string pds; 10304 char *tmp = ast_strdupa(data); 10305 struct iax2_peer *p; 10306 int res = AST_DEVICE_INVALID; 10307 10308 memset(&pds, 0, sizeof(pds)); 10309 parse_dial_string(tmp, &pds); 10310 if (ast_strlen_zero(pds.peer)) 10311 return res; 10312 10313 if (option_debug > 2) 10314 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10315 10316 /* SLD: FIXME: second call to find_peer during registration */ 10317 if (!(p = find_peer(pds.peer, 1))) 10318 return res; 10319 10320 res = AST_DEVICE_UNAVAILABLE; 10321 if (option_debug > 2) 10322 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10323 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10324 10325 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10326 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10327 /* Peer is registered, or have default IP address 10328 and a valid registration */ 10329 if (p->historicms == 0 || p->historicms <= p->maxms) 10330 /* let the core figure out whether it is in use or not */ 10331 res = AST_DEVICE_UNKNOWN; 10332 } 10333 10334 peer_unref(p); 10335 10336 return res; 10337 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2633 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02634 { 02635 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02636 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2638 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02639 { 02640 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02641 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4691 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04692 { 04693 if (argc < 2 || argc > 3) 04694 return RESULT_SHOWUSAGE; 04695 iaxdebug = 1; 04696 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04697 return RESULT_SUCCESS; 04698 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4709 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04710 { 04711 if (argc < 3 || argc > 4) 04712 return RESULT_SHOWUSAGE; 04713 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04714 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04715 return RESULT_SUCCESS; 04716 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8300 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_add(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), 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().
08301 { 08302 struct iax_ie_data ied; 08303 if (option_debug && iaxdebug) 08304 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08305 08306 if (reg->dnsmgr && 08307 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08308 /* Maybe the IP has changed, force DNS refresh */ 08309 ast_dnsmgr_refresh(reg->dnsmgr); 08310 } 08311 08312 /* 08313 * if IP has Changed, free allocated call to create a new one with new IP 08314 * call has the pointer to IP and must be updated to the new one 08315 */ 08316 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08317 ast_mutex_lock(&iaxsl[reg->callno]); 08318 iax2_destroy(reg->callno); 08319 ast_mutex_unlock(&iaxsl[reg->callno]); 08320 reg->callno = 0; 08321 } 08322 if (!reg->addr.sin_addr.s_addr) { 08323 if (option_debug && iaxdebug) 08324 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08325 /* Setup the next registration attempt */ 08326 if (reg->expire > -1) 08327 ast_sched_del(sched, reg->expire); 08328 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08329 return -1; 08330 } 08331 08332 if (!reg->callno) { 08333 if (option_debug) 08334 ast_log(LOG_DEBUG, "Allocate call number\n"); 08335 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, defaultsockfd); 08336 if (reg->callno < 1) { 08337 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08338 return -1; 08339 } else if (option_debug) 08340 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08341 iaxs[reg->callno]->reg = reg; 08342 } 08343 /* Schedule the next registration attempt */ 08344 if (reg->expire > -1) 08345 ast_sched_del(sched, reg->expire); 08346 /* Setup the next registration a little early */ 08347 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08348 /* Send the request */ 08349 memset(&ied, 0, sizeof(ied)); 08350 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08351 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08352 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08353 reg->regstate = REG_STATE_REGSENT; 08354 return 0; 08355 }
static int iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5493 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05494 { 05495 #ifdef SCHED_MULTITHREADED 05496 if (schedule_action(__iax2_do_register_s, data)) 05497 #endif 05498 __iax2_do_register_s(data); 05499 return 0; 05500 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4700 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04701 { 04702 if (argc < 3 || argc > 4) 04703 return RESULT_SHOWUSAGE; 04704 iaxtrunkdebug = 1; 04705 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04706 return RESULT_SUCCESS; 04707 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6152 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
06153 { 06154 struct iax_ie_data ied; 06155 /* Auto-hangup with 30 seconds of inactivity */ 06156 if (iaxs[callno]->autoid > -1) 06157 ast_sched_del(sched, iaxs[callno]->autoid); 06158 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06159 memset(&ied, 0, sizeof(ied)); 06160 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06161 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06162 dp->flags |= CACHE_FLAG_TRANSMITTED; 06163 }
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 10160 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.
10161 { 10162 char odata[256]; 10163 char req[256]; 10164 char *ncontext; 10165 struct iax2_dpcache *dp; 10166 struct ast_app *dial; 10167 #if 0 10168 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); 10169 #endif 10170 if (priority == 2) { 10171 /* Indicate status, can be overridden in dialplan */ 10172 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10173 if (dialstatus) { 10174 dial = pbx_findapp(dialstatus); 10175 if (dial) 10176 pbx_exec(chan, dial, ""); 10177 } 10178 return -1; 10179 } else if (priority != 1) 10180 return -1; 10181 ast_mutex_lock(&dpcache_lock); 10182 dp = find_cache(chan, data, context, exten, priority); 10183 if (dp) { 10184 if (dp->flags & CACHE_FLAG_EXISTS) { 10185 ast_copy_string(odata, data, sizeof(odata)); 10186 ncontext = strchr(odata, '/'); 10187 if (ncontext) { 10188 *ncontext = '\0'; 10189 ncontext++; 10190 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10191 } else { 10192 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10193 } 10194 if (option_verbose > 2) 10195 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10196 } else { 10197 ast_mutex_unlock(&dpcache_lock); 10198 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10199 return -1; 10200 } 10201 } 10202 ast_mutex_unlock(&dpcache_lock); 10203 dial = pbx_findapp("Dial"); 10204 if (dial) { 10205 return pbx_exec(chan, dial, req); 10206 } else { 10207 ast_log(LOG_WARNING, "No dial application registered\n"); 10208 } 10209 return -1; 10210 }
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 10091 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.
10092 { 10093 struct iax2_dpcache *dp; 10094 int res = 0; 10095 #if 0 10096 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10097 #endif 10098 if ((priority != 1) && (priority != 2)) 10099 return 0; 10100 ast_mutex_lock(&dpcache_lock); 10101 dp = find_cache(chan, data, context, exten, priority); 10102 if (dp) { 10103 if (dp->flags & CACHE_FLAG_EXISTS) 10104 res= 1; 10105 } 10106 ast_mutex_unlock(&dpcache_lock); 10107 if (!dp) { 10108 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10109 } 10110 return res; 10111 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2660 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.
02661 { 02662 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02663 ast_mutex_lock(&iaxsl[callno]); 02664 if (iaxs[callno]) 02665 iaxs[callno]->owner = newchan; 02666 else 02667 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02668 ast_mutex_unlock(&iaxsl[callno]); 02669 return 0; 02670 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1410 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(), iax2_destroy(), and schedule_delivery().
01411 { 01412 if (fr->retrans > -1) 01413 ast_sched_del(sched, fr->retrans); 01414 iax_frame_free(fr); 01415 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1141 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().
01142 { 01143 struct iax2_peer *peer = NULL; 01144 int res = 0; 01145 ao2_iterator i; 01146 01147 i = ao2_iterator_init(peers, 0); 01148 while ((peer = ao2_iterator_next(&i))) { 01149 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01150 (peer->addr.sin_port == sin.sin_port)) { 01151 ast_copy_string(host, peer->name, len); 01152 peer_unref(peer); 01153 res = 1; 01154 break; 01155 } 01156 peer_unref(peer); 01157 } 01158 01159 if (!peer) { 01160 peer = realtime_peer(NULL, &sin); 01161 if (peer) { 01162 ast_copy_string(host, peer->name, len); 01163 peer_unref(peer); 01164 res = 1; 01165 } 01166 } 01167 01168 return res; 01169 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3492 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().
03493 { 03494 struct iax2_peer *peer; 03495 int res = 0; 03496 ao2_iterator i; 03497 03498 i = ao2_iterator_init(peers, 0); 03499 while ((peer = ao2_iterator_next(&i))) { 03500 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03501 (peer->addr.sin_port == sin.sin_port)) { 03502 res = ast_test_flag(peer, IAX_TRUNK); 03503 peer_unref(peer); 03504 break; 03505 } 03506 peer_unref(peer); 03507 } 03508 03509 return res; 03510 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3172 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_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03173 { 03174 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03175 int alreadygone; 03176 struct iax_ie_data ied; 03177 memset(&ied, 0, sizeof(ied)); 03178 ast_mutex_lock(&iaxsl[callno]); 03179 if (callno && iaxs[callno]) { 03180 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03181 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03182 /* Send the hangup unless we have had a transmission error or are already gone */ 03183 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03184 if (!iaxs[callno]->error && !alreadygone) { 03185 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03186 if (!iaxs[callno]) { 03187 ast_mutex_unlock(&iaxsl[callno]); 03188 return 0; 03189 } 03190 } 03191 /* Explicitly predestroy it */ 03192 iax2_predestroy(callno); 03193 /* If we were already gone to begin with, destroy us now */ 03194 if (alreadygone && iaxs[callno]) { 03195 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03196 iax2_destroy(callno); 03197 } 03198 } 03199 ast_mutex_unlock(&iaxsl[callno]); 03200 if (option_verbose > 2) 03201 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03202 return 0; 03203 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3438 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(), iaxs, iaxsl, option_debug, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03439 { 03440 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03441 struct chan_iax2_pvt *pvt; 03442 int res = 0; 03443 03444 if (option_debug && iaxdebug) 03445 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03446 03447 ast_mutex_lock(&iaxsl[callno]); 03448 pvt = iaxs[callno]; 03449 03450 switch (condition) { 03451 case AST_CONTROL_HOLD: 03452 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03453 ast_moh_start(c, data, pvt->mohinterpret); 03454 goto done; 03455 } 03456 break; 03457 case AST_CONTROL_UNHOLD: 03458 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03459 ast_moh_stop(c); 03460 goto done; 03461 } 03462 } 03463 03464 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03465 03466 done: 03467 ast_mutex_unlock(&iaxsl[callno]); 03468 03469 return res; 03470 }
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 10137 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.
10138 { 10139 int res = 0; 10140 struct iax2_dpcache *dp; 10141 #if 0 10142 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10143 #endif 10144 if ((priority != 1) && (priority != 2)) 10145 return 0; 10146 ast_mutex_lock(&dpcache_lock); 10147 dp = find_cache(chan, data, context, exten, priority); 10148 if (dp) { 10149 if (dp->flags & CACHE_FLAG_MATCHMORE) 10150 res= 1; 10151 } 10152 ast_mutex_unlock(&dpcache_lock); 10153 if (!dp) { 10154 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10155 } 10156 return res; 10157 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4718 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04719 { 04720 if (argc < 3 || argc > 4) 04721 return RESULT_SHOWUSAGE; 04722 iaxdebug = 0; 04723 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04724 return RESULT_SUCCESS; 04725 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4736 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04737 { 04738 if (argc < 4 || argc > 5) 04739 return RESULT_SHOWUSAGE; 04740 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04741 jb_debug_output("\n"); 04742 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04743 return RESULT_SUCCESS; 04744 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4727 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04728 { 04729 if (argc < 4 || argc > 5) 04730 return RESULT_SHOWUSAGE; 04731 iaxtrunkdebug = 0; 04732 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04733 return RESULT_SUCCESS; 04734 }
static int iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 8496 of file chan_iax2.c.
References __iax2_poke_noanswer(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08497 { 08498 struct iax2_peer *peer = data; 08499 peer->pokeexpire = -1; 08500 #ifdef SCHED_MULTITHREADED 08501 if (schedule_action(__iax2_poke_noanswer, data)) 08502 #endif 08503 __iax2_poke_noanswer(data); 08504 return 0; 08505 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8516 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), reg_source_db(), and update_registry().
08517 { 08518 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 08519 /* IF we have no IP, or this isn't to be monitored, return 08520 immediately after clearing things out */ 08521 peer->lastms = 0; 08522 peer->historicms = 0; 08523 peer->pokeexpire = -1; 08524 peer->callno = 0; 08525 return 0; 08526 } 08527 if (peer->callno > 0) { 08528 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08529 ast_mutex_lock(&iaxsl[peer->callno]); 08530 iax2_destroy(peer->callno); 08531 ast_mutex_unlock(&iaxsl[peer->callno]); 08532 } 08533 if (heldcall) 08534 ast_mutex_unlock(&iaxsl[heldcall]); 08535 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd); 08536 if (heldcall) 08537 ast_mutex_lock(&iaxsl[heldcall]); 08538 if (peer->callno < 1) { 08539 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08540 return -1; 08541 } 08542 08543 /* Speed up retransmission times for this qualify call */ 08544 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08545 iaxs[peer->callno]->peerpoke = peer; 08546 08547 /* Remove any pending pokeexpire task */ 08548 if (peer->pokeexpire > -1) 08549 ast_sched_del(sched, peer->pokeexpire); 08550 08551 /* Queue up a new task to handle no reply */ 08552 /* If the host is already unreachable then use the unreachable interval instead */ 08553 if (peer->lastms < 0) { 08554 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 08555 } else 08556 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 08557 08558 /* And send the poke */ 08559 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08560 08561 return 0; 08562 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8507 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module(), and reload_config().
08508 { 08509 struct iax2_peer *peer = obj; 08510 08511 iax2_poke_peer(peer, 0); 08512 08513 return 0; 08514 }
static int iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 6192 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06193 { 06194 struct iax2_peer *peer = data; 06195 peer->pokeexpire = -1; 06196 #ifdef SCHED_MULTITHREADED 06197 if (schedule_action(__iax2_poke_peer_s, data)) 06198 #endif 06199 __iax2_poke_peer_s(data); 06200 return 0; 06201 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1928 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().
01929 { 01930 struct ast_channel *c; 01931 struct chan_iax2_pvt *pvt = iaxs[callno]; 01932 01933 if (!pvt) 01934 return -1; 01935 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01936 iax2_destroy_helper(pvt); 01937 ast_set_flag(pvt, IAX_ALREADYGONE); 01938 } 01939 c = pvt->owner; 01940 if (c) { 01941 c->tech_pvt = NULL; 01942 iax2_queue_hangup(callno); 01943 pvt->owner = NULL; 01944 ast_module_unref(ast_module_info->self); 01945 } 01946 return 0; 01947 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8187 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().
08188 { 08189 struct iax2_thread *thread = data; 08190 struct timeval tv; 08191 struct timespec ts; 08192 int put_into_idle = 0; 08193 08194 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08195 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08196 for(;;) { 08197 /* Wait for something to signal us to be awake */ 08198 ast_mutex_lock(&thread->lock); 08199 08200 /* Flag that we're ready to accept signals */ 08201 thread->ready_for_signal = 1; 08202 08203 /* Put into idle list if applicable */ 08204 if (put_into_idle) 08205 insert_idle_thread(thread); 08206 08207 if (thread->type == IAX_TYPE_DYNAMIC) { 08208 struct iax2_thread *t = NULL; 08209 /* Wait to be signalled or time out */ 08210 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08211 ts.tv_sec = tv.tv_sec; 08212 ts.tv_nsec = tv.tv_usec * 1000; 08213 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08214 /* This thread was never put back into the available dynamic 08215 * thread list, so just go away. */ 08216 if (!put_into_idle) { 08217 ast_mutex_unlock(&thread->lock); 08218 break; 08219 } 08220 AST_LIST_LOCK(&dynamic_list); 08221 /* Account for the case where this thread is acquired *right* after a timeout */ 08222 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08223 iaxdynamicthreadcount--; 08224 AST_LIST_UNLOCK(&dynamic_list); 08225 if (t) { 08226 /* This dynamic thread timed out waiting for a task and was 08227 * not acquired immediately after the timeout, 08228 * so it's time to go away. */ 08229 ast_mutex_unlock(&thread->lock); 08230 break; 08231 } 08232 /* Someone grabbed our thread *right* after we timed out. 08233 * Wait for them to set us up with something to do and signal 08234 * us to continue. */ 08235 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08236 ts.tv_sec = tv.tv_sec; 08237 ts.tv_nsec = tv.tv_usec * 1000; 08238 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08239 { 08240 ast_mutex_unlock(&thread->lock); 08241 break; 08242 } 08243 } 08244 } else { 08245 ast_cond_wait(&thread->cond, &thread->lock); 08246 } 08247 08248 /* Go back into our respective list */ 08249 put_into_idle = 1; 08250 08251 ast_mutex_unlock(&thread->lock); 08252 08253 if (thread->iostate == IAX_IOSTATE_IDLE) 08254 continue; 08255 08256 /* Add ourselves to the active list now */ 08257 AST_LIST_LOCK(&active_list); 08258 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08259 AST_LIST_UNLOCK(&active_list); 08260 08261 /* See what we need to do */ 08262 switch(thread->iostate) { 08263 case IAX_IOSTATE_READY: 08264 thread->actions++; 08265 thread->iostate = IAX_IOSTATE_PROCESSING; 08266 socket_process(thread); 08267 handle_deferred_full_frames(thread); 08268 break; 08269 case IAX_IOSTATE_SCHEDREADY: 08270 thread->actions++; 08271 thread->iostate = IAX_IOSTATE_PROCESSING; 08272 #ifdef SCHED_MULTITHREADED 08273 thread->schedfunc(thread->scheddata); 08274 #endif 08275 break; 08276 } 08277 time(&thread->checktime); 08278 thread->iostate = IAX_IOSTATE_IDLE; 08279 #ifdef DEBUG_SCHED_MULTITHREAD 08280 thread->curfunc[0]='\0'; 08281 #endif 08282 08283 /* Now... remove ourselves from the active list, and return to the idle list */ 08284 AST_LIST_LOCK(&active_list); 08285 AST_LIST_REMOVE(&active_list, thread, list); 08286 AST_LIST_UNLOCK(&active_list); 08287 08288 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08289 handle_deferred_full_frames(thread); 08290 } 08291 08292 /* I am exiting here on my own volition, I need to clean up my own data structures 08293 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08294 */ 08295 pthread_cleanup_pop(1); 08296 08297 return NULL; 08298 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8178 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08179 { 08180 struct iax2_thread *thread = data; 08181 ast_mutex_destroy(&thread->lock); 08182 ast_cond_destroy(&thread->cond); 08183 free(thread); 08184 ast_atomic_dec_and_test(&iaxactivethreadcount); 08185 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8455 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08456 { 08457 int force = 0; 08458 int res; 08459 if (argc < 4) 08460 return RESULT_SHOWUSAGE; 08461 if ((argc > 4)) { 08462 if (!strcasecmp(argv[4], "forced")) 08463 force = 1; 08464 else 08465 return RESULT_SHOWUSAGE; 08466 } 08467 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08468 if (res < 0) 08469 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08470 else if (res < 1) 08471 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08472 else 08473 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08474 return RESULT_SUCCESS; 08475 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8357 of file chan_iax2.c.
References iax_prov_complete_template().
08358 { 08359 if (pos != 3) 08360 return NULL; 08361 return iax_prov_complete_template(line, word, pos, state); 08362 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8364 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08365 { 08366 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08367 is found for template */ 08368 struct iax_ie_data provdata; 08369 struct iax_ie_data ied; 08370 unsigned int sig; 08371 struct sockaddr_in sin; 08372 int callno; 08373 struct create_addr_info cai; 08374 08375 memset(&cai, 0, sizeof(cai)); 08376 08377 if (option_debug) 08378 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08379 08380 if (iax_provision_build(&provdata, &sig, template, force)) { 08381 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08382 return 0; 08383 } 08384 08385 if (end) { 08386 memcpy(&sin, end, sizeof(sin)); 08387 cai.sockfd = sockfd; 08388 } else if (create_addr(dest, &sin, &cai)) 08389 return -1; 08390 08391 /* Build the rest of the message */ 08392 memset(&ied, 0, sizeof(ied)); 08393 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08394 08395 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08396 if (!callno) 08397 return -1; 08398 08399 ast_mutex_lock(&iaxsl[callno]); 08400 if (iaxs[callno]) { 08401 /* Schedule autodestruct in case they don't ever give us anything back */ 08402 if (iaxs[callno]->autoid > -1) 08403 ast_sched_del(sched, iaxs[callno]->autoid); 08404 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08405 ast_set_flag(iaxs[callno], IAX_PROVISION); 08406 /* Got a call number now, so go ahead and send the provisioning information */ 08407 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08408 } 08409 ast_mutex_unlock(&iaxsl[callno]); 08410 08411 return 1; 08412 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2122 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02123 { 02124 struct iax2_peer *peer; 02125 02126 if (argc != 4) 02127 return RESULT_SHOWUSAGE; 02128 if (!strcmp(argv[3],"all")) { 02129 reload_config(); 02130 ast_cli(fd, "OK cache is flushed.\n"); 02131 } else if ((peer = find_peer(argv[3], 0))) { 02132 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02133 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02134 expire_registry((void *)peer->name); 02135 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02136 } else { 02137 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02138 } 02139 peer_unref(peer); 02140 } else { 02141 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02142 } 02143 02144 return RESULT_SUCCESS; 02145 }
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 1493 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), iaxs, and iaxsl.
Referenced by socket_process().
01495 { 01496 for (;;) { 01497 if (iaxs[callno] && iaxs[callno]->owner) { 01498 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01499 /* Avoid deadlock by pausing and trying again */ 01500 ast_mutex_unlock(&iaxsl[callno]); 01501 usleep(1); 01502 ast_mutex_lock(&iaxsl[callno]); 01503 } else { 01504 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01505 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01506 break; 01507 } 01508 } else 01509 break; 01510 } 01511 return 0; 01512 }
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 1427 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), f, iaxs, and iaxsl.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), and __get_from_jb().
01428 { 01429 for (;;) { 01430 if (iaxs[callno] && iaxs[callno]->owner) { 01431 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01432 /* Avoid deadlock by pausing and trying again */ 01433 ast_mutex_unlock(&iaxsl[callno]); 01434 usleep(1); 01435 ast_mutex_lock(&iaxsl[callno]); 01436 } else { 01437 ast_queue_frame(iaxs[callno]->owner, f); 01438 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01439 break; 01440 } 01441 } else 01442 break; 01443 } 01444 return 0; 01445 }
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 1460 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), iaxs, and iaxsl.
Referenced by iax2_predestroy().
01461 { 01462 for (;;) { 01463 if (iaxs[callno] && iaxs[callno]->owner) { 01464 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01465 /* Avoid deadlock by pausing and trying again */ 01466 ast_mutex_unlock(&iaxsl[callno]); 01467 usleep(1); 01468 ast_mutex_lock(&iaxsl[callno]); 01469 } else { 01470 ast_queue_hangup(iaxs[callno]->owner); 01471 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01472 break; 01473 } 01474 } else 01475 break; 01476 } 01477 return 0; 01478 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3231 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
03232 { 03233 ast_log(LOG_NOTICE, "I should never be called!\n"); 03234 return &ast_null_frame; 03235 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5701 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().
05702 { 05703 struct iax2_registry *reg; 05704 char copy[256]; 05705 char *username, *hostname, *secret; 05706 char *porta; 05707 char *stringp=NULL; 05708 05709 if (!value) 05710 return -1; 05711 ast_copy_string(copy, value, sizeof(copy)); 05712 stringp=copy; 05713 username = strsep(&stringp, "@"); 05714 hostname = strsep(&stringp, "@"); 05715 if (!hostname) { 05716 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05717 return -1; 05718 } 05719 stringp=username; 05720 username = strsep(&stringp, ":"); 05721 secret = strsep(&stringp, ":"); 05722 stringp=hostname; 05723 hostname = strsep(&stringp, ":"); 05724 porta = strsep(&stringp, ":"); 05725 05726 if (porta && !atoi(porta)) { 05727 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05728 return -1; 05729 } 05730 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05731 return -1; 05732 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05733 free(reg); 05734 return -1; 05735 } 05736 ast_copy_string(reg->username, username, sizeof(reg->username)); 05737 if (secret) 05738 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05739 reg->expire = -1; 05740 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05741 reg->addr.sin_family = AF_INET; 05742 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05743 AST_LIST_LOCK(®istrations); 05744 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05745 AST_LIST_UNLOCK(®istrations); 05746 05747 return 0; 05748 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9865 of file chan_iax2.c.
References reload_config().
09866 { 09867 return reload_config(); 09868 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8574 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), 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.
08575 { 08576 int callno; 08577 int res; 08578 int fmt, native; 08579 struct sockaddr_in sin; 08580 struct ast_channel *c; 08581 struct parsed_dial_string pds; 08582 struct create_addr_info cai; 08583 char *tmpstr; 08584 08585 memset(&pds, 0, sizeof(pds)); 08586 tmpstr = ast_strdupa(data); 08587 parse_dial_string(tmpstr, &pds); 08588 08589 memset(&cai, 0, sizeof(cai)); 08590 cai.capability = iax2_capability; 08591 08592 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08593 08594 if (!pds.peer) { 08595 ast_log(LOG_WARNING, "No peer given\n"); 08596 return NULL; 08597 } 08598 08599 08600 /* Populate our address from the given */ 08601 if (create_addr(pds.peer, &sin, &cai)) { 08602 *cause = AST_CAUSE_UNREGISTERED; 08603 return NULL; 08604 } 08605 08606 if (pds.port) 08607 sin.sin_port = htons(atoi(pds.port)); 08608 08609 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd); 08610 if (callno < 1) { 08611 ast_log(LOG_WARNING, "Unable to create call\n"); 08612 *cause = AST_CAUSE_CONGESTION; 08613 return NULL; 08614 } 08615 08616 ast_mutex_lock(&iaxsl[callno]); 08617 08618 /* If this is a trunk, update it now */ 08619 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08620 if (ast_test_flag(&cai, IAX_TRUNK)) { 08621 int new_callno; 08622 if ((new_callno = make_trunk(callno, 1)) != -1) 08623 callno = new_callno; 08624 } 08625 iaxs[callno]->maxtime = cai.maxtime; 08626 if (cai.found) 08627 ast_string_field_set(iaxs[callno], host, pds.peer); 08628 08629 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08630 08631 ast_mutex_unlock(&iaxsl[callno]); 08632 08633 if (c) { 08634 /* Choose a format we can live with */ 08635 if (c->nativeformats & format) 08636 c->nativeformats &= format; 08637 else { 08638 native = c->nativeformats; 08639 fmt = format; 08640 res = ast_translator_best_choice(&fmt, &native); 08641 if (res < 0) { 08642 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08643 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08644 ast_hangup(c); 08645 return NULL; 08646 } 08647 c->nativeformats = native; 08648 } 08649 c->readformat = ast_best_codec(c->nativeformats); 08650 c->writeformat = c->readformat; 08651 } 08652 08653 return c; 08654 }
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 4040 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, 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().
04041 { 04042 /* Queue a packet for delivery on a given private structure. Use "ts" for 04043 timestamp, or calculate if ts is 0. Send immediately without retransmission 04044 or delayed, with retransmission */ 04045 struct ast_iax2_full_hdr *fh; 04046 struct ast_iax2_mini_hdr *mh; 04047 struct ast_iax2_video_hdr *vh; 04048 struct { 04049 struct iax_frame fr2; 04050 unsigned char buffer[4096]; 04051 } frb; 04052 struct iax_frame *fr; 04053 int res; 04054 int sendmini=0; 04055 unsigned int lastsent; 04056 unsigned int fts; 04057 04058 frb.fr2.afdatalen = sizeof(frb.buffer); 04059 04060 if (!pvt) { 04061 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04062 return -1; 04063 } 04064 04065 lastsent = pvt->lastsent; 04066 04067 /* Calculate actual timestamp */ 04068 fts = calc_timestamp(pvt, ts, f); 04069 04070 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04071 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04072 * increment the "predicted timestamps" for voice, if we're predecting */ 04073 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04074 return 0; 04075 04076 04077 if ((ast_test_flag(pvt, IAX_TRUNK) || 04078 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04079 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04080 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04081 (f->frametype == AST_FRAME_VOICE) 04082 /* is a voice frame */ && 04083 (f->subclass == pvt->svoiceformat) 04084 /* is the same type */ ) { 04085 /* Force immediate rather than delayed transmission */ 04086 now = 1; 04087 /* Mark that mini-style frame is appropriate */ 04088 sendmini = 1; 04089 } 04090 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 04091 (f->frametype == AST_FRAME_VIDEO) && 04092 ((f->subclass & ~0x1) == pvt->svideoformat)) { 04093 now = 1; 04094 sendmini = 1; 04095 } 04096 /* Allocate an iax_frame */ 04097 if (now) { 04098 fr = &frb.fr2; 04099 } else 04100 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)); 04101 if (!fr) { 04102 ast_log(LOG_WARNING, "Out of memory\n"); 04103 return -1; 04104 } 04105 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04106 iax_frame_wrap(fr, f); 04107 04108 fr->ts = fts; 04109 fr->callno = pvt->callno; 04110 fr->transfer = transfer; 04111 fr->final = final; 04112 if (!sendmini) { 04113 /* We need a full frame */ 04114 if (seqno > -1) 04115 fr->oseqno = seqno; 04116 else 04117 fr->oseqno = pvt->oseqno++; 04118 fr->iseqno = pvt->iseqno; 04119 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04120 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04121 fh->ts = htonl(fr->ts); 04122 fh->oseqno = fr->oseqno; 04123 if (transfer) { 04124 fh->iseqno = 0; 04125 } else 04126 fh->iseqno = fr->iseqno; 04127 /* Keep track of the last thing we've acknowledged */ 04128 if (!transfer) 04129 pvt->aseqno = fr->iseqno; 04130 fh->type = fr->af.frametype & 0xFF; 04131 if (fr->af.frametype == AST_FRAME_VIDEO) 04132 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04133 else 04134 fh->csub = compress_subclass(fr->af.subclass); 04135 if (transfer) { 04136 fr->dcallno = pvt->transfercallno; 04137 } else 04138 fr->dcallno = pvt->peercallno; 04139 fh->dcallno = htons(fr->dcallno); 04140 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04141 fr->data = fh; 04142 fr->retries = 0; 04143 /* Retry after 2x the ping time has passed */ 04144 fr->retrytime = pvt->pingtime * 2; 04145 if (fr->retrytime < MIN_RETRY_TIME) 04146 fr->retrytime = MIN_RETRY_TIME; 04147 if (fr->retrytime > MAX_RETRY_TIME) 04148 fr->retrytime = MAX_RETRY_TIME; 04149 /* Acks' don't get retried */ 04150 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04151 fr->retries = -1; 04152 else if (f->frametype == AST_FRAME_VOICE) 04153 pvt->svoiceformat = f->subclass; 04154 else if (f->frametype == AST_FRAME_VIDEO) 04155 pvt->svideoformat = f->subclass & ~0x1; 04156 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04157 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04158 if (iaxdebug) { 04159 if (fr->transfer) 04160 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04161 else 04162 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04163 } 04164 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04165 } else 04166 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04167 } 04168 04169 if (now) { 04170 res = send_packet(fr); 04171 } else 04172 res = iax2_transmit(fr); 04173 } else { 04174 if (ast_test_flag(pvt, IAX_TRUNK)) { 04175 iax2_trunk_queue(pvt, fr); 04176 res = 0; 04177 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04178 /* Video frame have no sequence number */ 04179 fr->oseqno = -1; 04180 fr->iseqno = -1; 04181 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04182 vh->zeros = 0; 04183 vh->callno = htons(0x8000 | fr->callno); 04184 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04185 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04186 fr->data = vh; 04187 fr->retries = -1; 04188 res = send_packet(fr); 04189 } else { 04190 /* Mini-frames have no sequence number */ 04191 fr->oseqno = -1; 04192 fr->iseqno = -1; 04193 /* Mini frame will do */ 04194 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04195 mh->callno = htons(fr->callno); 04196 mh->ts = htons(fr->ts & 0xFFFF); 04197 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04198 fr->data = mh; 04199 fr->retries = -1; 04200 if (pvt->transferring == TRANSFER_MEDIAPASS) 04201 fr->transfer = 1; 04202 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04203 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04204 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04205 } else 04206 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04207 } 04208 res = send_packet(fr); 04209 } 04210 } 04211 return res; 04212 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2655 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02656 { 02657 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02658 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2650 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.
02651 { 02652 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02653 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2643 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02644 { 02645 02646 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02647 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02648 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3205 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03206 { 03207 struct ast_option_header *h; 03208 int res; 03209 03210 switch (option) { 03211 case AST_OPTION_TXGAIN: 03212 case AST_OPTION_RXGAIN: 03213 /* these two cannot be sent, because they require a result */ 03214 errno = ENOSYS; 03215 return -1; 03216 default: 03217 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03218 return -1; 03219 03220 h->flag = AST_OPTION_FLAG_REQUEST; 03221 h->option = htons(option); 03222 memcpy(h->data, data, datalen); 03223 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03224 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03225 datalen + sizeof(*h), -1); 03226 free(h); 03227 return res; 03228 } 03229 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2326 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.
02327 { 02328 struct iax2_dpcache *dp; 02329 char tmp[1024], *pc; 02330 int s; 02331 int x,y; 02332 struct timeval tv; 02333 gettimeofday(&tv, NULL); 02334 ast_mutex_lock(&dpcache_lock); 02335 dp = dpcache; 02336 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02337 while(dp) { 02338 s = dp->expiry.tv_sec - tv.tv_sec; 02339 tmp[0] = '\0'; 02340 if (dp->flags & CACHE_FLAG_EXISTS) 02341 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02342 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02343 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02344 if (dp->flags & CACHE_FLAG_CANEXIST) 02345 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02346 if (dp->flags & CACHE_FLAG_PENDING) 02347 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02348 if (dp->flags & CACHE_FLAG_TIMEOUT) 02349 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02350 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02351 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02352 if (dp->flags & CACHE_FLAG_MATCHMORE) 02353 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02354 if (dp->flags & CACHE_FLAG_UNKNOWN) 02355 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02356 /* Trim trailing pipe */ 02357 if (!ast_strlen_zero(tmp)) 02358 tmp[strlen(tmp) - 1] = '\0'; 02359 else 02360 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02361 y=0; 02362 pc = strchr(dp->peercontext, '@'); 02363 if (!pc) 02364 pc = dp->peercontext; 02365 else 02366 pc++; 02367 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02368 if (dp->waiters[x] > -1) 02369 y++; 02370 if (s > 0) 02371 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02372 else 02373 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02374 dp = dp->next; 02375 } 02376 ast_mutex_unlock(&dpcache_lock); 02377 return RESULT_SUCCESS; 02378 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4556 of file chan_iax2.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04557 { 04558 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04559 #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" 04560 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04561 int x; 04562 int numchans = 0; 04563 04564 if (argc != 3) 04565 return RESULT_SHOWUSAGE; 04566 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04567 for (x=0;x<IAX_MAX_CALLS;x++) { 04568 ast_mutex_lock(&iaxsl[x]); 04569 if (iaxs[x]) { 04570 int lag, jitter, localdelay; 04571 jb_info jbinfo; 04572 04573 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04574 jb_getinfo(iaxs[x]->jb, &jbinfo); 04575 jitter = jbinfo.jitter; 04576 localdelay = jbinfo.current - jbinfo.min; 04577 } else { 04578 jitter = -1; 04579 localdelay = 0; 04580 } 04581 lag = iaxs[x]->remote_rr.delay; 04582 ast_cli(fd, FORMAT, 04583 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04584 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04585 S_OR(iaxs[x]->username, "(None)"), 04586 iaxs[x]->callno, iaxs[x]->peercallno, 04587 iaxs[x]->oseqno, iaxs[x]->iseqno, 04588 lag, 04589 jitter, 04590 localdelay, 04591 ast_getformatname(iaxs[x]->voiceformat) ); 04592 numchans++; 04593 } 04594 ast_mutex_unlock(&iaxsl[x]); 04595 } 04596 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04597 return RESULT_SUCCESS; 04598 #undef FORMAT 04599 #undef FORMAT2 04600 #undef FORMATB 04601 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4467 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.
04468 { 04469 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04470 #if !defined(__FreeBSD__) 04471 #define FORMAT "%-15.15s %-15d %-15d\n" 04472 #else /* __FreeBSD__ */ 04473 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04474 #endif /* __FreeBSD__ */ 04475 struct iax_firmware *cur; 04476 if ((argc != 3) && (argc != 4)) 04477 return RESULT_SHOWUSAGE; 04478 ast_mutex_lock(&waresl.lock); 04479 04480 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04481 for (cur = waresl.wares;cur;cur = cur->next) { 04482 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04483 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04484 (int)ntohl(cur->fwh->datalen)); 04485 } 04486 ast_mutex_unlock(&waresl.lock); 04487 return RESULT_SUCCESS; 04488 #undef FORMAT 04489 #undef FORMAT2 04490 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4679 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04680 { 04681 int numchans = 0; 04682 if (argc != 3) 04683 return RESULT_SHOWUSAGE; 04684 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04685 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04686 numchans = ast_cli_netstats(NULL, fd, 1); 04687 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04688 return RESULT_SUCCESS; 04689 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2216 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.
02217 { 02218 char status[30]; 02219 char cbuf[256]; 02220 struct iax2_peer *peer; 02221 char codec_buf[512]; 02222 int x = 0, codec = 0, load_realtime = 0; 02223 02224 if (argc < 4) 02225 return RESULT_SHOWUSAGE; 02226 02227 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02228 02229 peer = find_peer(argv[3], load_realtime); 02230 if (peer) { 02231 ast_cli(fd,"\n\n"); 02232 ast_cli(fd, " * Name : %s\n", peer->name); 02233 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02234 ast_cli(fd, " Context : %s\n", peer->context); 02235 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02236 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02237 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02238 ast_cli(fd, " Expire : %d\n", peer->expire); 02239 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02240 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)); 02241 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02242 ast_cli(fd, " Username : %s\n", peer->username); 02243 ast_cli(fd, " Codecs : "); 02244 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02245 ast_cli(fd, "%s\n", codec_buf); 02246 02247 ast_cli(fd, " Codec Order : ("); 02248 for(x = 0; x < 32 ; x++) { 02249 codec = ast_codec_pref_index(&peer->prefs,x); 02250 if(!codec) 02251 break; 02252 ast_cli(fd, "%s", ast_getformatname(codec)); 02253 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02254 ast_cli(fd, "|"); 02255 } 02256 02257 if (!x) 02258 ast_cli(fd, "none"); 02259 ast_cli(fd, ")\n"); 02260 02261 ast_cli(fd, " Status : "); 02262 peer_status(peer, status, sizeof(status)); 02263 ast_cli(fd, "%s\n",status); 02264 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02265 ast_cli(fd,"\n"); 02266 peer_unref(peer); 02267 } else { 02268 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02269 ast_cli(fd,"\n"); 02270 } 02271 02272 return RESULT_SUCCESS; 02273 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4456 of file chan_iax2.c.
References __iax2_show_peers().
04457 { 04458 return __iax2_show_peers(0, fd, NULL, argc, argv); 04459 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4528 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.
04529 { 04530 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04531 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04532 struct iax2_registry *reg = NULL; 04533 04534 char host[80]; 04535 char perceived[80]; 04536 if (argc != 3) 04537 return RESULT_SHOWUSAGE; 04538 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04539 AST_LIST_LOCK(®istrations); 04540 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04541 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04542 if (reg->us.sin_addr.s_addr) 04543 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04544 else 04545 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04546 ast_cli(fd, FORMAT, host, 04547 (reg->dnsmgr) ? "Y" : "N", 04548 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04549 } 04550 AST_LIST_UNLOCK(®istrations); 04551 return RESULT_SUCCESS; 04552 #undef FORMAT 04553 #undef FORMAT2 04554 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2300 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.
02301 { 02302 struct iax_frame *cur; 02303 int cnt = 0, dead=0, final=0; 02304 02305 if (argc != 3) 02306 return RESULT_SHOWUSAGE; 02307 02308 AST_LIST_LOCK(&iaxq.queue); 02309 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02310 if (cur->retries < 0) 02311 dead++; 02312 if (cur->final) 02313 final++; 02314 cnt++; 02315 } 02316 AST_LIST_UNLOCK(&iaxq.queue); 02317 02318 ast_cli(fd, " IAX Statistics\n"); 02319 ast_cli(fd, "---------------------\n"); 02320 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02321 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02322 02323 return RESULT_SUCCESS; 02324 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4397 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.
04398 { 04399 struct iax2_thread *thread = NULL; 04400 time_t t; 04401 int threadcount = 0, dynamiccount = 0; 04402 char type; 04403 04404 if (argc != 3) 04405 return RESULT_SHOWUSAGE; 04406 04407 ast_cli(fd, "IAX2 Thread Information\n"); 04408 time(&t); 04409 ast_cli(fd, "Idle Threads:\n"); 04410 AST_LIST_LOCK(&idle_list); 04411 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04412 #ifdef DEBUG_SCHED_MULTITHREAD 04413 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04414 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04415 #else 04416 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04417 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04418 #endif 04419 threadcount++; 04420 } 04421 AST_LIST_UNLOCK(&idle_list); 04422 ast_cli(fd, "Active Threads:\n"); 04423 AST_LIST_LOCK(&active_list); 04424 AST_LIST_TRAVERSE(&active_list, thread, list) { 04425 if (thread->type == IAX_TYPE_DYNAMIC) 04426 type = 'D'; 04427 else 04428 type = 'P'; 04429 #ifdef DEBUG_SCHED_MULTITHREAD 04430 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04431 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04432 #else 04433 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04434 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04435 #endif 04436 threadcount++; 04437 } 04438 AST_LIST_UNLOCK(&active_list); 04439 ast_cli(fd, "Dynamic Threads:\n"); 04440 AST_LIST_LOCK(&dynamic_list); 04441 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04442 #ifdef DEBUG_SCHED_MULTITHREAD 04443 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04444 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04445 #else 04446 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04447 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04448 #endif 04449 dynamiccount++; 04450 } 04451 AST_LIST_UNLOCK(&dynamic_list); 04452 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04453 return RESULT_SUCCESS; 04454 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4214 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.
04215 { 04216 regex_t regexbuf; 04217 int havepattern = 0; 04218 04219 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04220 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04221 04222 struct iax2_user *user = NULL; 04223 char auth[90]; 04224 char *pstr = ""; 04225 ao2_iterator i; 04226 04227 switch (argc) { 04228 case 5: 04229 if (!strcasecmp(argv[3], "like")) { 04230 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04231 return RESULT_SHOWUSAGE; 04232 havepattern = 1; 04233 } else 04234 return RESULT_SHOWUSAGE; 04235 case 3: 04236 break; 04237 default: 04238 return RESULT_SHOWUSAGE; 04239 } 04240 04241 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04242 i = ao2_iterator_init(users, 0); 04243 for (user = ao2_iterator_next(&i); user; 04244 user_unref(user), user = ao2_iterator_next(&i)) { 04245 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04246 continue; 04247 04248 if (!ast_strlen_zero(user->secret)) { 04249 ast_copy_string(auth,user->secret,sizeof(auth)); 04250 } else if (!ast_strlen_zero(user->inkeys)) { 04251 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04252 } else 04253 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04254 04255 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04256 pstr = "REQ Only"; 04257 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04258 pstr = "Disabled"; 04259 else 04260 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04261 04262 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04263 user->contexts ? user->contexts->context : context, 04264 user->ha ? "Yes" : "No", pstr); 04265 } 04266 04267 if (havepattern) 04268 regfree(®exbuf); 04269 04270 return RESULT_SUCCESS; 04271 #undef FORMAT 04272 #undef FORMAT2 04273 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3237 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.
03238 { 03239 int res; 03240 struct iax_ie_data ied0; 03241 struct iax_ie_data ied1; 03242 unsigned int transferid = (unsigned int)ast_random(); 03243 memset(&ied0, 0, sizeof(ied0)); 03244 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03245 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03246 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03247 03248 memset(&ied1, 0, sizeof(ied1)); 03249 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03250 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03251 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03252 03253 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03254 if (res) 03255 return -1; 03256 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03257 if (res) 03258 return -1; 03259 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03260 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03261 return 0; 03262 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2147 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02148 { 02149 if (argc != 4) 02150 return RESULT_SHOWUSAGE; 02151 02152 test_losspct = atoi(argv[3]); 02153 02154 return RESULT_SUCCESS; 02155 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3472 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.
03473 { 03474 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03475 struct iax_ie_data ied; 03476 char tmp[256], *context; 03477 ast_copy_string(tmp, dest, sizeof(tmp)); 03478 context = strchr(tmp, '@'); 03479 if (context) { 03480 *context = '\0'; 03481 context++; 03482 } 03483 memset(&ied, 0, sizeof(ied)); 03484 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03485 if (context) 03486 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03487 if (option_debug) 03488 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03489 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03490 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2614 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().
02615 { 02616 /* Lock the queue and place this packet at the end */ 02617 /* By setting this to 0, the network thread will send it for us, and 02618 queue retransmission if necessary */ 02619 fr->sentyet = 0; 02620 AST_LIST_LOCK(&iaxq.queue); 02621 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02622 iaxq.count++; 02623 AST_LIST_UNLOCK(&iaxq.queue); 02624 /* Wake up the network and scheduler thread */ 02625 if (netthreadid != AST_PTHREADT_NULL) 02626 pthread_kill(netthreadid, SIGURG); 02627 signal_condition(&sched_lock, &sched_cond); 02628 return 0; 02629 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6246 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06247 { 06248 /* Drop when trunk is about 5 seconds idle */ 06249 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06250 return 1; 06251 return 0; 06252 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3815 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, 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().
03816 { 03817 struct ast_frame *f; 03818 struct iax2_trunk_peer *tpeer; 03819 void *tmp, *ptr; 03820 struct ast_iax2_meta_trunk_entry *met; 03821 struct ast_iax2_meta_trunk_mini *mtm; 03822 03823 f = &fr->af; 03824 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03825 if (tpeer) { 03826 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03827 /* Need to reallocate space */ 03828 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03829 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03830 ast_mutex_unlock(&tpeer->lock); 03831 return -1; 03832 } 03833 03834 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03835 tpeer->trunkdata = tmp; 03836 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); 03837 } else { 03838 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)); 03839 ast_mutex_unlock(&tpeer->lock); 03840 return -1; 03841 } 03842 } 03843 03844 /* Append to meta frame */ 03845 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03846 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03847 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03848 mtm->len = htons(f->datalen); 03849 mtm->mini.callno = htons(pvt->callno); 03850 mtm->mini.ts = htons(0xffff & fr->ts); 03851 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03852 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03853 } else { 03854 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03855 /* Store call number and length in meta header */ 03856 met->callno = htons(pvt->callno); 03857 met->len = htons(f->datalen); 03858 /* Advance pointers/decrease length past trunk entry header */ 03859 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03860 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03861 } 03862 /* Copy actual trunk data */ 03863 memcpy(ptr, f->data, f->datalen); 03864 tpeer->trunkdatalen += f->datalen; 03865 03866 tpeer->calls++; 03867 ast_mutex_unlock(&tpeer->lock); 03868 } 03869 return 0; 03870 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6165 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06166 { 06167 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06168 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4746 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, error(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04747 { 04748 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04749 int res = -1; 04750 ast_mutex_lock(&iaxsl[callno]); 04751 if (iaxs[callno]) { 04752 /* If there's an outstanding error, return failure now */ 04753 if (!iaxs[callno]->error) { 04754 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04755 res = 0; 04756 /* Don't waste bandwidth sending null frames */ 04757 else if (f->frametype == AST_FRAME_NULL) 04758 res = 0; 04759 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04760 res = 0; 04761 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04762 res = 0; 04763 else 04764 /* Simple, just queue for transmission */ 04765 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04766 } else { 04767 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04768 } 04769 } 04770 /* If it's already gone, just return */ 04771 ast_mutex_unlock(&iaxsl[callno]); 04772 return res; 04773 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1668 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().
01669 { 01670 int res = 0; 01671 struct iax_firmware *cur; 01672 if (!ast_strlen_zero(dev)) { 01673 ast_mutex_lock(&waresl.lock); 01674 cur = waresl.wares; 01675 while(cur) { 01676 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01677 res = ntohs(cur->fwh->version); 01678 break; 01679 } 01680 cur = cur->next; 01681 } 01682 ast_mutex_unlock(&waresl.lock); 01683 } 01684 return res; 01685 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 762 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00763 { 00764 if (iaxdebug) 00765 ast_verbose("%s", data); 00766 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 768 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00769 { 00770 ast_log(LOG_WARNING, "%s", data); 00771 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1687 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().
01688 { 01689 int res = -1; 01690 unsigned int bs = desc & 0xff; 01691 unsigned int start = (desc >> 8) & 0xffffff; 01692 unsigned int bytes; 01693 struct iax_firmware *cur; 01694 if (!ast_strlen_zero((char *)dev) && bs) { 01695 start *= bs; 01696 ast_mutex_lock(&waresl.lock); 01697 cur = waresl.wares; 01698 while(cur) { 01699 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01700 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01701 if (start < ntohl(cur->fwh->datalen)) { 01702 bytes = ntohl(cur->fwh->datalen) - start; 01703 if (bytes > bs) 01704 bytes = bs; 01705 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01706 } else { 01707 bytes = 0; 01708 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01709 } 01710 if (bytes == bs) 01711 res = 0; 01712 else 01713 res = 1; 01714 break; 01715 } 01716 cur = cur->next; 01717 } 01718 ast_mutex_unlock(&waresl.lock); 01719 } 01720 return res; 01721 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6428 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().
06429 { 06430 struct iax_dual *d; 06431 struct ast_channel *chan1m, *chan2m; 06432 pthread_t th; 06433 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06434 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06435 if (chan2m && chan1m) { 06436 /* Make formats okay */ 06437 chan1m->readformat = chan1->readformat; 06438 chan1m->writeformat = chan1->writeformat; 06439 ast_channel_masquerade(chan1m, chan1); 06440 /* Setup the extensions and such */ 06441 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06442 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06443 chan1m->priority = chan1->priority; 06444 06445 /* We make a clone of the peer channel too, so we can play 06446 back the announcement */ 06447 /* Make formats okay */ 06448 chan2m->readformat = chan2->readformat; 06449 chan2m->writeformat = chan2->writeformat; 06450 ast_channel_masquerade(chan2m, chan2); 06451 /* Setup the extensions and such */ 06452 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06453 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06454 chan2m->priority = chan2->priority; 06455 if (ast_do_masquerade(chan2m)) { 06456 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06457 ast_hangup(chan2m); 06458 return -1; 06459 } 06460 } else { 06461 if (chan1m) 06462 ast_hangup(chan1m); 06463 if (chan2m) 06464 ast_hangup(chan2m); 06465 return -1; 06466 } 06467 if ((d = ast_calloc(1, sizeof(*d)))) { 06468 pthread_attr_t attr; 06469 06470 pthread_attr_init(&attr); 06471 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06472 06473 d->chan1 = chan1m; 06474 d->chan2 = chan2m; 06475 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06476 pthread_attr_destroy(&attr); 06477 return 0; 06478 } 06479 pthread_attr_destroy(&attr); 06480 free(d); 06481 } 06482 return -1; 06483 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6408 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().
06409 { 06410 struct ast_channel *chan1, *chan2; 06411 struct iax_dual *d; 06412 struct ast_frame *f; 06413 int ext; 06414 int res; 06415 d = stuff; 06416 chan1 = d->chan1; 06417 chan2 = d->chan2; 06418 free(d); 06419 f = ast_read(chan1); 06420 if (f) 06421 ast_frfree(f); 06422 res = ast_park_call(chan1, chan2, 0, &ext); 06423 ast_hangup(chan2); 06424 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06425 return NULL; 06426 }
Definition at line 1209 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().
01210 { 01211 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01212 if (new) { 01213 size_t afdatalen = new->afdatalen; 01214 memcpy(new, fr, sizeof(*new)); 01215 iax_frame_wrap(new, &fr->af); 01216 new->afdatalen = afdatalen; 01217 new->data = NULL; 01218 new->datalen = 0; 01219 new->direction = DIRECTION_INGRESS; 01220 new->retrans = -1; 01221 } 01222 return new; 01223 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 874 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().
00875 { 00876 if (thread->type == IAX_TYPE_DYNAMIC) { 00877 AST_LIST_LOCK(&dynamic_list); 00878 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00879 AST_LIST_UNLOCK(&dynamic_list); 00880 } else { 00881 AST_LIST_LOCK(&idle_list); 00882 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00883 AST_LIST_UNLOCK(&idle_list); 00884 } 00885 00886 return; 00887 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 797 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00798 { 00799 va_list args; 00800 char buf[1024]; 00801 00802 va_start(args, fmt); 00803 vsnprintf(buf, 1024, fmt, args); 00804 va_end(args); 00805 00806 ast_verbose(buf); 00807 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 773 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00774 { 00775 va_list args; 00776 char buf[1024]; 00777 00778 va_start(args, fmt); 00779 vsnprintf(buf, 1024, fmt, args); 00780 va_end(args); 00781 00782 ast_log(LOG_ERROR, buf); 00783 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 785 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00786 { 00787 va_list args; 00788 char buf[1024]; 00789 00790 va_start(args, fmt); 00791 vsnprintf(buf, 1024, fmt, args); 00792 va_end(args); 00793 00794 ast_log(LOG_WARNING, buf); 00795 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 10670 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, 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, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
10671 { 10672 char *config = "iax.conf"; 10673 int res = 0; 10674 int x; 10675 struct iax2_registry *reg = NULL; 10676 10677 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 10678 if (!peers) 10679 return AST_MODULE_LOAD_FAILURE; 10680 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 10681 if (!users) { 10682 ao2_ref(peers, -1); 10683 return AST_MODULE_LOAD_FAILURE; 10684 } 10685 10686 ast_custom_function_register(&iaxpeer_function); 10687 10688 iax_set_output(iax_debug_output); 10689 iax_set_error(iax_error_output); 10690 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10691 10692 #ifdef HAVE_ZAPTEL 10693 #ifdef ZT_TIMERACK 10694 timingfd = open("/dev/zap/timer", O_RDWR); 10695 if (timingfd < 0) 10696 #endif 10697 timingfd = open("/dev/zap/pseudo", O_RDWR); 10698 if (timingfd < 0) 10699 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10700 #endif 10701 10702 memset(iaxs, 0, sizeof(iaxs)); 10703 10704 for (x=0;x<IAX_MAX_CALLS;x++) 10705 ast_mutex_init(&iaxsl[x]); 10706 10707 ast_cond_init(&sched_cond, NULL); 10708 10709 io = io_context_create(); 10710 sched = sched_context_create(); 10711 10712 if (!io || !sched) { 10713 ast_log(LOG_ERROR, "Out of memory\n"); 10714 return -1; 10715 } 10716 10717 netsock = ast_netsock_list_alloc(); 10718 if (!netsock) { 10719 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10720 return -1; 10721 } 10722 ast_netsock_init(netsock); 10723 10724 outsock = ast_netsock_list_alloc(); 10725 if (!outsock) { 10726 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10727 return -1; 10728 } 10729 ast_netsock_init(outsock); 10730 10731 ast_mutex_init(&waresl.lock); 10732 10733 AST_LIST_HEAD_INIT(&iaxq.queue); 10734 10735 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10736 10737 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10738 10739 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10740 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10741 10742 if(set_config(config, 0) == -1) 10743 return AST_MODULE_LOAD_DECLINE; 10744 10745 if (ast_channel_register(&iax2_tech)) { 10746 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10747 __unload_module(); 10748 return -1; 10749 } 10750 10751 if (ast_register_switch(&iax2_switch)) 10752 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10753 10754 res = start_network_thread(); 10755 if (!res) { 10756 if (option_verbose > 1) 10757 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10758 } else { 10759 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10760 ast_netsock_release(netsock); 10761 ast_netsock_release(outsock); 10762 } 10763 10764 AST_LIST_LOCK(®istrations); 10765 AST_LIST_TRAVERSE(®istrations, reg, entry) 10766 iax2_do_register(reg); 10767 AST_LIST_UNLOCK(®istrations); 10768 10769 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 10770 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 10771 10772 reload_firmware(); 10773 iax_provision_reload(); 10774 return res; 10775 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3264 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03265 { 03266 ast_mutex_lock(&iaxsl[callno0]); 03267 while (ast_mutex_trylock(&iaxsl[callno1])) { 03268 ast_mutex_unlock(&iaxsl[callno0]); 03269 usleep(10); 03270 ast_mutex_lock(&iaxsl[callno0]); 03271 } 03272 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1277 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), and TRUNK_CALL_START.
Referenced by iax2_request(), and socket_process().
01278 { 01279 int x; 01280 int res= 0; 01281 struct timeval now; 01282 if (iaxs[callno]->oseqno) { 01283 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01284 return -1; 01285 } 01286 if (callno & TRUNK_CALL_START) { 01287 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01288 return -1; 01289 } 01290 gettimeofday(&now, NULL); 01291 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01292 ast_mutex_lock(&iaxsl[x]); 01293 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01294 iaxs[x] = iaxs[callno]; 01295 iaxs[x]->callno = x; 01296 iaxs[callno] = NULL; 01297 /* Update the two timers that should have been started */ 01298 if (iaxs[x]->pingid > -1) 01299 ast_sched_del(sched, iaxs[x]->pingid); 01300 if (iaxs[x]->lagid > -1) 01301 ast_sched_del(sched, iaxs[x]->lagid); 01302 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01303 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01304 if (locked) 01305 ast_mutex_unlock(&iaxsl[callno]); 01306 res = x; 01307 if (!locked) 01308 ast_mutex_unlock(&iaxsl[x]); 01309 break; 01310 } 01311 ast_mutex_unlock(&iaxsl[x]); 01312 } 01313 if (x >= IAX_MAX_CALLS - 1) { 01314 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01315 return -1; 01316 } 01317 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01318 /* We move this call from a non-trunked to a trunked call */ 01319 update_max_trunk(); 01320 update_max_nontrunk(); 01321 return res; 01322 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4460 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04461 { 04462 ast_cli_netstats(s, -1, 0); 04463 astman_append(s, "\r\n"); 04464 return RESULT_SUCCESS; 04465 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4493 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04494 { 04495 char *a[] = { "iax2", "show", "users" }; 04496 int ret; 04497 const char *id = astman_get_header(m,"ActionID"); 04498 04499 if (!ast_strlen_zero(id)) 04500 astman_append(s, "ActionID: %s\r\n",id); 04501 ret = __iax2_show_peers(1, -1, s, 3, a ); 04502 astman_append(s, "\r\n\r\n" ); 04503 return ret; 04504 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur | |||
) | [static] |
Definition at line 1229 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 ao2_callback(), ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01230 { 01231 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01232 (cur->addr.sin_port == sin->sin_port)) { 01233 /* This is the main host */ 01234 if ((cur->peercallno == callno) || 01235 ((dcallno == cur->callno) && !cur->peercallno)) { 01236 /* That's us. Be sure we keep track of the peer call number */ 01237 return 1; 01238 } 01239 } 01240 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01241 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01242 /* We're transferring */ 01243 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01244 return 1; 01245 } 01246 return 0; 01247 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3878 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03879 { 03880 #if 0 03881 /* Debug with "fake encryption" */ 03882 int x; 03883 if (len % 16) 03884 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03885 for (x=0;x<len;x++) 03886 dst[x] = src[x] ^ 0xff; 03887 #else 03888 unsigned char lastblock[16] = { 0 }; 03889 int x; 03890 while(len > 0) { 03891 aes_decrypt(src, dst, dcx); 03892 for (x=0;x<16;x++) 03893 dst[x] ^= lastblock[x]; 03894 memcpy(lastblock, src, sizeof(lastblock)); 03895 dst += 16; 03896 src += 16; 03897 len -= 16; 03898 } 03899 #endif 03900 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3902 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03903 { 03904 #if 0 03905 /* Debug with "fake encryption" */ 03906 int x; 03907 if (len % 16) 03908 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03909 for (x=0;x<len;x++) 03910 dst[x] = src[x] ^ 0xff; 03911 #else 03912 unsigned char curblock[16] = { 0 }; 03913 int x; 03914 while(len > 0) { 03915 for (x=0;x<16;x++) 03916 curblock[x] ^= src[x]; 03917 aes_encrypt(curblock, dst, ecx); 03918 memcpy(curblock, dst, sizeof(curblock)); 03919 dst += 16; 03920 src += 16; 03921 len -= 16; 03922 } 03923 #endif 03924 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5072 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05073 { 05074 /* Select exactly one common encryption if there are any */ 05075 p->encmethods &= enc; 05076 if (p->encmethods) { 05077 if (p->encmethods & IAX_ENCRYPT_AES128) 05078 p->encmethods = IAX_ENCRYPT_AES128; 05079 else 05080 p->encmethods = 0; 05081 } 05082 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8684 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(), ast_sched_add(), attempt_transmit(), f, iax_frame_free(), iaxq, iaxs, iaxsl, io, sched, send_packet(), signal_condition(), and timing_read().
Referenced by start_network_thread().
08685 { 08686 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08687 from the network, and queue them for delivery to the channels */ 08688 int res, count, wakeup; 08689 struct iax_frame *f; 08690 08691 if (timingfd > -1) 08692 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08693 08694 for(;;) { 08695 pthread_testcancel(); 08696 08697 /* Go through the queue, sending messages which have not yet been 08698 sent, and scheduling retransmissions if appropriate */ 08699 AST_LIST_LOCK(&iaxq.queue); 08700 count = 0; 08701 wakeup = -1; 08702 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08703 if (f->sentyet) 08704 continue; 08705 08706 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08707 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08708 wakeup = 1; 08709 continue; 08710 } 08711 08712 f->sentyet++; 08713 08714 if (iaxs[f->callno]) { 08715 send_packet(f); 08716 count++; 08717 } 08718 08719 ast_mutex_unlock(&iaxsl[f->callno]); 08720 08721 if (f->retries < 0) { 08722 /* This is not supposed to be retransmitted */ 08723 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 08724 iaxq.count--; 08725 /* Free the iax frame */ 08726 iax_frame_free(f); 08727 } else { 08728 /* We need reliable delivery. Schedule a retransmission */ 08729 f->retries++; 08730 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 08731 signal_condition(&sched_lock, &sched_cond); 08732 } 08733 } 08734 AST_LIST_TRAVERSE_SAFE_END 08735 AST_LIST_UNLOCK(&iaxq.queue); 08736 08737 pthread_testcancel(); 08738 08739 if (count >= 20) 08740 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08741 08742 /* Now do the IO, and run scheduled tasks */ 08743 res = ast_io_wait(io, wakeup); 08744 if (res >= 0) { 08745 if (res >= 20) 08746 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08747 } 08748 } 08749 return NULL; 08750 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1171 of file chan_iax2.c.
References ast_calloc, ast_string_field_init, ast_string_field_set, exten, free, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, and jb_conf::resync_threshold.
Referenced by find_callno().
01172 { 01173 struct chan_iax2_pvt *tmp; 01174 jb_conf jbconf; 01175 01176 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01177 return NULL; 01178 01179 if (ast_string_field_init(tmp, 32)) { 01180 free(tmp); 01181 tmp = NULL; 01182 return NULL; 01183 } 01184 01185 tmp->prefs = prefs; 01186 tmp->callno = 0; 01187 tmp->peercallno = 0; 01188 tmp->transfercallno = 0; 01189 tmp->bridgecallno = 0; 01190 tmp->pingid = -1; 01191 tmp->lagid = -1; 01192 tmp->autoid = -1; 01193 tmp->authid = -1; 01194 tmp->initid = -1; 01195 01196 ast_string_field_set(tmp,exten, "s"); 01197 ast_string_field_set(tmp,host, host); 01198 01199 tmp->jb = jb_new(); 01200 tmp->jbid = -1; 01201 jbconf.max_jitterbuf = maxjitterbuffer; 01202 jbconf.resync_threshold = resyncthreshold; 01203 jbconf.max_contig_interp = maxjitterinterps; 01204 jb_setconf(tmp->jb,&jbconf); 01205 01206 return tmp; 01207 }
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 2991 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().
02992 { 02993 if (ast_strlen_zero(data)) 02994 return; 02995 02996 pds->peer = strsep(&data, "/"); 02997 pds->exten = strsep(&data, "/"); 02998 pds->options = data; 02999 03000 if (pds->exten) { 03001 data = pds->exten; 03002 pds->exten = strsep(&data, "@"); 03003 pds->context = data; 03004 } 03005 03006 if (strchr(pds->peer, '@')) { 03007 data = pds->peer; 03008 pds->username = strsep(&data, "@"); 03009 pds->peer = data; 03010 } 03011 03012 if (pds->username) { 03013 data = pds->username; 03014 pds->username = strsep(&data, ":"); 03015 pds->password = data; 03016 } 03017 03018 data = pds->peer; 03019 pds->peer = strsep(&data, ":"); 03020 pds->port = data; 03021 03022 /* check for a key name wrapped in [] in the secret position, if found, 03023 move it to the key field instead 03024 */ 03025 if (pds->password && (pds->password[0] == '[')) { 03026 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03027 pds->password = NULL; 03028 } 03029 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1070 of file chan_iax2.c.
Referenced by load_module().
01071 { 01072 struct iax2_peer *peer = obj, *peer2 = arg; 01073 01074 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01075 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9392 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09393 { 09394 struct iax2_peer *peer = obj; 09395 09396 ast_set_flag(peer, IAX_DELME); 09397 09398 return 0; 09399 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 8906 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_string_field_free_pools, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::expire, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::pokeexpire, register_peer_exten(), and sched.
Referenced by build_peer().
08907 { 08908 struct iax2_peer *peer = obj; 08909 08910 ast_free_ha(peer->ha); 08911 08912 /* Delete it, it needs to disappear */ 08913 if (peer->expire > -1) 08914 ast_sched_del(sched, peer->expire); 08915 if (peer->pokeexpire > -1) 08916 ast_sched_del(sched, peer->pokeexpire); 08917 if (peer->callno > 0) { 08918 ast_mutex_lock(&iaxsl[peer->callno]); 08919 iax2_destroy(peer->callno); 08920 ast_mutex_unlock(&iaxsl[peer->callno]); 08921 } 08922 08923 register_peer_exten(peer, 0); 08924 08925 if (peer->dnsmgr) 08926 ast_dnsmgr_release(peer->dnsmgr); 08927 08928 ast_string_field_free_pools(peer); 08929 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1060 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01061 { 01062 const struct iax2_peer *peer = obj; 01063 01064 return ast_str_hash(peer->name); 01065 }
Definition at line 1117 of file chan_iax2.c.
References ao2_ref().
01118 { 01119 ao2_ref(peer, +1); 01120 return peer; 01121 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10659 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
10660 { 10661 struct iax2_peer *peer = obj; 10662 10663 if (peer->sockfd < 0) 10664 peer->sockfd = defaultsockfd; 10665 10666 return 0; 10667 }
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 8834 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, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
08835 { 08836 struct sockaddr_in sin; 08837 int nonlocal = 1; 08838 int port = IAX_DEFAULT_PORTNO; 08839 int sockfd = defaultsockfd; 08840 char *tmp; 08841 char *addr; 08842 char *portstr; 08843 08844 if (!(tmp = ast_strdupa(srcaddr))) 08845 return -1; 08846 08847 addr = strsep(&tmp, ":"); 08848 portstr = tmp; 08849 08850 if (portstr) { 08851 port = atoi(portstr); 08852 if (port < 1) 08853 port = IAX_DEFAULT_PORTNO; 08854 } 08855 08856 if (!ast_get_ip(&sin, addr)) { 08857 struct ast_netsock *sock; 08858 int res; 08859 08860 sin.sin_port = 0; 08861 sin.sin_family = AF_INET; 08862 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08863 if (res == 0) { 08864 /* ip address valid. */ 08865 sin.sin_port = htons(port); 08866 if (!(sock = ast_netsock_find(netsock, &sin))) 08867 sock = ast_netsock_find(outsock, &sin); 08868 if (sock) { 08869 sockfd = ast_netsock_sockfd(sock); 08870 nonlocal = 0; 08871 } else { 08872 unsigned int orig_saddr = sin.sin_addr.s_addr; 08873 /* INADDR_ANY matches anyway! */ 08874 sin.sin_addr.s_addr = INADDR_ANY; 08875 if (ast_netsock_find(netsock, &sin)) { 08876 sin.sin_addr.s_addr = orig_saddr; 08877 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 08878 if (sock) { 08879 sockfd = ast_netsock_sockfd(sock); 08880 ast_netsock_unref(sock); 08881 nonlocal = 0; 08882 } else { 08883 nonlocal = 2; 08884 } 08885 } 08886 } 08887 } 08888 } 08889 08890 peer->sockfd = sockfd; 08891 08892 if (nonlocal == 1) { 08893 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08894 srcaddr, peer->name); 08895 return -1; 08896 } else if (nonlocal == 2) { 08897 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 08898 srcaddr, peer->name); 08899 return -1; 08900 } else { 08901 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08902 return 0; 08903 } 08904 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2193 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().
02194 { 02195 int res = 0; 02196 if (peer->maxms) { 02197 if (peer->lastms < 0) { 02198 ast_copy_string(status, "UNREACHABLE", statuslen); 02199 } else if (peer->lastms > peer->maxms) { 02200 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02201 res = 1; 02202 } else if (peer->lastms) { 02203 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02204 res = 1; 02205 } else { 02206 ast_copy_string(status, "UNKNOWN", statuslen); 02207 } 02208 } else { 02209 ast_copy_string(status, "Unmonitored", statuslen); 02210 res = -1; 02211 } 02212 return res; 02213 }
Definition at line 1123 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_prune_realtime(), iax2_show_peer(), prune_peers(), realtime_peer(), registry_authrequest(), and update_registry().
01124 { 01125 ao2_ref(peer, -1); 01126 return NULL; 01127 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9451 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, peer_unref(), and peers.
09452 { 09453 struct iax2_peer *peer; 09454 ao2_iterator i; 09455 09456 i = ao2_iterator_init(peers, 0); 09457 while ((peer = ao2_iterator_next(&i))) { 09458 if (ast_test_flag(peer, IAX_DELME)) 09459 ao2_unlink(peers, peer); 09460 peer_unref(peer); 09461 } 09462 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9437 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().
09438 { 09439 struct iax2_user *user; 09440 ao2_iterator i; 09441 09442 i = ao2_iterator_init(users, 0); 09443 while ((user = ao2_iterator_next(&i))) { 09444 if (ast_test_flag(user, IAX_DELME)) 09445 ao2_unlink(users, user); 09446 user_unref(user); 09447 } 09448 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5052 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().
05053 { 05054 struct ast_iax2_full_hdr fh; 05055 fh.scallno = htons(src | IAX_FLAG_FULL); 05056 fh.dcallno = htons(dst); 05057 fh.ts = 0; 05058 fh.oseqno = 0; 05059 fh.iseqno = 0; 05060 fh.type = AST_FRAME_IAX; 05061 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05062 if (iaxdebug) 05063 iax_showframe(NULL, &fh, 0, sin, 0); 05064 #if 0 05065 if (option_debug) 05066 #endif 05067 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05068 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05069 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05070 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2676 of file chan_iax2.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_test_flag, ast_variables_destroy(), build_peer(), globalflags, IAX_RTCACHEFRIENDS, ast_variable::name, ast_variable::next, peer_unref(), ast_variable::value, and var.
02677 { 02678 struct ast_variable *var; 02679 struct ast_variable *tmp; 02680 struct iax2_peer *peer=NULL; 02681 time_t regseconds = 0, nowtime; 02682 int dynamic=0; 02683 02684 if (peername) 02685 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02686 else { 02687 char porta[25]; 02688 sprintf(porta, "%d", ntohs(sin->sin_port)); 02689 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02690 if (var) { 02691 /* We'll need the peer name in order to build the structure! */ 02692 for (tmp = var; tmp; tmp = tmp->next) { 02693 if (!strcasecmp(tmp->name, "name")) 02694 peername = tmp->value; 02695 } 02696 } 02697 } 02698 if (!var) 02699 return NULL; 02700 02701 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02702 02703 if (!peer) { 02704 ast_variables_destroy(var); 02705 return NULL; 02706 } 02707 02708 for (tmp = var; tmp; tmp = tmp->next) { 02709 /* Make sure it's not a user only... */ 02710 if (!strcasecmp(tmp->name, "type")) { 02711 if (strcasecmp(tmp->value, "friend") && 02712 strcasecmp(tmp->value, "peer")) { 02713 /* Whoops, we weren't supposed to exist! */ 02714 peer = peer_unref(peer); 02715 break; 02716 } 02717 } else if (!strcasecmp(tmp->name, "regseconds")) { 02718 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02719 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02720 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02721 } else if (!strcasecmp(tmp->name, "port")) { 02722 peer->addr.sin_port = htons(atoi(tmp->value)); 02723 } else if (!strcasecmp(tmp->name, "host")) { 02724 if (!strcasecmp(tmp->value, "dynamic")) 02725 dynamic = 1; 02726 } 02727 } 02728 02729 ast_variables_destroy(var); 02730 02731 if (!peer) 02732 return NULL; 02733 02734 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02735 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02736 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02737 if (peer->expire > -1) 02738 ast_sched_del(sched, peer->expire); 02739 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name); 02740 } 02741 ao2_link(peers, peer_ref(peer)); 02742 if (ast_test_flag(peer, IAX_DYNAMIC)) 02743 reg_source_db(peer); 02744 } else { 02745 ast_set_flag(peer, IAX_TEMPONLY); 02746 } 02747 02748 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02749 time(&nowtime); 02750 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02751 memset(&peer->addr, 0, sizeof(peer->addr)); 02752 realtime_update_peer(peer->name, &peer->addr, 0); 02753 if (option_debug) 02754 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02755 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02756 } 02757 else { 02758 if (option_debug) 02759 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02760 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02761 } 02762 } 02763 02764 return peer; 02765 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2806 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02807 { 02808 char port[10]; 02809 char regseconds[20]; 02810 02811 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02812 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02813 ast_update_realtime("iaxpeers", "name", peername, 02814 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02815 "regseconds", regseconds, NULL); 02816 }
static struct iax2_user* realtime_user | ( | const char * | username | ) | [static] |
Definition at line 2767 of file chan_iax2.c.
References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), globalflags, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, user_ref(), users, ast_variable::value, and var.
02768 { 02769 struct ast_variable *var; 02770 struct ast_variable *tmp; 02771 struct iax2_user *user=NULL; 02772 02773 var = ast_load_realtime("iaxusers", "name", username, NULL); 02774 if (!var) 02775 return NULL; 02776 02777 tmp = var; 02778 while(tmp) { 02779 /* Make sure it's not a peer only... */ 02780 if (!strcasecmp(tmp->name, "type")) { 02781 if (strcasecmp(tmp->value, "friend") && 02782 strcasecmp(tmp->value, "user")) { 02783 return NULL; 02784 } 02785 } 02786 tmp = tmp->next; 02787 } 02788 02789 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02790 02791 ast_variables_destroy(var); 02792 02793 if (!user) 02794 return NULL; 02795 02796 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02797 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02798 ao2_link(users, user_ref(user)); 02799 } else { 02800 ast_set_flag(user, IAX_TEMPONLY); 02801 } 02802 02803 return user; 02804 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5815 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, IAX_TEMPONLY, option_verbose, register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
05816 { 05817 char data[80]; 05818 struct in_addr in; 05819 char *c, *d; 05820 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05821 c = strchr(data, ':'); 05822 if (c) { 05823 *c = '\0'; 05824 c++; 05825 if (inet_aton(data, &in)) { 05826 d = strchr(c, ':'); 05827 if (d) { 05828 *d = '\0'; 05829 d++; 05830 if (option_verbose > 2) 05831 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05832 ast_inet_ntoa(in), atoi(c), atoi(d)); 05833 iax2_poke_peer(p, 0); 05834 p->expiry = atoi(d); 05835 memset(&p->addr, 0, sizeof(p->addr)); 05836 p->addr.sin_family = AF_INET; 05837 p->addr.sin_addr = in; 05838 p->addr.sin_port = htons(atoi(c)); 05839 if (p->expire > -1) 05840 ast_sched_del(sched, p->expire); 05841 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05842 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05843 if (iax2_regfunk) 05844 iax2_regfunk(p->name, 1); 05845 register_peer_exten(p, 1); 05846 } 05847 05848 } 05849 } 05850 } 05851 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5750 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().
05751 { 05752 char multi[256]; 05753 char *stringp, *ext; 05754 if (!ast_strlen_zero(regcontext)) { 05755 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05756 stringp = multi; 05757 while((ext = strsep(&stringp, "&"))) { 05758 if (onoff) { 05759 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05760 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05761 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05762 } else 05763 ast_context_remove_extension(regcontext, ext, 1, NULL); 05764 } 05765 } 05766 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5218 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(), key(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by handle_request_register(), and socket_process().
05219 { 05220 char requeststr[256] = ""; 05221 char peer[256] = ""; 05222 char md5secret[256] = ""; 05223 char rsasecret[256] = ""; 05224 char secret[256] = ""; 05225 struct iax2_peer *p = NULL; 05226 struct ast_key *key; 05227 char *keyn; 05228 int x; 05229 int expire = 0; 05230 int res = -1; 05231 05232 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05233 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05234 if (ies->username) 05235 ast_copy_string(peer, ies->username, sizeof(peer)); 05236 if (ies->password) 05237 ast_copy_string(secret, ies->password, sizeof(secret)); 05238 if (ies->md5_result) 05239 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05240 if (ies->rsa_result) 05241 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05242 if (ies->refresh) 05243 expire = ies->refresh; 05244 05245 if (ast_strlen_zero(peer)) { 05246 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05247 return -1; 05248 } 05249 05250 /* SLD: first call to lookup peer during registration */ 05251 ast_mutex_unlock(&iaxsl[callno]); 05252 p = find_peer(peer, 1); 05253 ast_mutex_lock(&iaxsl[callno]); 05254 if (!p || !iaxs[callno]) { 05255 if (authdebug && !p) 05256 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05257 goto return_unref; 05258 } 05259 05260 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05261 if (authdebug) 05262 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05263 goto return_unref; 05264 } 05265 05266 if (!ast_apply_ha(p->ha, sin)) { 05267 if (authdebug) 05268 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05269 goto return_unref; 05270 } 05271 if (!inaddrcmp(&p->addr, sin)) 05272 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05273 ast_string_field_set(iaxs[callno], secret, p->secret); 05274 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05275 /* Check secret against what we have on file */ 05276 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05277 if (!ast_strlen_zero(p->inkeys)) { 05278 char tmpkeys[256]; 05279 char *stringp=NULL; 05280 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05281 stringp=tmpkeys; 05282 keyn = strsep(&stringp, ":"); 05283 while(keyn) { 05284 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05285 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05286 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05287 break; 05288 } else if (!key) 05289 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05290 keyn = strsep(&stringp, ":"); 05291 } 05292 if (!keyn) { 05293 if (authdebug) 05294 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05295 goto return_unref; 05296 } 05297 } else { 05298 if (authdebug) 05299 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05300 goto return_unref; 05301 } 05302 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05303 struct MD5Context md5; 05304 unsigned char digest[16]; 05305 char *tmppw, *stringp; 05306 05307 tmppw = ast_strdupa(p->secret); 05308 stringp = tmppw; 05309 while((tmppw = strsep(&stringp, ";"))) { 05310 MD5Init(&md5); 05311 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05312 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05313 MD5Final(digest, &md5); 05314 for (x=0;x<16;x++) 05315 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05316 if (!strcasecmp(requeststr, md5secret)) 05317 break; 05318 } 05319 if (tmppw) { 05320 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05321 } else { 05322 if (authdebug) 05323 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05324 goto return_unref; 05325 } 05326 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05327 /* They've provided a plain text password and we support that */ 05328 if (strcmp(secret, p->secret)) { 05329 if (authdebug) 05330 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05331 goto return_unref; 05332 } else 05333 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05334 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05335 if (authdebug) 05336 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05337 goto return_unref; 05338 } 05339 ast_string_field_set(iaxs[callno], peer, peer); 05340 /* Choose lowest expiry number */ 05341 if (expire && (expire < iaxs[callno]->expiry)) 05342 iaxs[callno]->expiry = expire; 05343 05344 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05345 05346 res = 0; 05347 05348 return_unref: 05349 if (p) 05350 peer_unref(p); 05351 05352 return res; 05353 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 5981 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().
05982 { 05983 struct iax_ie_data ied; 05984 struct iax2_peer *p; 05985 char challenge[10]; 05986 const char *peer_name; 05987 int res = -1; 05988 05989 peer_name = ast_strdupa(iaxs[callno]->peer); 05990 05991 /* SLD: third call to find_peer in registration */ 05992 ast_mutex_unlock(&iaxsl[callno]); 05993 p = find_peer(peer_name, 1); 05994 ast_mutex_lock(&iaxsl[callno]); 05995 if (!iaxs[callno]) 05996 goto return_unref; 05997 if (!p) { 05998 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 05999 goto return_unref; 06000 } 06001 06002 memset(&ied, 0, sizeof(ied)); 06003 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 06004 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06005 /* Build the challenge */ 06006 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06007 ast_string_field_set(iaxs[callno], challenge, challenge); 06008 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06009 } 06010 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06011 06012 res = 0; 06013 06014 return_unref: 06015 peer_unref(p); 06016 06017 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 06018 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6020 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().
06021 { 06022 struct iax2_registry *reg; 06023 /* Start pessimistic */ 06024 struct iax_ie_data ied; 06025 char peer[256] = ""; 06026 char challenge[256] = ""; 06027 int res; 06028 int authmethods = 0; 06029 if (ies->authmethods) 06030 authmethods = ies->authmethods; 06031 if (ies->username) 06032 ast_copy_string(peer, ies->username, sizeof(peer)); 06033 if (ies->challenge) 06034 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06035 memset(&ied, 0, sizeof(ied)); 06036 reg = iaxs[callno]->reg; 06037 if (reg) { 06038 if (inaddrcmp(®->addr, sin)) { 06039 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06040 return -1; 06041 } 06042 if (ast_strlen_zero(reg->secret)) { 06043 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06044 reg->regstate = REG_STATE_NOAUTH; 06045 return -1; 06046 } 06047 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06048 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06049 if (reg->secret[0] == '[') { 06050 char tmpkey[256]; 06051 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06052 tmpkey[strlen(tmpkey) - 1] = '\0'; 06053 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06054 } else 06055 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06056 if (!res) { 06057 reg->regstate = REG_STATE_AUTHSENT; 06058 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06059 } else 06060 return -1; 06061 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06062 } else 06063 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06064 return -1; 06065 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4506 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().
04507 { 04508 switch(regstate) { 04509 case REG_STATE_UNREGISTERED: 04510 return "Unregistered"; 04511 case REG_STATE_REGSENT: 04512 return "Request Sent"; 04513 case REG_STATE_AUTHSENT: 04514 return "Auth. Sent"; 04515 case REG_STATE_REGISTERED: 04516 return "Registered"; 04517 case REG_STATE_REJECTED: 04518 return "Rejected"; 04519 case REG_STATE_TIMEOUT: 04520 return "Timeout"; 04521 case REG_STATE_NOAUTH: 04522 return "No Authentication"; 04523 default: 04524 return "Unknown"; 04525 } 04526 }
static int reload | ( | void | ) | [static] |
Definition at line 9870 of file chan_iax2.c.
References reload_config().
09871 { 09872 return reload_config(); 09873 }
static int reload_config | ( | void | ) | [static] |
Definition at line 9834 of file chan_iax2.c.
References ao2_callback(), ast_clear_flag, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, delete_users(), globalflags, iax2_do_register(), iax2_poke_peer_cb(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_provision_reload(), IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, peers, prune_peers(), prune_users(), reload_firmware(), and set_config().
09835 { 09836 char *config = "iax.conf"; 09837 struct iax2_registry *reg; 09838 09839 strcpy(accountcode, ""); 09840 strcpy(language, ""); 09841 strcpy(mohinterpret, "default"); 09842 strcpy(mohsuggest, ""); 09843 amaflags = 0; 09844 delayreject = 0; 09845 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09846 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09847 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09848 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09849 delete_users(); 09850 set_config(config, 1); 09851 prune_peers(); 09852 prune_users(); 09853 AST_LIST_LOCK(®istrations); 09854 AST_LIST_TRAVERSE(®istrations, reg, entry) 09855 iax2_do_register(reg); 09856 AST_LIST_UNLOCK(®istrations); 09857 /* Qualify hosts, too */ 09858 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 09859 reload_firmware(); 09860 iax_provision_reload(); 09861 09862 return 0; 09863 }
static void reload_firmware | ( | void | ) | [static] |
Definition at line 1724 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(), ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by load_module(), and reload_config().
01725 { 01726 struct iax_firmware *cur, *curl, *curp; 01727 DIR *fwd; 01728 struct dirent *de; 01729 char dir[256]; 01730 char fn[256]; 01731 /* Mark all as dead */ 01732 ast_mutex_lock(&waresl.lock); 01733 cur = waresl.wares; 01734 while(cur) { 01735 cur->dead = 1; 01736 cur = cur->next; 01737 } 01738 /* Now that we've freed them, load the new ones */ 01739 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01740 fwd = opendir(dir); 01741 if (fwd) { 01742 while((de = readdir(fwd))) { 01743 if (de->d_name[0] != '.') { 01744 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01745 if (!try_firmware(fn)) { 01746 if (option_verbose > 1) 01747 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01748 } 01749 } 01750 } 01751 closedir(fwd); 01752 } else 01753 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01754 01755 /* Clean up leftovers */ 01756 cur = waresl.wares; 01757 curp = NULL; 01758 while(cur) { 01759 curl = cur; 01760 cur = cur->next; 01761 if (curl->dead) { 01762 if (curp) { 01763 curp->next = cur; 01764 } else { 01765 waresl.wares = cur; 01766 } 01767 destroy_firmware(curl); 01768 } else { 01769 curp = cur; 01770 } 01771 } 01772 ast_mutex_unlock(&waresl.lock); 01773 }
Definition at line 6518 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().
06519 { 06520 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06521 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06522 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06523 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06524 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06525 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06526 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06527 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8656 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(), and sched.
Referenced by start_network_thread().
08657 { 08658 int count; 08659 int res; 08660 struct timeval tv; 08661 struct timespec ts; 08662 08663 for (;;) { 08664 res = ast_sched_wait(sched); 08665 if ((res > 1000) || (res < 0)) 08666 res = 1000; 08667 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08668 ts.tv_sec = tv.tv_sec; 08669 ts.tv_nsec = tv.tv_usec * 1000; 08670 08671 pthread_testcancel(); 08672 ast_mutex_lock(&sched_lock); 08673 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08674 ast_mutex_unlock(&sched_lock); 08675 pthread_testcancel(); 08676 08677 count = ast_sched_runq(sched); 08678 if (count >= 20) 08679 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08680 } 08681 return NULL; 08682 }
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 2530 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02531 { 02532 int type, len; 02533 int ret; 02534 int needfree = 0; 02535 02536 /* Attempt to recover wrapped timestamps */ 02537 unwrap_timestamp(fr); 02538 02539 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02540 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02541 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02542 else { 02543 #if 0 02544 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02545 #endif 02546 fr->af.delivery = ast_tv(0,0); 02547 } 02548 02549 type = JB_TYPE_CONTROL; 02550 len = 0; 02551 02552 if(fr->af.frametype == AST_FRAME_VOICE) { 02553 type = JB_TYPE_VOICE; 02554 len = ast_codec_get_samples(&fr->af) / 8; 02555 } else if(fr->af.frametype == AST_FRAME_CNG) { 02556 type = JB_TYPE_SILENCE; 02557 } 02558 02559 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02560 if (tsout) 02561 *tsout = fr->ts; 02562 __do_deliver(fr); 02563 return -1; 02564 } 02565 02566 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02567 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02568 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02569 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02570 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02571 jb_frame frame; 02572 02573 /* deliver any frames in the jb */ 02574 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02575 __do_deliver(frame.data); 02576 /* __do_deliver() can make the call disappear */ 02577 if (!iaxs[fr->callno]) 02578 return -1; 02579 } 02580 02581 jb_reset(iaxs[fr->callno]->jb); 02582 02583 if (iaxs[fr->callno]->jbid > -1) 02584 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02585 02586 iaxs[fr->callno]->jbid = -1; 02587 02588 /* deliver this frame now */ 02589 if (tsout) 02590 *tsout = fr->ts; 02591 __do_deliver(fr); 02592 return -1; 02593 } 02594 02595 /* insert into jitterbuffer */ 02596 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02597 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02598 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02599 if (ret == JB_DROP) { 02600 needfree++; 02601 } else if (ret == JB_SCHED) { 02602 update_jbsched(iaxs[fr->callno]); 02603 } 02604 if (tsout) 02605 *tsout = fr->ts; 02606 if (needfree) { 02607 /* Free our iax frame */ 02608 iax2_frame_free(fr); 02609 return -1; 02610 } 02611 return 0; 02612 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4789 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().
04790 { 04791 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04792 }
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 4808 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().
04809 { 04810 int call_num = i->callno; 04811 /* It is assumed that the callno has already been locked */ 04812 iax2_predestroy(i->callno); 04813 if (!iaxs[call_num]) 04814 return -1; 04815 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04816 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4818 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04819 { 04820 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04821 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4794 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().
04795 { 04796 int res; 04797 ast_mutex_lock(&iaxsl[callno]); 04798 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04799 ast_mutex_unlock(&iaxsl[callno]); 04800 return res; 04801 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 4823 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04824 { 04825 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04826 }
static int send_lagrq | ( | void * | data | ) | [static] |
Definition at line 1014 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
01015 { 01016 #ifdef SCHED_MULTITHREADED 01017 if (schedule_action(__send_lagrq, data)) 01018 #endif 01019 __send_lagrq(data); 01020 return 0; 01021 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1846 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_backtrace(), ast_inet_ntoa(), ast_log(), error(), f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, LOG_ERROR, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01847 { 01848 int res; 01849 int callno; 01850 01851 if( f == NULL ) { 01852 ast_log(LOG_ERROR, "send_packet( NULL )\n"); 01853 ast_backtrace(); 01854 return -1; 01855 } 01856 01857 callno = f->callno; 01858 01859 /* Don't send if there was an error, but return error instead */ 01860 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01861 return -1; 01862 01863 /* Called with iaxsl held */ 01864 if (option_debug > 2 && iaxdebug) 01865 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)); 01866 if (f->transfer) { 01867 if (iaxdebug) 01868 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01869 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01870 sizeof(iaxs[callno]->transfer)); 01871 } else { 01872 if (iaxdebug) 01873 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01874 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01875 sizeof(iaxs[callno]->addr)); 01876 } 01877 if (res < 0) { 01878 if (option_debug && iaxdebug) 01879 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01880 handle_error(); 01881 } else 01882 res = 0; 01883 return res; 01884 }
static int send_ping | ( | void * | data | ) | [static] |
Definition at line 979 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00980 { 00981 #ifdef SCHED_MULTITHREADED 00982 if (schedule_action(__send_ping, data)) 00983 #endif 00984 __send_ping(data); 00985 return 0; 00986 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6203 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06204 { 06205 int res = 0; 06206 struct iax_frame *fr; 06207 struct ast_iax2_meta_hdr *meta; 06208 struct ast_iax2_meta_trunk_hdr *mth; 06209 int calls = 0; 06210 06211 /* Point to frame */ 06212 fr = (struct iax_frame *)tpeer->trunkdata; 06213 /* Point to meta data */ 06214 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06215 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06216 if (tpeer->trunkdatalen) { 06217 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06218 meta->zeros = 0; 06219 meta->metacmd = IAX_META_TRUNK; 06220 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06221 meta->cmddata = IAX_META_TRUNK_MINI; 06222 else 06223 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06224 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06225 /* And the rest of the ast_iax2 header */ 06226 fr->direction = DIRECTION_OUTGRESS; 06227 fr->retrans = -1; 06228 fr->transfer = 0; 06229 /* Any appropriate call will do */ 06230 fr->data = fr->afdata; 06231 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06232 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06233 calls = tpeer->calls; 06234 #if 0 06235 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)); 06236 #endif 06237 /* Reset transmit trunk side data */ 06238 tpeer->trunkdatalen = 0; 06239 tpeer->calls = 0; 06240 } 06241 if (res < 0) 06242 return res; 06243 return calls; 06244 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9481 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, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_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, peers, portno, prefs, reg_source_db(), secret, set_timing(), socket_read(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09482 { 09483 struct ast_config *cfg, *ucfg; 09484 int capability=iax2_capability; 09485 struct ast_variable *v; 09486 char *cat; 09487 const char *utype; 09488 const char *tosval; 09489 int format; 09490 int portno = IAX_DEFAULT_PORTNO; 09491 int x; 09492 struct iax2_user *user; 09493 struct iax2_peer *peer; 09494 struct ast_netsock *ns; 09495 #if 0 09496 static unsigned short int last_port=0; 09497 #endif 09498 09499 cfg = ast_config_load(config_file); 09500 09501 if (!cfg) { 09502 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09503 return -1; 09504 } 09505 09506 /* Reset global codec prefs */ 09507 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09508 09509 /* Reset Global Flags */ 09510 memset(&globalflags, 0, sizeof(globalflags)); 09511 ast_set_flag(&globalflags, IAX_RTUPDATE); 09512 09513 #ifdef SO_NO_CHECK 09514 nochecksums = 0; 09515 #endif 09516 09517 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09518 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09519 09520 maxauthreq = 3; 09521 09522 v = ast_variable_browse(cfg, "general"); 09523 09524 /* Seed initial tos value */ 09525 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09526 if (tosval) { 09527 if (ast_str2tos(tosval, &tos)) 09528 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09529 } 09530 while(v) { 09531 if (!strcasecmp(v->name, "bindport")){ 09532 if (reload) 09533 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09534 else 09535 portno = atoi(v->value); 09536 } else if (!strcasecmp(v->name, "pingtime")) 09537 ping_time = atoi(v->value); 09538 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09539 if (reload) { 09540 if (atoi(v->value) != iaxthreadcount) 09541 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09542 } else { 09543 iaxthreadcount = atoi(v->value); 09544 if (iaxthreadcount < 1) { 09545 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09546 iaxthreadcount = 1; 09547 } else if (iaxthreadcount > 256) { 09548 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09549 iaxthreadcount = 256; 09550 } 09551 } 09552 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09553 if (reload) { 09554 AST_LIST_LOCK(&dynamic_list); 09555 iaxmaxthreadcount = atoi(v->value); 09556 AST_LIST_UNLOCK(&dynamic_list); 09557 } else { 09558 iaxmaxthreadcount = atoi(v->value); 09559 if (iaxmaxthreadcount < 0) { 09560 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09561 iaxmaxthreadcount = 0; 09562 } else if (iaxmaxthreadcount > 256) { 09563 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09564 iaxmaxthreadcount = 256; 09565 } 09566 } 09567 } else if (!strcasecmp(v->name, "nochecksums")) { 09568 #ifdef SO_NO_CHECK 09569 if (ast_true(v->value)) 09570 nochecksums = 1; 09571 else 09572 nochecksums = 0; 09573 #else 09574 if (ast_true(v->value)) 09575 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09576 #endif 09577 } 09578 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09579 maxjitterbuffer = atoi(v->value); 09580 else if (!strcasecmp(v->name, "resyncthreshold")) 09581 resyncthreshold = atoi(v->value); 09582 else if (!strcasecmp(v->name, "maxjitterinterps")) 09583 maxjitterinterps = atoi(v->value); 09584 else if (!strcasecmp(v->name, "lagrqtime")) 09585 lagrq_time = atoi(v->value); 09586 else if (!strcasecmp(v->name, "maxregexpire")) 09587 max_reg_expire = atoi(v->value); 09588 else if (!strcasecmp(v->name, "minregexpire")) 09589 min_reg_expire = atoi(v->value); 09590 else if (!strcasecmp(v->name, "bindaddr")) { 09591 if (reload) { 09592 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09593 } else { 09594 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09595 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09596 } else { 09597 if (option_verbose > 1) { 09598 if (strchr(v->value, ':')) 09599 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09600 else 09601 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09602 } 09603 if (defaultsockfd < 0) 09604 defaultsockfd = ast_netsock_sockfd(ns); 09605 ast_netsock_unref(ns); 09606 } 09607 } 09608 } else if (!strcasecmp(v->name, "authdebug")) 09609 authdebug = ast_true(v->value); 09610 else if (!strcasecmp(v->name, "encryption")) 09611 iax2_encryption = get_encrypt_methods(v->value); 09612 else if (!strcasecmp(v->name, "notransfer")) { 09613 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09614 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09615 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09616 } else if (!strcasecmp(v->name, "transfer")) { 09617 if (!strcasecmp(v->value, "mediaonly")) { 09618 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09619 } else if (ast_true(v->value)) { 09620 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09621 } else 09622 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09623 } else if (!strcasecmp(v->name, "codecpriority")) { 09624 if(!strcasecmp(v->value, "caller")) 09625 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09626 else if(!strcasecmp(v->value, "disabled")) 09627 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09628 else if(!strcasecmp(v->value, "reqonly")) { 09629 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09630 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09631 } 09632 } else if (!strcasecmp(v->name, "jitterbuffer")) 09633 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09634 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09635 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09636 else if (!strcasecmp(v->name, "delayreject")) 09637 delayreject = ast_true(v->value); 09638 else if (!strcasecmp(v->name, "rtcachefriends")) 09639 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09640 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09641 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09642 else if (!strcasecmp(v->name, "rtupdate")) 09643 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09644 else if (!strcasecmp(v->name, "trunktimestamps")) 09645 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09646 else if (!strcasecmp(v->name, "rtautoclear")) { 09647 int i = atoi(v->value); 09648 if(i > 0) 09649 global_rtautoclear = i; 09650 else 09651 i = 0; 09652 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09653 } else if (!strcasecmp(v->name, "trunkfreq")) { 09654 trunkfreq = atoi(v->value); 09655 if (trunkfreq < 10) 09656 trunkfreq = 10; 09657 } else if (!strcasecmp(v->name, "autokill")) { 09658 if (sscanf(v->value, "%d", &x) == 1) { 09659 if (x >= 0) 09660 autokill = x; 09661 else 09662 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09663 } else if (ast_true(v->value)) { 09664 autokill = DEFAULT_MAXMS; 09665 } else { 09666 autokill = 0; 09667 } 09668 } else if (!strcasecmp(v->name, "bandwidth")) { 09669 if (!strcasecmp(v->value, "low")) { 09670 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09671 } else if (!strcasecmp(v->value, "medium")) { 09672 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09673 } else if (!strcasecmp(v->value, "high")) { 09674 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09675 } else 09676 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09677 } else if (!strcasecmp(v->name, "allow")) { 09678 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09679 } else if (!strcasecmp(v->name, "disallow")) { 09680 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09681 } else if (!strcasecmp(v->name, "register")) { 09682 iax2_register(v->value, v->lineno); 09683 } else if (!strcasecmp(v->name, "iaxcompat")) { 09684 iaxcompat = ast_true(v->value); 09685 } else if (!strcasecmp(v->name, "regcontext")) { 09686 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09687 /* Create context if it doesn't exist already */ 09688 if (!ast_context_find(regcontext)) 09689 ast_context_create(NULL, regcontext, "IAX2"); 09690 } else if (!strcasecmp(v->name, "tos")) { 09691 if (ast_str2tos(v->value, &tos)) 09692 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09693 } else if (!strcasecmp(v->name, "accountcode")) { 09694 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09695 } else if (!strcasecmp(v->name, "mohinterpret")) { 09696 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09697 } else if (!strcasecmp(v->name, "mohsuggest")) { 09698 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09699 } else if (!strcasecmp(v->name, "amaflags")) { 09700 format = ast_cdr_amaflags2int(v->value); 09701 if (format < 0) { 09702 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09703 } else { 09704 amaflags = format; 09705 } 09706 } else if (!strcasecmp(v->name, "language")) { 09707 ast_copy_string(language, v->value, sizeof(language)); 09708 } else if (!strcasecmp(v->name, "maxauthreq")) { 09709 maxauthreq = atoi(v->value); 09710 if (maxauthreq < 0) 09711 maxauthreq = 0; 09712 } else if (!strcasecmp(v->name, "adsi")) { 09713 adsi = ast_true(v->value); 09714 } /*else if (strcasecmp(v->name,"type")) */ 09715 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09716 v = v->next; 09717 } 09718 09719 if (defaultsockfd < 0) { 09720 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09721 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09722 } else { 09723 if (option_verbose > 1) 09724 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09725 defaultsockfd = ast_netsock_sockfd(ns); 09726 ast_netsock_unref(ns); 09727 } 09728 } 09729 if (reload) { 09730 ast_netsock_release(outsock); 09731 outsock = ast_netsock_list_alloc(); 09732 if (!outsock) { 09733 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09734 return -1; 09735 } 09736 ast_netsock_init(outsock); 09737 } 09738 09739 if (min_reg_expire > max_reg_expire) { 09740 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09741 min_reg_expire, max_reg_expire, max_reg_expire); 09742 min_reg_expire = max_reg_expire; 09743 } 09744 iax2_capability = capability; 09745 09746 ucfg = ast_config_load("users.conf"); 09747 if (ucfg) { 09748 struct ast_variable *gen; 09749 int genhasiax; 09750 int genregisteriax; 09751 const char *hasiax, *registeriax; 09752 09753 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09754 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09755 gen = ast_variable_browse(ucfg, "general"); 09756 cat = ast_category_browse(ucfg, NULL); 09757 while (cat) { 09758 if (strcasecmp(cat, "general")) { 09759 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09760 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09761 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09762 /* Start with general parameters, then specific parameters, user and peer */ 09763 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09764 if (user) { 09765 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09766 user = NULL; 09767 } 09768 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09769 if (peer) { 09770 if (ast_test_flag(peer, IAX_DYNAMIC)) 09771 reg_source_db(peer); 09772 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09773 peer = NULL; 09774 } 09775 } 09776 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09777 char tmp[256]; 09778 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09779 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09780 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09781 if (!host) 09782 host = ast_variable_retrieve(ucfg, "general", "host"); 09783 if (!username) 09784 username = ast_variable_retrieve(ucfg, "general", "username"); 09785 if (!secret) 09786 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09787 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09788 if (!ast_strlen_zero(secret)) 09789 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09790 else 09791 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09792 iax2_register(tmp, 0); 09793 } 09794 } 09795 } 09796 cat = ast_category_browse(ucfg, cat); 09797 } 09798 ast_config_destroy(ucfg); 09799 } 09800 09801 cat = ast_category_browse(cfg, NULL); 09802 while(cat) { 09803 if (strcasecmp(cat, "general")) { 09804 utype = ast_variable_retrieve(cfg, cat, "type"); 09805 if (utype) { 09806 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 09807 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 09808 if (user) { 09809 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09810 user = NULL; 09811 } 09812 } 09813 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 09814 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 09815 if (peer) { 09816 if (ast_test_flag(peer, IAX_DYNAMIC)) 09817 reg_source_db(peer); 09818 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09819 peer = NULL; 09820 } 09821 } else if (strcasecmp(utype, "user")) { 09822 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 09823 } 09824 } else 09825 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 09826 } 09827 cat = ast_category_browse(cfg, cat); 09828 } 09829 ast_config_destroy(cfg); 09830 set_timing(); 09831 return capability; 09832 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9464 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09465 { 09466 #ifdef HAVE_ZAPTEL 09467 int bs = trunkfreq * 8; 09468 if (timingfd > -1) { 09469 if ( 09470 #ifdef ZT_TIMERACK 09471 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09472 #endif 09473 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09474 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09475 } 09476 #endif 09477 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 755 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_transmit(), network_thread(), socket_read(), and update_jbsched().
00756 { 00757 ast_mutex_lock(lock); 00758 ast_cond_signal(cond); 00759 ast_mutex_unlock(lock); 00760 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6670 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), 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, chan_iax2_pvt::callno, iax_frame::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, decrypt_frame(), dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_send(), iax2_vnak(), IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_STATE_UNCHANGED, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, 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, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), chan_iax2_pvt::state, stop_stuff(), 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().
06671 { 06672 struct sockaddr_in sin; 06673 int res; 06674 int updatehistory=1; 06675 int new = NEW_PREVENT; 06676 void *ptr; 06677 int dcallno = 0; 06678 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06679 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06680 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06681 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06682 struct ast_iax2_meta_trunk_hdr *mth; 06683 struct ast_iax2_meta_trunk_entry *mte; 06684 struct ast_iax2_meta_trunk_mini *mtm; 06685 struct iax_frame *fr; 06686 struct iax_frame *cur; 06687 struct ast_frame f = { 0, }; 06688 struct ast_channel *c; 06689 struct iax2_dpcache *dp; 06690 struct iax2_peer *peer; 06691 struct iax2_trunk_peer *tpeer; 06692 struct timeval rxtrunktime; 06693 struct iax_ies ies; 06694 struct iax_ie_data ied0, ied1; 06695 int format; 06696 int fd; 06697 int exists; 06698 int minivid = 0; 06699 unsigned int ts; 06700 char empty[32]=""; /* Safety measure */ 06701 struct iax_frame *duped_fr; 06702 char host_pref_buf[128]; 06703 char caller_pref_buf[128]; 06704 struct ast_codec_pref pref; 06705 char *using_prefs = "mine"; 06706 06707 /* allocate an iax_frame with 4096 bytes of data buffer */ 06708 fr = alloca(sizeof(*fr) + 4096); 06709 fr->callno = 0; 06710 fr->afdatalen = 4096; /* From alloca() above */ 06711 06712 /* Copy frequently used parameters to the stack */ 06713 res = thread->buf_len; 06714 fd = thread->iofd; 06715 memcpy(&sin, &thread->iosin, sizeof(sin)); 06716 06717 if (res < sizeof(*mh)) { 06718 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06719 return 1; 06720 } 06721 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06722 if (res < sizeof(*vh)) { 06723 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)); 06724 return 1; 06725 } 06726 06727 /* This is a video frame, get call number */ 06728 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd); 06729 minivid = 1; 06730 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06731 unsigned char metatype; 06732 06733 if (res < sizeof(*meta)) { 06734 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)); 06735 return 1; 06736 } 06737 06738 /* This is a meta header */ 06739 switch(meta->metacmd) { 06740 case IAX_META_TRUNK: 06741 if (res < (sizeof(*meta) + sizeof(*mth))) { 06742 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06743 sizeof(*meta) + sizeof(*mth)); 06744 return 1; 06745 } 06746 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06747 ts = ntohl(mth->ts); 06748 metatype = meta->cmddata; 06749 res -= (sizeof(*meta) + sizeof(*mth)); 06750 ptr = mth->data; 06751 tpeer = find_tpeer(&sin, fd); 06752 if (!tpeer) { 06753 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)); 06754 return 1; 06755 } 06756 tpeer->trunkact = ast_tvnow(); 06757 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06758 tpeer->rxtrunktime = tpeer->trunkact; 06759 rxtrunktime = tpeer->rxtrunktime; 06760 ast_mutex_unlock(&tpeer->lock); 06761 while(res >= sizeof(*mte)) { 06762 /* Process channels */ 06763 unsigned short callno, trunked_ts, len; 06764 06765 if (metatype == IAX_META_TRUNK_MINI) { 06766 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06767 ptr += sizeof(*mtm); 06768 res -= sizeof(*mtm); 06769 len = ntohs(mtm->len); 06770 callno = ntohs(mtm->mini.callno); 06771 trunked_ts = ntohs(mtm->mini.ts); 06772 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06773 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06774 ptr += sizeof(*mte); 06775 res -= sizeof(*mte); 06776 len = ntohs(mte->len); 06777 callno = ntohs(mte->callno); 06778 trunked_ts = 0; 06779 } else { 06780 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06781 break; 06782 } 06783 /* Stop if we don't have enough data */ 06784 if (len > res) 06785 break; 06786 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd); 06787 if (fr->callno) { 06788 ast_mutex_lock(&iaxsl[fr->callno]); 06789 /* If it's a valid call, deliver the contents. If not, we 06790 drop it, since we don't have a scallno to use for an INVAL */ 06791 /* Process as a mini frame */ 06792 memset(&f, 0, sizeof(f)); 06793 f.frametype = AST_FRAME_VOICE; 06794 if (iaxs[fr->callno]) { 06795 if (iaxs[fr->callno]->voiceformat > 0) { 06796 f.subclass = iaxs[fr->callno]->voiceformat; 06797 f.datalen = len; 06798 if (f.datalen >= 0) { 06799 if (f.datalen) 06800 f.data = ptr; 06801 if(trunked_ts) { 06802 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06803 } else 06804 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06805 /* Don't pass any packets until we're started */ 06806 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06807 /* Common things */ 06808 f.src = "IAX2"; 06809 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06810 f.samples = ast_codec_get_samples(&f); 06811 iax_frame_wrap(fr, &f); 06812 duped_fr = iaxfrdup2(fr); 06813 if (duped_fr) { 06814 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06815 } 06816 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06817 if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06818 iaxs[fr->callno]->last = fr->ts; 06819 #if 1 06820 if (option_debug && iaxdebug) 06821 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06822 #endif 06823 } 06824 } 06825 } else { 06826 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06827 } 06828 } else { 06829 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06830 iax2_vnak(fr->callno); 06831 } 06832 } 06833 ast_mutex_unlock(&iaxsl[fr->callno]); 06834 } 06835 ptr += len; 06836 res -= len; 06837 } 06838 06839 } 06840 return 1; 06841 } 06842 06843 #ifdef DEBUG_SUPPORT 06844 if (iaxdebug && (res >= sizeof(*fh))) 06845 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06846 #endif 06847 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06848 if (res < sizeof(*fh)) { 06849 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)); 06850 return 1; 06851 } 06852 06853 /* Get the destination call number */ 06854 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06855 /* Retrieve the type and subclass */ 06856 f.frametype = fh->type; 06857 if (f.frametype == AST_FRAME_VIDEO) { 06858 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06859 } else { 06860 f.subclass = uncompress_subclass(fh->csub); 06861 } 06862 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06863 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06864 (f.subclass == IAX_COMMAND_REGREL))) 06865 new = NEW_ALLOW; 06866 } else { 06867 /* Don't know anything about it yet */ 06868 f.frametype = AST_FRAME_NULL; 06869 f.subclass = 0; 06870 } 06871 06872 if (!fr->callno) 06873 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd); 06874 06875 if (fr->callno > 0) 06876 ast_mutex_lock(&iaxsl[fr->callno]); 06877 06878 if (!fr->callno || !iaxs[fr->callno]) { 06879 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06880 frame, reply with an inval */ 06881 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06882 /* We can only raw hangup control frames */ 06883 if (((f.subclass != IAX_COMMAND_INVAL) && 06884 (f.subclass != IAX_COMMAND_TXCNT) && 06885 (f.subclass != IAX_COMMAND_TXACC) && 06886 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06887 (f.frametype != AST_FRAME_IAX)) 06888 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06889 fd); 06890 } 06891 if (fr->callno > 0) 06892 ast_mutex_unlock(&iaxsl[fr->callno]); 06893 return 1; 06894 } 06895 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06896 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06897 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06898 ast_mutex_unlock(&iaxsl[fr->callno]); 06899 return 1; 06900 } 06901 #ifdef DEBUG_SUPPORT 06902 else if (iaxdebug) 06903 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 06904 #endif 06905 } 06906 06907 /* count this frame */ 06908 iaxs[fr->callno]->frames_received++; 06909 06910 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 06911 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06912 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06913 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06914 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06915 if (option_debug && iaxdebug) 06916 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06917 /* Check if it's out of order (and not an ACK or INVAL) */ 06918 fr->oseqno = fh->oseqno; 06919 fr->iseqno = fh->iseqno; 06920 fr->ts = ntohl(fh->ts); 06921 #ifdef IAXTESTS 06922 if (test_resync) { 06923 if (option_debug) 06924 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 06925 fr->ts += test_resync; 06926 } 06927 #endif /* IAXTESTS */ 06928 #if 0 06929 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06930 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06931 (f.subclass == IAX_COMMAND_NEW || 06932 f.subclass == IAX_COMMAND_AUTHREQ || 06933 f.subclass == IAX_COMMAND_ACCEPT || 06934 f.subclass == IAX_COMMAND_REJECT)) ) ) 06935 #endif 06936 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06937 updatehistory = 0; 06938 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 06939 (iaxs[fr->callno]->iseqno || 06940 ((f.subclass != IAX_COMMAND_TXCNT) && 06941 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06942 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06943 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06944 (f.subclass != IAX_COMMAND_TXACC)) || 06945 (f.frametype != AST_FRAME_IAX))) { 06946 if ( 06947 ((f.subclass != IAX_COMMAND_ACK) && 06948 (f.subclass != IAX_COMMAND_INVAL) && 06949 (f.subclass != IAX_COMMAND_TXCNT) && 06950 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06951 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06952 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06953 (f.subclass != IAX_COMMAND_TXACC) && 06954 (f.subclass != IAX_COMMAND_VNAK)) || 06955 (f.frametype != AST_FRAME_IAX)) { 06956 /* If it's not an ACK packet, it's out of order. */ 06957 if (option_debug) 06958 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06959 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 06960 /* Check to see if we need to request retransmission, 06961 * and take sequence number wraparound into account */ 06962 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 06963 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06964 if ((f.frametype != AST_FRAME_IAX) || 06965 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06966 if (option_debug) 06967 ast_log(LOG_DEBUG, "Acking anyway\n"); 06968 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06969 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06970 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06971 } 06972 } else { 06973 /* Send a VNAK requesting retransmission */ 06974 iax2_vnak(fr->callno); 06975 } 06976 ast_mutex_unlock(&iaxsl[fr->callno]); 06977 return 1; 06978 } 06979 } else { 06980 /* Increment unless it's an ACK or VNAK */ 06981 if (((f.subclass != IAX_COMMAND_ACK) && 06982 (f.subclass != IAX_COMMAND_INVAL) && 06983 (f.subclass != IAX_COMMAND_TXCNT) && 06984 (f.subclass != IAX_COMMAND_TXACC) && 06985 (f.subclass != IAX_COMMAND_VNAK)) || 06986 (f.frametype != AST_FRAME_IAX)) 06987 iaxs[fr->callno]->iseqno++; 06988 } 06989 /* A full frame */ 06990 if (res < sizeof(*fh)) { 06991 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 06992 ast_mutex_unlock(&iaxsl[fr->callno]); 06993 return 1; 06994 } 06995 /* Ensure text frames are NULL-terminated */ 06996 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 06997 if (res < thread->buf_size) 06998 thread->buf[res++] = '\0'; 06999 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07000 thread->buf[res - 1] = '\0'; 07001 } 07002 f.datalen = res - sizeof(*fh); 07003 07004 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07005 from the real peer, not the transfer peer */ 07006 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07007 ((f.subclass != IAX_COMMAND_INVAL) || 07008 (f.frametype != AST_FRAME_IAX))) { 07009 unsigned char x; 07010 int call_to_destroy; 07011 /* XXX This code is not very efficient. Surely there is a better way which still 07012 properly handles boundary conditions? XXX */ 07013 /* First we have to qualify that the ACKed value is within our window */ 07014 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07015 if (fr->iseqno == x) 07016 break; 07017 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07018 /* The acknowledgement is within our window. Time to acknowledge everything 07019 that it says to */ 07020 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07021 /* Ack the packet with the given timestamp */ 07022 if (option_debug && iaxdebug) 07023 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07024 call_to_destroy = 0; 07025 AST_LIST_LOCK(&iaxq.queue); 07026 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07027 /* If it's our call, and our timestamp, mark -1 retries */ 07028 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07029 cur->retries = -1; 07030 /* Destroy call if this is the end */ 07031 if (cur->final) 07032 call_to_destroy = fr->callno; 07033 } 07034 } 07035 AST_LIST_UNLOCK(&iaxq.queue); 07036 if (call_to_destroy) { 07037 if (iaxdebug && option_debug) 07038 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07039 iax2_destroy(call_to_destroy); 07040 } 07041 } 07042 /* Note how much we've received acknowledgement for */ 07043 if (iaxs[fr->callno]) 07044 iaxs[fr->callno]->rseqno = fr->iseqno; 07045 else { 07046 /* Stop processing now */ 07047 ast_mutex_unlock(&iaxsl[fr->callno]); 07048 return 1; 07049 } 07050 } else 07051 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07052 } 07053 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07054 ((f.frametype != AST_FRAME_IAX) || 07055 ((f.subclass != IAX_COMMAND_TXACC) && 07056 (f.subclass != IAX_COMMAND_TXCNT)))) { 07057 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07058 ast_mutex_unlock(&iaxsl[fr->callno]); 07059 return 1; 07060 } 07061 07062 if (f.datalen) { 07063 if (f.frametype == AST_FRAME_IAX) { 07064 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07065 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07066 ast_mutex_unlock(&iaxsl[fr->callno]); 07067 return 1; 07068 } 07069 f.data = NULL; 07070 f.datalen = 0; 07071 } else 07072 f.data = thread->buf + sizeof(*fh); 07073 } else { 07074 if (f.frametype == AST_FRAME_IAX) 07075 f.data = NULL; 07076 else 07077 f.data = empty; 07078 memset(&ies, 0, sizeof(ies)); 07079 } 07080 07081 /* when we receive the first full frame for a new incoming channel, 07082 it is safe to start the PBX on the channel because we have now 07083 completed a 3-way handshake with the peer */ 07084 if ((f.frametype == AST_FRAME_VOICE) || 07085 (f.frametype == AST_FRAME_VIDEO) || 07086 (f.frametype == AST_FRAME_IAX)) { 07087 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07088 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07089 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07090 ast_mutex_unlock(&iaxsl[fr->callno]); 07091 return 1; 07092 } 07093 } 07094 } 07095 07096 if (f.frametype == AST_FRAME_VOICE) { 07097 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07098 iaxs[fr->callno]->voiceformat = f.subclass; 07099 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07100 if (iaxs[fr->callno]->owner) { 07101 int orignative; 07102 retryowner: 07103 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07104 ast_mutex_unlock(&iaxsl[fr->callno]); 07105 usleep(1); 07106 ast_mutex_lock(&iaxsl[fr->callno]); 07107 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07108 } 07109 if (iaxs[fr->callno]) { 07110 if (iaxs[fr->callno]->owner) { 07111 orignative = iaxs[fr->callno]->owner->nativeformats; 07112 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07113 if (iaxs[fr->callno]->owner->readformat) 07114 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07115 iaxs[fr->callno]->owner->nativeformats = orignative; 07116 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07117 } 07118 } else { 07119 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07120 ast_mutex_unlock(&iaxsl[fr->callno]); 07121 return 1; 07122 } 07123 } 07124 } 07125 } 07126 if (f.frametype == AST_FRAME_VIDEO) { 07127 if (f.subclass != iaxs[fr->callno]->videoformat) { 07128 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07129 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07130 } 07131 } 07132 if (f.frametype == AST_FRAME_IAX) { 07133 if (iaxs[fr->callno]->initid > -1) { 07134 /* Don't auto congest anymore since we've gotten something usefulb ack */ 07135 ast_sched_del(sched, iaxs[fr->callno]->initid); 07136 iaxs[fr->callno]->initid = -1; 07137 } 07138 /* Handle the IAX pseudo frame itself */ 07139 if (option_debug && iaxdebug) 07140 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07141 07142 /* Update last ts unless the frame's timestamp originated with us. */ 07143 if (iaxs[fr->callno]->last < fr->ts && 07144 f.subclass != IAX_COMMAND_ACK && 07145 f.subclass != IAX_COMMAND_PONG && 07146 f.subclass != IAX_COMMAND_LAGRP) { 07147 iaxs[fr->callno]->last = fr->ts; 07148 if (option_debug && iaxdebug) 07149 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07150 } 07151 07152 switch(f.subclass) { 07153 case IAX_COMMAND_ACK: 07154 /* Do nothing */ 07155 break; 07156 case IAX_COMMAND_QUELCH: 07157 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07158 /* Generate Manager Hold event, if necessary*/ 07159 if (iaxs[fr->callno]->owner) { 07160 manager_event(EVENT_FLAG_CALL, "Hold", 07161 "Channel: %s\r\n" 07162 "Uniqueid: %s\r\n", 07163 iaxs[fr->callno]->owner->name, 07164 iaxs[fr->callno]->owner->uniqueid); 07165 } 07166 07167 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07168 if (ies.musiconhold) { 07169 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07170 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07171 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07172 S_OR(mohsuggest, NULL), 07173 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07174 if (!iaxs[fr->callno]) { 07175 ast_mutex_unlock(&iaxsl[fr->callno]); 07176 return 1; 07177 } 07178 } 07179 } 07180 } 07181 break; 07182 case IAX_COMMAND_UNQUELCH: 07183 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07184 /* Generate Manager Unhold event, if necessary*/ 07185 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07186 manager_event(EVENT_FLAG_CALL, "Unhold", 07187 "Channel: %s\r\n" 07188 "Uniqueid: %s\r\n", 07189 iaxs[fr->callno]->owner->name, 07190 iaxs[fr->callno]->owner->uniqueid); 07191 } 07192 07193 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07194 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07195 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07196 if (!iaxs[fr->callno]) { 07197 ast_mutex_unlock(&iaxsl[fr->callno]); 07198 return 1; 07199 } 07200 } 07201 } 07202 break; 07203 case IAX_COMMAND_TXACC: 07204 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07205 /* Ack the packet with the given timestamp */ 07206 AST_LIST_LOCK(&iaxq.queue); 07207 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07208 /* Cancel any outstanding txcnt's */ 07209 if ((fr->callno == cur->callno) && (cur->transfer)) 07210 cur->retries = -1; 07211 } 07212 AST_LIST_UNLOCK(&iaxq.queue); 07213 memset(&ied1, 0, sizeof(ied1)); 07214 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07215 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07216 iaxs[fr->callno]->transferring = TRANSFER_READY; 07217 } 07218 break; 07219 case IAX_COMMAND_NEW: 07220 /* Ignore if it's already up */ 07221 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07222 break; 07223 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07224 ast_mutex_unlock(&iaxsl[fr->callno]); 07225 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07226 ast_mutex_lock(&iaxsl[fr->callno]); 07227 if (!iaxs[fr->callno]) { 07228 ast_mutex_unlock(&iaxsl[fr->callno]); 07229 return 1; 07230 } 07231 } 07232 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07233 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07234 int new_callno; 07235 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07236 fr->callno = new_callno; 07237 } 07238 /* For security, always ack immediately */ 07239 if (delayreject) 07240 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07241 if (check_access(fr->callno, &sin, &ies)) { 07242 /* They're not allowed on */ 07243 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07244 if (authdebug) 07245 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); 07246 break; 07247 } 07248 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07249 const char *context, *exten, *cid_num; 07250 07251 context = ast_strdupa(iaxs[fr->callno]->context); 07252 exten = ast_strdupa(iaxs[fr->callno]->exten); 07253 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07254 07255 /* This might re-enter the IAX code and need the lock */ 07256 ast_mutex_unlock(&iaxsl[fr->callno]); 07257 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07258 ast_mutex_lock(&iaxsl[fr->callno]); 07259 07260 if (!iaxs[fr->callno]) { 07261 ast_mutex_unlock(&iaxsl[fr->callno]); 07262 return 1; 07263 } 07264 } else 07265 exists = 0; 07266 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07267 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07268 memset(&ied0, 0, sizeof(ied0)); 07269 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07270 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07271 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07272 if (!iaxs[fr->callno]) { 07273 ast_mutex_unlock(&iaxsl[fr->callno]); 07274 return 1; 07275 } 07276 if (authdebug) 07277 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); 07278 } else { 07279 /* Select an appropriate format */ 07280 07281 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07282 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07283 using_prefs = "reqonly"; 07284 } else { 07285 using_prefs = "disabled"; 07286 } 07287 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07288 memset(&pref, 0, sizeof(pref)); 07289 strcpy(caller_pref_buf, "disabled"); 07290 strcpy(host_pref_buf, "disabled"); 07291 } else { 07292 using_prefs = "mine"; 07293 /* If the information elements are in here... use them */ 07294 if (ies.codec_prefs) 07295 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07296 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07297 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07298 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07299 pref = iaxs[fr->callno]->rprefs; 07300 using_prefs = "caller"; 07301 } else { 07302 pref = iaxs[fr->callno]->prefs; 07303 } 07304 } else 07305 pref = iaxs[fr->callno]->prefs; 07306 07307 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07308 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07309 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07310 } 07311 if (!format) { 07312 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07313 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07314 if (!format) { 07315 memset(&ied0, 0, sizeof(ied0)); 07316 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07317 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07318 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07319 if (!iaxs[fr->callno]) { 07320 ast_mutex_unlock(&iaxsl[fr->callno]); 07321 return 1; 07322 } 07323 if (authdebug) { 07324 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07325 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); 07326 else 07327 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); 07328 } 07329 } else { 07330 /* Pick one... */ 07331 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07332 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07333 format = 0; 07334 } else { 07335 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07336 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07337 memset(&pref, 0, sizeof(pref)); 07338 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07339 strcpy(caller_pref_buf,"disabled"); 07340 strcpy(host_pref_buf,"disabled"); 07341 } else { 07342 using_prefs = "mine"; 07343 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07344 /* Do the opposite of what we tried above. */ 07345 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07346 pref = iaxs[fr->callno]->prefs; 07347 } else { 07348 pref = iaxs[fr->callno]->rprefs; 07349 using_prefs = "caller"; 07350 } 07351 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07352 07353 } else /* if no codec_prefs IE do it the old way */ 07354 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07355 } 07356 } 07357 07358 if (!format) { 07359 memset(&ied0, 0, sizeof(ied0)); 07360 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07361 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07362 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07363 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07364 if (!iaxs[fr->callno]) { 07365 ast_mutex_unlock(&iaxsl[fr->callno]); 07366 return 1; 07367 } 07368 if (authdebug) 07369 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); 07370 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07371 break; 07372 } 07373 } 07374 } 07375 if (format) { 07376 /* No authentication required, let them in */ 07377 memset(&ied1, 0, sizeof(ied1)); 07378 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07379 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07380 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07381 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07382 if (option_verbose > 2) 07383 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07384 "%srequested format = %s,\n" 07385 "%srequested prefs = %s,\n" 07386 "%sactual format = %s,\n" 07387 "%shost prefs = %s,\n" 07388 "%spriority = %s\n", 07389 ast_inet_ntoa(sin.sin_addr), 07390 VERBOSE_PREFIX_4, 07391 ast_getformatname(iaxs[fr->callno]->peerformat), 07392 VERBOSE_PREFIX_4, 07393 caller_pref_buf, 07394 VERBOSE_PREFIX_4, 07395 ast_getformatname(format), 07396 VERBOSE_PREFIX_4, 07397 host_pref_buf, 07398 VERBOSE_PREFIX_4, 07399 using_prefs); 07400 07401 iaxs[fr->callno]->chosenformat = format; 07402 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07403 } else { 07404 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07405 /* If this is a TBD call, we're ready but now what... */ 07406 if (option_verbose > 2) 07407 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07408 } 07409 } 07410 } 07411 break; 07412 } 07413 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07414 merge_encryption(iaxs[fr->callno],ies.encmethods); 07415 else 07416 iaxs[fr->callno]->encmethods = 0; 07417 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07418 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07419 if (!iaxs[fr->callno]) { 07420 ast_mutex_unlock(&iaxsl[fr->callno]); 07421 return 1; 07422 } 07423 break; 07424 case IAX_COMMAND_DPREQ: 07425 /* Request status in the dialplan */ 07426 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07427 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07428 if (iaxcompat) { 07429 /* Spawn a thread for the lookup */ 07430 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07431 } else { 07432 /* Just look it up */ 07433 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07434 } 07435 } 07436 break; 07437 case IAX_COMMAND_HANGUP: 07438 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07439 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07440 /* Set hangup cause according to remote */ 07441 if (ies.causecode && iaxs[fr->callno]->owner) 07442 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07443 /* Send ack immediately, before we destroy */ 07444 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07445 iax2_destroy(fr->callno); 07446 break; 07447 case IAX_COMMAND_REJECT: 07448 /* Set hangup cause according to remote */ 07449 if (ies.causecode && iaxs[fr->callno]->owner) 07450 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07451 07452 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07453 if (iaxs[fr->callno]->owner && authdebug) 07454 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07455 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07456 ies.cause ? ies.cause : "<Unknown>"); 07457 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07458 fr->callno); 07459 } 07460 /* Send ack immediately, before we destroy */ 07461 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07462 fr->ts, NULL, 0, fr->iseqno); 07463 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07464 iaxs[fr->callno]->error = EPERM; 07465 iax2_destroy(fr->callno); 07466 break; 07467 case IAX_COMMAND_TRANSFER: 07468 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07469 /* Set BLINDTRANSFER channel variables */ 07470 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07471 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07472 if (!strcmp(ies.called_number, ast_parking_ext())) { 07473 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07474 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07475 } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) 07476 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07477 } else { 07478 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07479 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07480 ies.called_number, iaxs[fr->callno]->context); 07481 else 07482 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07483 ies.called_number, iaxs[fr->callno]->context); 07484 } 07485 } else 07486 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07487 break; 07488 case IAX_COMMAND_ACCEPT: 07489 /* Ignore if call is already up or needs authentication or is a TBD */ 07490 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07491 break; 07492 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07493 /* Send ack immediately, before we destroy */ 07494 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07495 iax2_destroy(fr->callno); 07496 break; 07497 } 07498 if (ies.format) { 07499 iaxs[fr->callno]->peerformat = ies.format; 07500 } else { 07501 if (iaxs[fr->callno]->owner) 07502 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07503 else 07504 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07505 } 07506 if (option_verbose > 2) 07507 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)); 07508 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07509 memset(&ied0, 0, sizeof(ied0)); 07510 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07511 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07512 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07513 if (!iaxs[fr->callno]) { 07514 ast_mutex_unlock(&iaxsl[fr->callno]); 07515 return 1; 07516 } 07517 if (authdebug) 07518 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); 07519 } else { 07520 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07521 if (iaxs[fr->callno]->owner) { 07522 /* Switch us to use a compatible format */ 07523 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07524 if (option_verbose > 2) 07525 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07526 retryowner2: 07527 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07528 ast_mutex_unlock(&iaxsl[fr->callno]); 07529 usleep(1); 07530 ast_mutex_lock(&iaxsl[fr->callno]); 07531 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07532 } 07533 07534 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07535 /* Setup read/write formats properly. */ 07536 if (iaxs[fr->callno]->owner->writeformat) 07537 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07538 if (iaxs[fr->callno]->owner->readformat) 07539 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07540 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07541 } 07542 } 07543 } 07544 if (iaxs[fr->callno]) { 07545 ast_mutex_lock(&dpcache_lock); 07546 dp = iaxs[fr->callno]->dpentries; 07547 while(dp) { 07548 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07549 iax2_dprequest(dp, fr->callno); 07550 } 07551 dp = dp->peer; 07552 } 07553 ast_mutex_unlock(&dpcache_lock); 07554 } 07555 break; 07556 case IAX_COMMAND_POKE: 07557 /* Send back a pong packet with the original timestamp */ 07558 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07559 if (!iaxs[fr->callno]) { 07560 ast_mutex_unlock(&iaxsl[fr->callno]); 07561 return 1; 07562 } 07563 break; 07564 case IAX_COMMAND_PING: 07565 { 07566 struct iax_ie_data pingied; 07567 construct_rr(iaxs[fr->callno], &pingied); 07568 /* Send back a pong packet with the original timestamp */ 07569 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07570 } 07571 break; 07572 case IAX_COMMAND_PONG: 07573 /* Calculate ping time */ 07574 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07575 /* save RR info */ 07576 save_rr(fr, &ies); 07577 07578 if (iaxs[fr->callno]->peerpoke) { 07579 peer = iaxs[fr->callno]->peerpoke; 07580 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07581 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07582 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07583 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07584 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07585 } 07586 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07587 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07588 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07589 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07590 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07591 } 07592 } 07593 peer->lastms = iaxs[fr->callno]->pingtime; 07594 if (peer->smoothing && (peer->lastms > -1)) 07595 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07596 else if (peer->smoothing && peer->lastms < 0) 07597 peer->historicms = (0 + peer->historicms) / 2; 07598 else 07599 peer->historicms = iaxs[fr->callno]->pingtime; 07600 07601 /* Remove scheduled iax2_poke_noanswer */ 07602 if (peer->pokeexpire > -1) 07603 ast_sched_del(sched, peer->pokeexpire); 07604 /* Schedule the next cycle */ 07605 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07606 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07607 else 07608 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07609 /* and finally send the ack */ 07610 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07611 /* And wrap up the qualify call */ 07612 iax2_destroy(fr->callno); 07613 peer->callno = 0; 07614 if (option_debug) 07615 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07616 } 07617 break; 07618 case IAX_COMMAND_LAGRQ: 07619 case IAX_COMMAND_LAGRP: 07620 f.src = "LAGRQ"; 07621 f.mallocd = 0; 07622 f.offset = 0; 07623 f.samples = 0; 07624 /* f.data should never be NULL before a iax_frame_wrap call. 07625 * -- wad@google.com, 9 July 2007 */ 07626 if (!f.data) { 07627 ast_log(LOG_ERROR, 07628 "Non-zero data length for NULL data in LAGRP from peer %s.\n", 07629 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07630 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 07631 fr->ts, NULL, 0, fr->iseqno); 07632 iax2_destroy(fr->callno); 07633 break; 07634 } 07635 iax_frame_wrap(fr, &f); 07636 if(f.subclass == IAX_COMMAND_LAGRQ) { 07637 /* Received a LAGRQ - echo back a LAGRP */ 07638 fr->af.subclass = IAX_COMMAND_LAGRP; 07639 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07640 } else { 07641 /* Received LAGRP in response to our LAGRQ */ 07642 unsigned int ts; 07643 /* This is a reply we've been given, actually measure the difference */ 07644 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07645 iaxs[fr->callno]->lag = ts - fr->ts; 07646 if (option_debug && iaxdebug) 07647 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07648 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07649 } 07650 break; 07651 case IAX_COMMAND_AUTHREQ: 07652 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07653 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>"); 07654 break; 07655 } 07656 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07657 ast_log(LOG_WARNING, 07658 "I don't know how to authenticate %s to %s\n", 07659 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07660 } 07661 if (!iaxs[fr->callno]) { 07662 ast_mutex_unlock(&iaxsl[fr->callno]); 07663 return 1; 07664 } 07665 break; 07666 case IAX_COMMAND_AUTHREP: 07667 /* For security, always ack immediately */ 07668 if (delayreject) 07669 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07670 /* Ignore once we've started */ 07671 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07672 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>"); 07673 break; 07674 } 07675 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07676 if (authdebug) 07677 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); 07678 memset(&ied0, 0, sizeof(ied0)); 07679 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07680 break; 07681 } 07682 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07683 /* This might re-enter the IAX code and need the lock */ 07684 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07685 } else 07686 exists = 0; 07687 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07688 if (authdebug) 07689 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); 07690 memset(&ied0, 0, sizeof(ied0)); 07691 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07692 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07693 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07694 if (!iaxs[fr->callno]) { 07695 ast_mutex_unlock(&iaxsl[fr->callno]); 07696 return 1; 07697 } 07698 } else { 07699 /* Select an appropriate format */ 07700 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07701 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07702 using_prefs = "reqonly"; 07703 } else { 07704 using_prefs = "disabled"; 07705 } 07706 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07707 memset(&pref, 0, sizeof(pref)); 07708 strcpy(caller_pref_buf, "disabled"); 07709 strcpy(host_pref_buf, "disabled"); 07710 } else { 07711 using_prefs = "mine"; 07712 if (ies.codec_prefs) 07713 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07714 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07715 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07716 pref = iaxs[fr->callno]->rprefs; 07717 using_prefs = "caller"; 07718 } else { 07719 pref = iaxs[fr->callno]->prefs; 07720 } 07721 } else /* if no codec_prefs IE do it the old way */ 07722 pref = iaxs[fr->callno]->prefs; 07723 07724 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07725 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07726 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07727 } 07728 if (!format) { 07729 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07730 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); 07731 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07732 } 07733 if (!format) { 07734 if (authdebug) { 07735 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07736 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); 07737 else 07738 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); 07739 } 07740 memset(&ied0, 0, sizeof(ied0)); 07741 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07742 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07743 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07744 if (!iaxs[fr->callno]) { 07745 ast_mutex_unlock(&iaxsl[fr->callno]); 07746 return 1; 07747 } 07748 } else { 07749 /* Pick one... */ 07750 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07751 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07752 format = 0; 07753 } else { 07754 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07755 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07756 memset(&pref, 0, sizeof(pref)); 07757 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07758 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07759 strcpy(caller_pref_buf,"disabled"); 07760 strcpy(host_pref_buf,"disabled"); 07761 } else { 07762 using_prefs = "mine"; 07763 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07764 /* Do the opposite of what we tried above. */ 07765 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07766 pref = iaxs[fr->callno]->prefs; 07767 } else { 07768 pref = iaxs[fr->callno]->rprefs; 07769 using_prefs = "caller"; 07770 } 07771 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07772 } else /* if no codec_prefs IE do it the old way */ 07773 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07774 } 07775 } 07776 if (!format) { 07777 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07778 if (authdebug) { 07779 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07780 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); 07781 else 07782 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); 07783 } 07784 memset(&ied0, 0, sizeof(ied0)); 07785 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07786 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07787 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07788 if (!iaxs[fr->callno]) { 07789 ast_mutex_unlock(&iaxsl[fr->callno]); 07790 return 1; 07791 } 07792 } 07793 } 07794 } 07795 if (format) { 07796 /* Authentication received */ 07797 memset(&ied1, 0, sizeof(ied1)); 07798 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07799 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07800 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07801 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07802 if (option_verbose > 2) 07803 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07804 "%srequested format = %s,\n" 07805 "%srequested prefs = %s,\n" 07806 "%sactual format = %s,\n" 07807 "%shost prefs = %s,\n" 07808 "%spriority = %s\n", 07809 ast_inet_ntoa(sin.sin_addr), 07810 VERBOSE_PREFIX_4, 07811 ast_getformatname(iaxs[fr->callno]->peerformat), 07812 VERBOSE_PREFIX_4, 07813 caller_pref_buf, 07814 VERBOSE_PREFIX_4, 07815 ast_getformatname(format), 07816 VERBOSE_PREFIX_4, 07817 host_pref_buf, 07818 VERBOSE_PREFIX_4, 07819 using_prefs); 07820 07821 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07822 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07823 iax2_destroy(fr->callno); 07824 } else { 07825 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07826 /* If this is a TBD call, we're ready but now what... */ 07827 if (option_verbose > 2) 07828 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07829 } 07830 } 07831 } 07832 break; 07833 case IAX_COMMAND_DIAL: 07834 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07835 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07836 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07837 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07838 if (authdebug) 07839 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); 07840 memset(&ied0, 0, sizeof(ied0)); 07841 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07842 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07843 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07844 if (!iaxs[fr->callno]) { 07845 ast_mutex_unlock(&iaxsl[fr->callno]); 07846 return 1; 07847 } 07848 } else { 07849 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07850 if (option_verbose > 2) 07851 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 07852 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07853 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07854 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07855 iax2_destroy(fr->callno); 07856 } 07857 } 07858 break; 07859 case IAX_COMMAND_INVAL: 07860 iaxs[fr->callno]->error = ENOTCONN; 07861 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07862 iax2_destroy(fr->callno); 07863 if (option_debug) 07864 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07865 break; 07866 case IAX_COMMAND_VNAK: 07867 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07868 /* Force retransmission */ 07869 vnak_retransmit(fr->callno, fr->iseqno); 07870 break; 07871 case IAX_COMMAND_REGREQ: 07872 case IAX_COMMAND_REGREL: 07873 /* For security, always ack immediately */ 07874 if (delayreject) 07875 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07876 if (register_verify(fr->callno, &sin, &ies)) { 07877 if (!iaxs[fr->callno]) { 07878 ast_mutex_unlock(&iaxsl[fr->callno]); 07879 return 1; 07880 } 07881 /* Send delayed failure */ 07882 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07883 break; 07884 } 07885 if (!iaxs[fr->callno]) { 07886 ast_mutex_unlock(&iaxsl[fr->callno]); 07887 return 1; 07888 } 07889 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 07890 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 07891 if (f.subclass == IAX_COMMAND_REGREL) 07892 memset(&sin, 0, sizeof(sin)); 07893 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07894 ast_log(LOG_WARNING, "Registry error\n"); 07895 if (!iaxs[fr->callno]) { 07896 ast_mutex_unlock(&iaxsl[fr->callno]); 07897 return 1; 07898 } 07899 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07900 ast_mutex_unlock(&iaxsl[fr->callno]); 07901 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07902 ast_mutex_lock(&iaxsl[fr->callno]); 07903 if (!iaxs[fr->callno]) { 07904 ast_mutex_unlock(&iaxsl[fr->callno]); 07905 return 1; 07906 } 07907 } 07908 break; 07909 } 07910 registry_authrequest(fr->callno); 07911 if (!iaxs[fr->callno]) { 07912 ast_mutex_unlock(&iaxsl[fr->callno]); 07913 return 1; 07914 } 07915 break; 07916 case IAX_COMMAND_REGACK: 07917 if (iax2_ack_registry(&ies, &sin, fr->callno)) 07918 ast_log(LOG_WARNING, "Registration failure\n"); 07919 /* Send ack immediately, before we destroy */ 07920 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07921 iax2_destroy(fr->callno); 07922 break; 07923 case IAX_COMMAND_REGREJ: 07924 if (iaxs[fr->callno]->reg) { 07925 if (authdebug) { 07926 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)); 07927 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>"); 07928 } 07929 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 07930 } 07931 /* Send ack immediately, before we destroy */ 07932 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07933 iax2_destroy(fr->callno); 07934 break; 07935 case IAX_COMMAND_REGAUTH: 07936 /* Authentication request */ 07937 if (registry_rerequest(&ies, fr->callno, &sin)) { 07938 memset(&ied0, 0, sizeof(ied0)); 07939 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07940 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07941 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07942 if (!iaxs[fr->callno]) { 07943 ast_mutex_unlock(&iaxsl[fr->callno]); 07944 return 1; 07945 } 07946 } 07947 break; 07948 case IAX_COMMAND_TXREJ: 07949 iaxs[fr->callno]->transferring = 0; 07950 if (option_verbose > 2) 07951 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07952 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 07953 if (iaxs[fr->callno]->bridgecallno) { 07954 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 07955 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 07956 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07957 } 07958 } 07959 break; 07960 case IAX_COMMAND_TXREADY: 07961 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 07962 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 07963 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 07964 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 07965 else 07966 iaxs[fr->callno]->transferring = TRANSFER_READY; 07967 if (option_verbose > 2) 07968 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07969 if (iaxs[fr->callno]->bridgecallno) { 07970 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 07971 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 07972 /* They're both ready, now release them. */ 07973 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 07974 if (option_verbose > 2) 07975 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07976 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07977 07978 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 07979 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 07980 07981 memset(&ied0, 0, sizeof(ied0)); 07982 memset(&ied1, 0, sizeof(ied1)); 07983 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07984 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07985 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 07986 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 07987 } else { 07988 if (option_verbose > 2) 07989 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07990 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07991 07992 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07993 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 07994 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 07995 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07996 07997 /* Stop doing lag & ping requests */ 07998 stop_stuff(fr->callno); 07999 stop_stuff(iaxs[fr->callno]->bridgecallno); 08000 08001 memset(&ied0, 0, sizeof(ied0)); 08002 memset(&ied1, 0, sizeof(ied1)); 08003 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08004 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08005 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08006 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08007 } 08008 08009 } 08010 } 08011 } 08012 break; 08013 case IAX_COMMAND_TXREQ: 08014 try_transfer(iaxs[fr->callno], &ies); 08015 break; 08016 case IAX_COMMAND_TXCNT: 08017 if (iaxs[fr->callno]->transferring) 08018 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08019 break; 08020 case IAX_COMMAND_TXREL: 08021 /* Send ack immediately, rather than waiting until we've changed addresses */ 08022 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08023 complete_transfer(fr->callno, &ies); 08024 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08025 break; 08026 case IAX_COMMAND_TXMEDIA: 08027 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08028 AST_LIST_LOCK(&iaxq.queue); 08029 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08030 /* Cancel any outstanding frames and start anew */ 08031 if ((fr->callno == cur->callno) && (cur->transfer)) { 08032 cur->retries = -1; 08033 } 08034 } 08035 AST_LIST_UNLOCK(&iaxq.queue); 08036 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08037 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08038 } 08039 break; 08040 case IAX_COMMAND_DPREP: 08041 complete_dpreply(iaxs[fr->callno], &ies); 08042 break; 08043 case IAX_COMMAND_UNSUPPORT: 08044 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08045 break; 08046 case IAX_COMMAND_FWDOWNL: 08047 /* Firmware download */ 08048 memset(&ied0, 0, sizeof(ied0)); 08049 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08050 if (res < 0) 08051 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08052 else if (res > 0) 08053 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08054 else 08055 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08056 if (!iaxs[fr->callno]) { 08057 ast_mutex_unlock(&iaxsl[fr->callno]); 08058 return 1; 08059 } 08060 break; 08061 default: 08062 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08063 memset(&ied0, 0, sizeof(ied0)); 08064 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08065 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08066 } 08067 /* Don't actually pass these frames along */ 08068 if ((f.subclass != IAX_COMMAND_ACK) && 08069 (f.subclass != IAX_COMMAND_TXCNT) && 08070 (f.subclass != IAX_COMMAND_TXACC) && 08071 (f.subclass != IAX_COMMAND_INVAL) && 08072 (f.subclass != IAX_COMMAND_VNAK)) { 08073 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08074 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08075 } 08076 ast_mutex_unlock(&iaxsl[fr->callno]); 08077 return 1; 08078 } 08079 /* Unless this is an ACK or INVAL frame, ack it */ 08080 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08081 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08082 } else if (minivid) { 08083 f.frametype = AST_FRAME_VIDEO; 08084 if (iaxs[fr->callno]->videoformat > 0) 08085 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08086 else { 08087 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08088 iax2_vnak(fr->callno); 08089 ast_mutex_unlock(&iaxsl[fr->callno]); 08090 return 1; 08091 } 08092 f.datalen = res - sizeof(*vh); 08093 if (f.datalen) 08094 f.data = thread->buf + sizeof(*vh); 08095 else 08096 f.data = NULL; 08097 #ifdef IAXTESTS 08098 if (test_resync) { 08099 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08100 } else 08101 #endif /* IAXTESTS */ 08102 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08103 } else { 08104 /* A mini frame */ 08105 f.frametype = AST_FRAME_VOICE; 08106 if (iaxs[fr->callno]->voiceformat > 0) 08107 f.subclass = iaxs[fr->callno]->voiceformat; 08108 else { 08109 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 08110 iax2_vnak(fr->callno); 08111 ast_mutex_unlock(&iaxsl[fr->callno]); 08112 return 1; 08113 } 08114 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08115 if (f.datalen < 0) { 08116 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08117 ast_mutex_unlock(&iaxsl[fr->callno]); 08118 return 1; 08119 } 08120 if (f.datalen) 08121 f.data = thread->buf + sizeof(*mh); 08122 else 08123 f.data = NULL; 08124 #ifdef IAXTESTS 08125 if (test_resync) { 08126 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08127 } else 08128 #endif /* IAXTESTS */ 08129 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08130 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08131 } 08132 /* Don't pass any packets until we're started */ 08133 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08134 ast_mutex_unlock(&iaxsl[fr->callno]); 08135 return 1; 08136 } 08137 /* Common things */ 08138 f.src = "IAX2"; 08139 f.mallocd = 0; 08140 f.offset = 0; 08141 f.len = 0; 08142 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08143 f.samples = ast_codec_get_samples(&f); 08144 /* We need to byteswap incoming slinear samples from network byte order */ 08145 if (f.subclass == AST_FORMAT_SLINEAR) 08146 ast_frame_byteswap_be(&f); 08147 } else 08148 f.samples = 0; 08149 iax_frame_wrap(fr, &f); 08150 08151 /* If this is our most recent packet, use it as our basis for timestamping */ 08152 if (iaxs[fr->callno]->last < fr->ts) { 08153 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08154 fr->outoforder = 0; 08155 } else { 08156 if (option_debug && iaxdebug) 08157 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); 08158 fr->outoforder = -1; 08159 } 08160 duped_fr = iaxfrdup2(fr); 08161 if (duped_fr) { 08162 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08163 } 08164 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08165 iaxs[fr->callno]->last = fr->ts; 08166 #if 1 08167 if (option_debug && iaxdebug) 08168 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08169 #endif 08170 } 08171 08172 /* Always run again */ 08173 ast_mutex_unlock(&iaxsl[fr->callno]); 08174 return 1; 08175 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6592 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(), iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len, LOG_NOTICE, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06593 { 06594 struct iax2_thread *thread; 06595 socklen_t len; 06596 time_t t; 06597 static time_t last_errtime = 0; 06598 struct ast_iax2_full_hdr *fh; 06599 06600 if (!(thread = find_idle_thread())) { 06601 time(&t); 06602 if (t != last_errtime) 06603 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n"); 06604 last_errtime = t; 06605 usleep(1); 06606 return 1; 06607 } 06608 06609 len = sizeof(thread->iosin); 06610 thread->iofd = fd; 06611 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06612 thread->buf_size = sizeof(thread->readbuf); 06613 thread->buf = thread->readbuf; 06614 if (thread->buf_len < 0) { 06615 if (errno != ECONNREFUSED && errno != EAGAIN) 06616 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06617 handle_error(); 06618 thread->iostate = IAX_IOSTATE_IDLE; 06619 signal_condition(&thread->lock, &thread->cond); 06620 return 1; 06621 } 06622 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06623 thread->iostate = IAX_IOSTATE_IDLE; 06624 signal_condition(&thread->lock, &thread->cond); 06625 return 1; 06626 } 06627 06628 /* Determine if this frame is a full frame; if so, and any thread is currently 06629 processing a full frame for the same callno from this peer, then drop this 06630 frame (and the peer will retransmit it) */ 06631 fh = (struct ast_iax2_full_hdr *) thread->buf; 06632 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06633 struct iax2_thread *cur = NULL; 06634 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06635 06636 AST_LIST_LOCK(&active_list); 06637 AST_LIST_TRAVERSE(&active_list, cur, list) { 06638 if ((cur->ffinfo.callno == callno) && 06639 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06640 break; 06641 } 06642 if (cur) { 06643 /* we found another thread processing a full frame for this call, 06644 so queue it up for processing later. */ 06645 defer_full_frame(thread, cur); 06646 AST_LIST_UNLOCK(&active_list); 06647 thread->iostate = IAX_IOSTATE_IDLE; 06648 signal_condition(&thread->lock, &thread->cond); 06649 return 1; 06650 } else { 06651 /* this thread is going to process this frame, so mark it */ 06652 thread->ffinfo.callno = callno; 06653 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06654 thread->ffinfo.type = fh->type; 06655 thread->ffinfo.csub = fh->csub; 06656 } 06657 AST_LIST_UNLOCK(&active_list); 06658 } 06659 06660 /* Mark as ready and send on its way */ 06661 thread->iostate = IAX_IOSTATE_READY; 06662 #ifdef DEBUG_SCHED_MULTITHREAD 06663 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06664 #endif 06665 signal_condition(&thread->lock, &thread->cond); 06666 06667 return 1; 06668 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6379 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().
06380 { 06381 pthread_t newthread; 06382 struct dpreq_data *dpr; 06383 pthread_attr_t attr; 06384 06385 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06386 return; 06387 06388 pthread_attr_init(&attr); 06389 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06390 06391 dpr->callno = callno; 06392 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06393 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06394 if (callerid) 06395 dpr->callerid = ast_strdup(callerid); 06396 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06397 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06398 } 06399 06400 pthread_attr_destroy(&attr); 06401 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8752 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().
08753 { 08754 pthread_attr_t attr; 08755 int threadcount = 0; 08756 int x; 08757 for (x = 0; x < iaxthreadcount; x++) { 08758 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08759 if (thread) { 08760 thread->type = IAX_TYPE_POOL; 08761 thread->threadnum = ++threadcount; 08762 ast_mutex_init(&thread->lock); 08763 ast_cond_init(&thread->cond, NULL); 08764 pthread_attr_init(&attr); 08765 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08766 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08767 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08768 free(thread); 08769 thread = NULL; 08770 } 08771 AST_LIST_LOCK(&idle_list); 08772 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08773 AST_LIST_UNLOCK(&idle_list); 08774 } 08775 } 08776 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08777 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08778 if (option_verbose > 1) 08779 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08780 return 0; 08781 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6067 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06068 { 06069 iax2_destroy_helper(iaxs[callno]); 06070 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6254 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, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06255 { 06256 char buf[1024]; 06257 int res; 06258 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06259 int processed = 0; 06260 int totalcalls = 0; 06261 #ifdef ZT_TIMERACK 06262 int x = 1; 06263 #endif 06264 struct timeval now; 06265 if (iaxtrunkdebug) 06266 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06267 gettimeofday(&now, NULL); 06268 if (events & AST_IO_PRI) { 06269 #ifdef ZT_TIMERACK 06270 /* Great, this is a timing interface, just call the ioctl */ 06271 if (ioctl(fd, ZT_TIMERACK, &x)) 06272 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06273 res = 0; 06274 #endif 06275 } else { 06276 /* Read and ignore from the pseudo channel for timing */ 06277 res = read(fd, buf, sizeof(buf)); 06278 if (res < 1) { 06279 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06280 return 1; 06281 } 06282 } 06283 /* For each peer that supports trunking... */ 06284 ast_mutex_lock(&tpeerlock); 06285 tpeer = tpeers; 06286 while(tpeer) { 06287 processed++; 06288 res = 0; 06289 ast_mutex_lock(&tpeer->lock); 06290 /* We can drop a single tpeer per pass. That makes all this logic 06291 substantially easier */ 06292 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06293 /* Take it out of the list, but don't free it yet, because it 06294 could be in use */ 06295 if (prev) 06296 prev->next = tpeer->next; 06297 else 06298 tpeers = tpeer->next; 06299 drop = tpeer; 06300 } else { 06301 res = send_trunk(tpeer, &now); 06302 if (iaxtrunkdebug) 06303 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); 06304 } 06305 totalcalls += res; 06306 res = 0; 06307 ast_mutex_unlock(&tpeer->lock); 06308 prev = tpeer; 06309 tpeer = tpeer->next; 06310 } 06311 ast_mutex_unlock(&tpeerlock); 06312 if (drop) { 06313 ast_mutex_lock(&drop->lock); 06314 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06315 because by the time they could get tpeerlock, we've already grabbed it */ 06316 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06317 free(drop->trunkdata); 06318 ast_mutex_unlock(&drop->lock); 06319 ast_mutex_destroy(&drop->lock); 06320 free(drop); 06321 06322 } 06323 if (iaxtrunkdebug) 06324 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06325 iaxtrunkdebug =0; 06326 return 1; 06327 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1832 of file chan_iax2.c.
References ast_log(), f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01833 { 01834 int res; 01835 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01836 sizeof(*sin)); 01837 if (res < 0) { 01838 if (option_debug) 01839 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01840 handle_error(); 01841 } else 01842 res = 0; 01843 return res; 01844 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1523 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, 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().
01524 { 01525 struct stat stbuf; 01526 struct iax_firmware *cur; 01527 int ifd; 01528 int fd; 01529 int res; 01530 01531 struct ast_iax2_firmware_header *fwh, fwh2; 01532 struct MD5Context md5; 01533 unsigned char sum[16]; 01534 unsigned char buf[1024]; 01535 int len, chunk; 01536 char *s2; 01537 char *last; 01538 s2 = alloca(strlen(s) + 100); 01539 if (!s2) { 01540 ast_log(LOG_WARNING, "Alloca failed!\n"); 01541 return -1; 01542 } 01543 last = strrchr(s, '/'); 01544 if (last) 01545 last++; 01546 else 01547 last = s; 01548 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01549 res = stat(s, &stbuf); 01550 if (res < 0) { 01551 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01552 return -1; 01553 } 01554 /* Make sure it's not a directory */ 01555 if (S_ISDIR(stbuf.st_mode)) 01556 return -1; 01557 ifd = open(s, O_RDONLY); 01558 if (ifd < 0) { 01559 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01560 return -1; 01561 } 01562 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01563 if (fd < 0) { 01564 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01565 close(ifd); 01566 return -1; 01567 } 01568 /* Unlink our newly created file */ 01569 unlink(s2); 01570 01571 /* Now copy the firmware into it */ 01572 len = stbuf.st_size; 01573 while(len) { 01574 chunk = len; 01575 if (chunk > sizeof(buf)) 01576 chunk = sizeof(buf); 01577 res = read(ifd, buf, chunk); 01578 if (res != chunk) { 01579 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01580 close(ifd); 01581 close(fd); 01582 return -1; 01583 } 01584 res = write(fd, buf, chunk); 01585 if (res != chunk) { 01586 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01587 close(ifd); 01588 close(fd); 01589 return -1; 01590 } 01591 len -= chunk; 01592 } 01593 close(ifd); 01594 /* Return to the beginning */ 01595 lseek(fd, 0, SEEK_SET); 01596 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01597 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01598 close(fd); 01599 return -1; 01600 } 01601 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01602 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01603 close(fd); 01604 return -1; 01605 } 01606 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01607 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01608 close(fd); 01609 return -1; 01610 } 01611 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01612 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01613 close(fd); 01614 return -1; 01615 } 01616 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01617 if (fwh == (void *) -1) { 01618 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01619 close(fd); 01620 return -1; 01621 } 01622 MD5Init(&md5); 01623 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01624 MD5Final(sum, &md5); 01625 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01626 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01627 munmap((void*)fwh, stbuf.st_size); 01628 close(fd); 01629 return -1; 01630 } 01631 cur = waresl.wares; 01632 while(cur) { 01633 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01634 /* Found a candidate */ 01635 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01636 /* The version we have on loaded is older, load this one instead */ 01637 break; 01638 /* This version is no newer than what we have. Don't worry about it. 01639 We'll consider it a proper load anyhow though */ 01640 munmap((void*)fwh, stbuf.st_size); 01641 close(fd); 01642 return 0; 01643 } 01644 cur = cur->next; 01645 } 01646 if (!cur) { 01647 /* Allocate a new one and link it */ 01648 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01649 cur->fd = -1; 01650 cur->next = waresl.wares; 01651 waresl.wares = cur; 01652 } 01653 } 01654 if (cur) { 01655 if (cur->fwh) { 01656 munmap((void*)cur->fwh, cur->mmaplen); 01657 } 01658 if (cur->fd > -1) 01659 close(cur->fd); 01660 cur->fwh = fwh; 01661 cur->fd = fd; 01662 cur->mmaplen = stbuf.st_size; 01663 cur->dead = 0; 01664 } 01665 return 0; 01666 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5502 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().
05503 { 05504 int newcall = 0; 05505 char newip[256]; 05506 struct iax_ie_data ied; 05507 struct sockaddr_in new; 05508 05509 05510 memset(&ied, 0, sizeof(ied)); 05511 if (ies->apparent_addr) 05512 bcopy(ies->apparent_addr, &new, sizeof(new)); 05513 if (ies->callno) 05514 newcall = ies->callno; 05515 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05516 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05517 return -1; 05518 } 05519 pvt->transfercallno = newcall; 05520 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05521 inet_aton(newip, &pvt->transfer.sin_addr); 05522 pvt->transfer.sin_family = AF_INET; 05523 pvt->transferring = TRANSFER_BEGIN; 05524 pvt->transferid = ies->transferid; 05525 if (ies->transferid) 05526 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05527 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05528 return 0; 05529 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1043 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01044 { 01045 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01046 if (csub & IAX_FLAG_SC_LOG) { 01047 /* special case for 'compressed' -1 */ 01048 if (csub == 0xff) 01049 return -1; 01050 else 01051 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01052 } 01053 else 01054 return csub; 01055 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10653 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
10654 { 10655 ast_custom_function_unregister(&iaxpeer_function); 10656 return __unload_module(); 10657 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3274 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03275 { 03276 ast_mutex_unlock(&iaxsl[callno1]); 03277 ast_mutex_unlock(&iaxsl[callno0]); 03278 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2382 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().
02383 { 02384 int x; 02385 02386 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02387 x = fr->ts - iaxs[fr->callno]->last; 02388 if (x < -50000) { 02389 /* Sudden big jump backwards in timestamp: 02390 What likely happened here is that miniframe timestamp has circled but we haven't 02391 gotten the update from the main packet. We'll just pretend that we did, and 02392 update the timestamp appropriately. */ 02393 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02394 if (option_debug && iaxdebug) 02395 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02396 } 02397 if (x > 50000) { 02398 /* Sudden apparent big jump forwards in timestamp: 02399 What's likely happened is this is an old miniframe belonging to the previous 02400 top-16-bit timestamp that has turned up out of order. 02401 Adjust the timestamp appropriately. */ 02402 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02403 if (option_debug && iaxdebug) 02404 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02405 } 02406 } 02407 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2411 of file chan_iax2.c.
References ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, sched, and signal_condition().
Referenced by __get_from_jb(), and schedule_delivery().
02412 { 02413 int when; 02414 02415 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02416 02417 when = jb_next(pvt->jb) - when; 02418 02419 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02420 02421 if(when <= 0) { 02422 /* XXX should really just empty until when > 0.. */ 02423 when = 1; 02424 } 02425 02426 pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02427 02428 /* Signal scheduler thread */ 02429 signal_condition(&sched_lock, &sched_cond); 02430 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1263 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno().
01264 { 01265 int max = 1; 01266 int x; 01267 /* XXX Prolly don't need locks here XXX */ 01268 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01269 if (iaxs[x]) 01270 max = x + 1; 01271 } 01272 maxnontrunkcall = max; 01273 if (option_debug && iaxdebug) 01274 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01275 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1249 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy().
01250 { 01251 int max = TRUNK_CALL_START; 01252 int x; 01253 /* XXX Prolly don't need locks here XXX */ 01254 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01255 if (iaxs[x]) 01256 max = x + 1; 01257 } 01258 maxtrunkcall = max; 01259 if (option_debug && iaxdebug) 01260 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01261 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2019 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().
02020 { 02021 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02022 struct ast_iax2_full_hdr *fh = f->data; 02023 /* Mark this as a retransmission */ 02024 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02025 /* Update iseqno */ 02026 f->iseqno = iaxs[f->callno]->iseqno; 02027 fh->iseqno = f->iseqno; 02028 return 0; 02029 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5859 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_add(), 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, 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_unref(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05860 { 05861 /* Called from IAX thread only, with proper iaxsl lock */ 05862 struct iax_ie_data ied; 05863 struct iax2_peer *p; 05864 int msgcount; 05865 char data[80]; 05866 int version; 05867 const char *peer_name; 05868 int res = -1; 05869 05870 memset(&ied, 0, sizeof(ied)); 05871 05872 peer_name = ast_strdupa(iaxs[callno]->peer); 05873 05874 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05875 ast_mutex_unlock(&iaxsl[callno]); 05876 if (!(p = find_peer(peer_name, 1))) { 05877 ast_mutex_lock(&iaxsl[callno]); 05878 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 05879 return -1; 05880 } 05881 ast_mutex_lock(&iaxsl[callno]); 05882 if (!iaxs[callno]) 05883 goto return_unref; 05884 05885 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 05886 if (sin->sin_addr.s_addr) { 05887 time_t nowtime; 05888 time(&nowtime); 05889 realtime_update_peer(peer_name, sin, nowtime); 05890 } else { 05891 realtime_update_peer(peer_name, sin, 0); 05892 } 05893 } 05894 if (inaddrcmp(&p->addr, sin)) { 05895 if (iax2_regfunk) 05896 iax2_regfunk(p->name, 1); 05897 /* Stash the IP address from which they registered */ 05898 memcpy(&p->addr, sin, sizeof(p->addr)); 05899 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05900 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05901 ast_db_put("IAX/Registry", p->name, data); 05902 if (option_verbose > 2) 05903 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05904 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 05905 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05906 register_peer_exten(p, 1); 05907 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05908 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05909 if (option_verbose > 2) 05910 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05911 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05912 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05913 register_peer_exten(p, 0); 05914 ast_db_del("IAX/Registry", p->name); 05915 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05916 } 05917 /* Update the host */ 05918 /* Verify that the host is really there */ 05919 iax2_poke_peer(p, callno); 05920 } 05921 05922 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 05923 if (!iaxs[callno]) { 05924 res = 0; 05925 goto return_unref; 05926 } 05927 05928 /* Store socket fd */ 05929 p->sockfd = fd; 05930 /* Setup the expiry */ 05931 if (p->expire > -1) 05932 ast_sched_del(sched, p->expire); 05933 /* treat an unspecified refresh interval as the minimum */ 05934 if (!refresh) 05935 refresh = min_reg_expire; 05936 if (refresh > max_reg_expire) { 05937 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05938 p->name, max_reg_expire, refresh); 05939 p->expiry = max_reg_expire; 05940 } else if (refresh < min_reg_expire) { 05941 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05942 p->name, min_reg_expire, refresh); 05943 p->expiry = min_reg_expire; 05944 } else { 05945 p->expiry = refresh; 05946 } 05947 if (p->expiry && sin->sin_addr.s_addr) 05948 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05949 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05950 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05951 if (sin->sin_addr.s_addr) { 05952 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05953 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05954 if (!ast_strlen_zero(p->mailbox)) { 05955 int new, old; 05956 ast_app_inboxcount(p->mailbox, &new, &old); 05957 if (new > 255) 05958 new = 255; 05959 if (old > 255) 05960 old = 255; 05961 msgcount = (old << 8) | new; 05962 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05963 } 05964 if (ast_test_flag(p, IAX_HASCALLERID)) { 05965 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05966 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05967 } 05968 } 05969 version = iax_check_version(devtype); 05970 if (version) 05971 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05972 05973 res = 0; 05974 05975 return_unref: 05976 peer_unref(p); 05977 05978 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05979 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1090 of file chan_iax2.c.
Referenced by load_module().
01091 { 01092 struct iax2_user *user = obj, *user2 = arg; 01093 01094 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01095 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9401 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09402 { 09403 struct iax2_user *user = obj; 09404 09405 ast_set_flag(user, IAX_DELME); 09406 09407 return 0; 09408 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9165 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_pools, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
09166 { 09167 struct iax2_user *user = obj; 09168 09169 ast_free_ha(user->ha); 09170 free_context(user->contexts); 09171 if(user->vars) { 09172 ast_variables_destroy(user->vars); 09173 user->vars = NULL; 09174 } 09175 ast_string_field_free_pools(user); 09176 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1080 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01081 { 01082 const struct iax2_user *user = obj; 01083 01084 return ast_str_hash(user->name); 01085 }
Definition at line 1129 of file chan_iax2.c.
References ao2_ref().
Referenced by realtime_user().
01130 { 01131 ao2_ref(user, +1); 01132 return user; 01133 }
Definition at line 1135 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), and prune_users().
01136 { 01137 ao2_ref(user, -1); 01138 return NULL; 01139 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6170 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().
06171 { 06172 struct iax_frame *f; 06173 06174 AST_LIST_LOCK(&iaxq.queue); 06175 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06176 /* Send a copy immediately */ 06177 if ((f->callno == callno) && iaxs[f->callno] && 06178 ((unsigned char ) (f->oseqno - last) < 128) && 06179 (f->retries >= 0)) { 06180 send_packet(f); 06181 } 06182 } 06183 AST_LIST_UNLOCK(&iaxq.queue); 06184 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 219 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] |
Definition at line 222 of file chan_iax2.c.
Referenced by build_device(), build_gateway(), and pgsql_log().
int authdebug = 1 [static] |
int autokill = 0 [static] |
Definition at line 160 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 10454 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 10459 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 10469 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 10464 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 10449 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 144 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 10423 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 10415 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 10407 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 176 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 224 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 277 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 227 of file chan_iax2.c.
Referenced by __expire_registry(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_callno(), 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(), realtime_peer(), realtime_user(), reload_config(), send_trunk(), sendmail(), set_config(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 205 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 225 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 178 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 10365 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 846 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 10431 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 453 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 161 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 207 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 163 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 452 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 810 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), find_callno(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[IAX_MAX_CALLS] [static] |
Definition at line 811 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), find_callno(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), and update_registry().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 209 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 202 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 152 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 146 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
int max_reg_expire [static] |
Definition at line 170 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 150 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 149 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 155 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 157 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 154 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 153 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 169 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 221 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 174 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 229 of file chan_iax2.c.
Referenced by network_thread(), start_network_thread(), and unload_module().
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 10427 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 10419 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 10411 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 175 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 8414 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 8416 of file chan_iax2.c.
ao2_container* peers [static] |
Definition at line 648 of file chan_iax2.c.
Referenced by __expire_registry(), __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(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), mark_mappings(), mark_peers(), network_thread(), optimize_transactions(), precache_transactions(), prune_mappings(), prune_peers(), query_transactions(), register_request(), reload_config(), set_config(), socket_read(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 151 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 140 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 10361 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8415 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 147 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 156 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 203 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 232 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 230 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 10353 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 10381 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 10399 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 10385 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 10357 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 10393 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10369 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 10403 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 10349 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 10389 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 10376 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 142 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 211 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 172 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 167 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 158 of file chan_iax2.c.
ao2_container* users [static] |
Definition at line 651 of file chan_iax2.c.
Referenced by __unload_module(), ast_get_manager_by_name_locked(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_voicemail_show_users(), delete_users(), find_or_create(), find_user(), handle_showmanager(), handle_showmanagers(), handle_voicemail_show_users(), iax2_destroy_helper(), iax2_show_users(), init_manager(), load_config(), load_module(), prune_users(), realtime_user(), reset_user_pw(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().